Repository: openstack/openstack-helm Branch: master Commit: 7e8f26de0ac3 Files: 3167 Total size: 8.1 MB Directory structure: gitextract_9pqhdo10/ ├── .gitignore ├── .gitreview ├── .pre-commit-config.yaml ├── CONTRIBUTING.rst ├── LICENSE ├── Makefile ├── README.rst ├── aodh/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _aodh-alarms-cleaner.sh.tpl │ │ │ ├── _aodh-api.sh.tpl │ │ │ ├── _aodh-evaluator.sh.tpl │ │ │ ├── _aodh-listener.sh.tpl │ │ │ ├── _aodh-notifier.sh.tpl │ │ │ ├── _aodh-test.sh.tpl │ │ │ ├── _bootstrap.sh.tpl │ │ │ └── _db-sync.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-alarms-cleaner.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-evaluator.yaml │ │ ├── deployment-listener.yaml │ │ ├── deployment-notifier.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-aodh-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── barbican/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _barbican-test.sh.tpl │ │ │ ├── _barbican.sh.tpl │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ └── _simple_crypto_kek_rewrap.py.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── bindep.txt ├── blazar/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _blazar_api.sh.tpl │ │ │ ├── _blazar_manager.sh.tpl │ │ │ └── _db-sync.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-manager.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── pdb-api.yaml │ │ ├── pdb-manager.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ks-etc.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── ca-clusterissuer/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── clusterissuer-ca.yaml │ │ ├── extra-manifests.yaml │ │ └── secret-ca.yaml │ └── values.yaml ├── ca-issuer/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── extra-manifests.yaml │ │ ├── issuer-ca.yaml │ │ └── secret-ca.yaml │ └── values.yaml ├── ceilometer/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _ceilometer-central.sh.tpl │ │ │ ├── _ceilometer-compute.sh.tpl │ │ │ ├── _ceilometer-ipmi.sh.tpl │ │ │ ├── _ceilometer-notification.sh.tpl │ │ │ └── _db-sync.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-compute.yaml │ │ ├── daemonset-ipmi.yaml │ │ ├── deployment-central.yaml │ │ ├── deployment-notification.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── ceph-adapter-rook/ │ ├── Chart.yaml │ ├── README.md │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _config-manager.sh.tpl │ │ │ └── _key-manager.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc-client.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-namespace-client-ceph-config.yaml │ │ └── job-namespace-client-key.yaml │ └── values.yaml ├── ceph-client/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _helm-tests.sh.tpl │ │ │ ├── _init-dirs.sh.tpl │ │ │ ├── mds/ │ │ │ │ └── _start.sh.tpl │ │ │ ├── pool/ │ │ │ │ ├── _calc.py.tpl │ │ │ │ └── _init.sh.tpl │ │ │ └── utils/ │ │ │ ├── _checkDNS.sh.tpl │ │ │ ├── _checkDNS_start.sh.tpl │ │ │ ├── _checkPGs.sh.tpl │ │ │ └── _defragOSDs.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc-client.yaml │ │ ├── cronjob-checkPGs.yaml │ │ ├── cronjob-defragosds.yaml │ │ ├── deployment-checkdns.yaml │ │ ├── deployment-mds.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-rbd-pool.yaml │ │ ├── pod-helm-tests.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── ceph-mon/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _init-dirs.sh.tpl │ │ │ ├── _post-apply.sh.tpl │ │ │ ├── keys/ │ │ │ │ ├── _bootstrap-keyring-generator.py.tpl │ │ │ │ ├── _bootstrap-keyring-manager.sh.tpl │ │ │ │ └── _storage-keyring-manager.sh.tpl │ │ │ ├── mgr/ │ │ │ │ ├── _check.sh.tpl │ │ │ │ └── _start.sh.tpl │ │ │ ├── mon/ │ │ │ │ ├── _check.sh.tpl │ │ │ │ ├── _start.sh.tpl │ │ │ │ └── _stop.sh.tpl │ │ │ ├── moncheck/ │ │ │ │ ├── _reap-zombies.py.tpl │ │ │ │ └── _start.sh.tpl │ │ │ └── utils/ │ │ │ ├── _checkDNS.sh.tpl │ │ │ ├── _checkObjectReplication.py.tpl │ │ │ └── _checkPGs.py.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── configmap-templates.yaml │ │ ├── daemonset-mon.yaml │ │ ├── deployment-mgr.yaml │ │ ├── deployment-moncheck.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-keyring.yaml │ │ ├── job-post-apply.yaml │ │ ├── job-storage-admin-keys.yaml │ │ ├── secret-registry.yaml │ │ ├── service-mgr.yaml │ │ ├── service-mon-discovery.yaml │ │ ├── service-mon.yaml │ │ ├── snippets/ │ │ │ └── _mon_host_from_k8s_ep.sh.tpl │ │ └── utils/ │ │ └── _mon_daemonset_overrides.tpl │ └── values.yaml ├── ceph-osd/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _helm-tests.sh.tpl │ │ │ ├── _init-dirs.sh.tpl │ │ │ ├── _post-apply.sh.tpl │ │ │ ├── osd/ │ │ │ │ ├── _check.sh.tpl │ │ │ │ ├── _config.sh.tpl │ │ │ │ ├── _directory.sh.tpl │ │ │ │ ├── _init.sh.tpl │ │ │ │ ├── _log-runner-stop.sh.tpl │ │ │ │ ├── _log-tail.sh.tpl │ │ │ │ ├── _start.sh.tpl │ │ │ │ ├── _stop.sh.tpl │ │ │ │ └── ceph-volume/ │ │ │ │ ├── _block.sh.tpl │ │ │ │ ├── _bluestore.sh.tpl │ │ │ │ ├── _common.sh.tpl │ │ │ │ ├── _init-ceph-volume-helper-block-logical.sh.tpl │ │ │ │ ├── _init-ceph-volume-helper-bluestore.sh.tpl │ │ │ │ ├── _init-ceph-volume-helper-directory.sh.tpl │ │ │ │ └── _init-with-ceph-volume.sh.tpl │ │ │ └── utils/ │ │ │ ├── _checkDNS.sh.tpl │ │ │ ├── _defragOSDs.sh.tpl │ │ │ └── _resolveLocations.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-osd.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-post-apply.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-registry.yaml │ │ └── utils/ │ │ └── _osd_daemonset_overrides.tpl │ └── values.yaml ├── ceph-provisioners/ │ ├── Chart.yaml │ ├── crds/ │ │ ├── snapshot.storage.k8s.io_volumesnapshotclasses.yaml │ │ ├── snapshot.storage.k8s.io_volumesnapshotcontents.yaml │ │ └── snapshot.storage.k8s.io_volumesnapshots.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _helm-tests.sh.tpl │ │ │ └── provisioner/ │ │ │ ├── cephfs/ │ │ │ │ ├── _client-key-manager.sh.tpl │ │ │ │ └── _start.sh.tpl │ │ │ └── rbd/ │ │ │ ├── _namespace-client-ceph-config-manager.sh.tpl │ │ │ ├── _namespace-client-key-cleaner.sh.tpl │ │ │ ├── _namespace-client-key-manager.sh.tpl │ │ │ └── _start.sh.tpl │ │ ├── configmap-bin-provisioner.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc-client.yaml │ │ ├── configmap-etc-csi.yaml │ │ ├── daemonset-csi-rbd-plugin.yaml │ │ ├── deployment-csi-rbd-provisioner.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-cephfs-client-key.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-namespace-client-ceph-config.yaml │ │ ├── job-namespace-client-key-cleaner.yaml │ │ ├── job-namespace-client-key.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-registry.yaml │ │ └── storageclass.yaml │ └── values.yaml ├── ceph-rgw/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _ceph-admin-keyring.sh.tpl │ │ │ ├── _ceph-rgw-storage-init.sh.tpl │ │ │ ├── _create-rgw-placement-targets.sh.tpl │ │ │ ├── _helm-tests.sh.tpl │ │ │ ├── _init-dirs.sh.tpl │ │ │ ├── _rgw-restart.sh.tpl │ │ │ ├── rgw/ │ │ │ │ ├── _init.sh.tpl │ │ │ │ ├── _rerun-pool-job.sh.tpl │ │ │ │ └── _start.sh.tpl │ │ │ └── utils/ │ │ │ └── _checkDNS.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin-ks.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-ceph-rgw-templates.yaml │ │ ├── configmap-etc-client.yaml │ │ ├── deployment-rgw.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-rgw.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rgw-placement-targets.yaml │ │ ├── job-rgw-pool.yaml │ │ ├── job-rgw-restart.yaml │ │ ├── job-rgw-storage-init.yaml │ │ ├── job-s3-admin.yaml │ │ ├── network_policy.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone-rgw.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-s3-rgw.yaml │ │ ├── service-ingress-rgw.yaml │ │ └── service-rgw.yaml │ └── values.yaml ├── cert-rotation/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _rotate-certs.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── cron-job-cert-rotate.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-cert-rotate.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── cinder/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _backup-storage-init.sh.tpl │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _ceph-admin-keyring.sh.tpl │ │ │ ├── _ceph-keyring.sh.tpl │ │ │ ├── _cinder-api.sh.tpl │ │ │ ├── _cinder-backup.sh.tpl │ │ │ ├── _cinder-scheduler.sh.tpl │ │ │ ├── _cinder-volume.sh.tpl │ │ │ ├── _clean-secrets.sh.tpl │ │ │ ├── _create-internal-tenant-id.sh.tpl │ │ │ ├── _db-purge.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _external-ceph-rbd-admin-keyring.sh.tpl │ │ │ ├── _iscsiadm.tpl │ │ │ ├── _multipath.tpl │ │ │ ├── _multipathd.tpl │ │ │ ├── _retrieve-internal-tenant-id.sh.tpl │ │ │ ├── _storage-init.sh.tpl │ │ │ └── _volume-usage-audit.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-cinder-db-purge.yaml │ │ ├── cron-job-cinder-volume-usage-audit.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-backup.yaml │ │ ├── deployment-scheduler.yaml │ │ ├── deployment-volume.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-backup-storage-init.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-clean.yaml │ │ ├── job-create-internal-tenant.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── job-storage-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-rally-test.yaml │ │ ├── pvc-backup.yaml │ │ ├── secret-db.yaml │ │ ├── secret-external-ceph-keyring.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ks-etc.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ ├── service-ingress-api.yaml │ │ └── utils/ │ │ ├── _ceph_backend_list.tpl │ │ ├── _has_ceph_backend.tpl │ │ └── _is_ceph_backend.tpl │ └── values.yaml ├── cloudkitty/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _cloudkitty-api.sh.tpl │ │ │ ├── _cloudkitty-processor.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ └── _storage-init.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-processor.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbitmq-init.yaml │ │ ├── job-storage-init.yaml │ │ ├── network_policy.yaml │ │ ├── pbd-api.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ks-etc.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ └── service-api.yaml │ └── values.yaml ├── cyborg/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _cyborg-agent.sh.tpl │ │ │ ├── _cyborg-api.sh.tpl │ │ │ ├── _cyborg-conductor.sh.tpl │ │ │ └── _db-sync.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-agent.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-conductor.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── designate/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _designate-api.sh.tpl │ │ │ ├── _designate-central.sh.tpl │ │ │ ├── _designate-mdns.sh.tpl │ │ │ ├── _designate-producer.sh.tpl │ │ │ ├── _designate-service-cleaner.sh.tpl │ │ │ ├── _designate-sink.sh.tpl │ │ │ └── _designate-worker.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-service.cleaner.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-central.yaml │ │ ├── deployment-mdns.yaml │ │ ├── deployment-producer.yaml │ │ ├── deployment-sink.yaml │ │ ├── deployment-worker.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── pdb-api.yaml │ │ ├── pdb-central.yaml │ │ ├── pdb-mdns.yaml │ │ ├── pdb-producer.yaml │ │ ├── pdb-sink.yaml │ │ ├── pdb-worker.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ ├── service-ingress-api.yaml │ │ └── service-mdns.yaml │ └── values.yaml ├── doc/ │ ├── helm-docs.rst.gotmpl │ ├── requirements.txt │ └── source/ │ ├── _exts/ │ │ └── helm_docs.py │ ├── _static/ │ │ └── .placeholder │ ├── chart/ │ │ ├── index.rst │ │ ├── infra_charts.rst │ │ └── openstack_charts.rst │ ├── conf.py │ ├── devref/ │ │ ├── endpoints.rst │ │ ├── fluent-logging.rst │ │ ├── images.rst │ │ ├── index.rst │ │ ├── networking.rst │ │ ├── node-and-label-specific-configurations.rst │ │ ├── oslo-config.rst │ │ ├── pod-disruption-budgets.rst │ │ └── upgrades.rst │ ├── index.rst │ ├── install/ │ │ ├── before_starting.rst │ │ ├── index.rst │ │ ├── kubernetes.rst │ │ ├── openstack.rst │ │ └── prerequisites.rst │ ├── logging/ │ │ ├── elasticsearch.rst │ │ ├── fluent-logging.rst │ │ ├── index.rst │ │ └── kibana.rst │ ├── monitoring/ │ │ ├── grafana.rst │ │ ├── index.rst │ │ ├── nagios.rst │ │ └── prometheus.rst │ ├── readme.rst │ ├── specs/ │ │ ├── 2025.1/ │ │ │ └── chart_versioning.rst │ │ ├── 2025.2/ │ │ │ └── own_service_accounts.rst │ │ ├── COPYME │ │ ├── developer-environment.rst │ │ ├── fluentbit-fluentd-architecture.rst │ │ ├── index.rst │ │ ├── multi-os.rst │ │ ├── neutron-multiple-sdns.rst │ │ ├── nginx-sidecar.rst │ │ ├── osh-1.0-requirements.rst │ │ ├── osh-lma-stack.rst │ │ ├── support-OCI-image-registry-with-authentication-turned-on.rst │ │ ├── support-linux-bridge-on-neutron.rst │ │ ├── tenant-ceph.rst │ │ └── values-ordering.rst │ ├── testing/ │ │ ├── ceph-node-resiliency.rst │ │ ├── ceph-resiliency/ │ │ │ ├── README.rst │ │ │ ├── disk-failure.rst │ │ │ ├── failure-domain.rst │ │ │ ├── host-failure.rst │ │ │ ├── index.rst │ │ │ ├── monitor-failure.rst │ │ │ ├── namespace-deletion.rst │ │ │ ├── osd-failure.rst │ │ │ └── validate-object-replication.rst │ │ ├── ceph-upgrade.rst │ │ ├── helm-tests.rst │ │ └── index.rst │ ├── troubleshooting/ │ │ ├── ceph.rst │ │ ├── database.rst │ │ ├── index.rst │ │ ├── migrate-ceph-to-rook.rst │ │ ├── persistent-storage.rst │ │ └── ubuntu-hwe-kernel.rst │ └── upgrade/ │ ├── index.rst │ └── multiple-osd-releases.rst ├── elastic-apm-server/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-elasticsearch-creds.yaml │ │ ├── secret-registry.yaml │ │ └── service.yaml │ └── values.yaml ├── elastic-filebeat/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-elasticsearch-creds.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── elastic-metricbeat/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-etc.yaml │ │ ├── daemonset-node-metrics.yaml │ │ ├── deployment-modules.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-elasticsearch-creds.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── elastic-packetbeat/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-etc.yaml │ │ ├── daemonset.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-elasticsearch-creds.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── elasticsearch/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _apache.sh.tpl │ │ │ ├── _ceph-admin-keyring.sh.tpl │ │ │ ├── _create_s3_buckets.sh.tpl │ │ │ ├── _create_s3_users.sh.tpl │ │ │ ├── _create_template.sh.tpl │ │ │ ├── _curator.sh.tpl │ │ │ ├── _elasticsearch.sh.tpl │ │ │ ├── _helm-tests.sh.tpl │ │ │ └── _verify-repositories.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin-curator.yaml │ │ ├── configmap-bin-elasticsearch.yaml │ │ ├── configmap-etc-curator.yaml │ │ ├── configmap-etc-elasticsearch.yaml │ │ ├── cron-job-curator.yaml │ │ ├── cron-job-verify-repositories.yaml │ │ ├── deployment-client.yaml │ │ ├── deployment-gateway.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-elasticsearch.yaml │ │ ├── job-elasticsearch-template.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-s3-bucket.yaml │ │ ├── job-s3-user.yaml │ │ ├── monitoring/ │ │ │ └── prometheus/ │ │ │ ├── exporter-deployment.yaml │ │ │ ├── exporter-network-policy.yaml │ │ │ └── exporter-service.yaml │ │ ├── network-policy.yaml │ │ ├── object-bucket-claim.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-elasticsearch.yaml │ │ ├── secret-environment.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-s3-user.yaml │ │ ├── service-data.yaml │ │ ├── service-discovery.yaml │ │ ├── service-gateway.yaml │ │ ├── service-ingress-elasticsearch.yaml │ │ ├── service-logging.yaml │ │ ├── statefulset-data.yaml │ │ └── statefulset-master.yaml │ └── values.yaml ├── etcd/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _etcd-db-compact.sh.tpl │ │ │ ├── _etcd-healthcheck.sh.tpl │ │ │ └── _etcd.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── cron-job-db-compact.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-registry.yaml │ │ ├── service-discovery.yaml │ │ ├── service.yaml │ │ └── statefulset.yaml │ └── values.yaml ├── fluentbit/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _fluent-bit.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-fluent-bit.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── fluentd/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _fluentd.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── secret-elasticsearch-creds.yaml │ │ ├── secret-fluentd.yaml │ │ ├── secret-kafka-creds.yaml │ │ ├── secret-registry.yaml │ │ └── service-fluentd.yaml │ └── values.yaml ├── freezer/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ └── _freezer-api.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── pdb-api.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── glance/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _ceph-admin-keyring.sh.tpl │ │ │ ├── _ceph-keyring.sh.tpl │ │ │ ├── _clean-image.sh.tpl │ │ │ ├── _clean-secrets.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _glance-api.sh.tpl │ │ │ ├── _iscsiadm.tpl │ │ │ ├── _metadefs-load.sh.tpl │ │ │ ├── _multipath.tpl │ │ │ ├── _multipathd.tpl │ │ │ ├── _nginx.sh.tpl │ │ │ └── _storage-init.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-clean.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-metadefs-load.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── job-storage-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-rally-test.yaml │ │ ├── pvc-images.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── gnocchi/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _ceph-admin-keyring.sh.tpl │ │ │ ├── _ceph-keyring.sh.tpl │ │ │ ├── _clean-secrets.sh.tpl │ │ │ ├── _db-init.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _gnocchi-api.sh.tpl │ │ │ ├── _gnocchi-metricd.sh.tpl │ │ │ ├── _gnocchi-resources-cleaner.sh.tpl │ │ │ ├── _gnocchi-statsd.sh.tpl │ │ │ ├── _gnocchi-test.sh.tpl │ │ │ └── _storage-init.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-resources-cleaner.yaml │ │ ├── daemonset-metricd.yaml │ │ ├── daemonset-statsd.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-clean.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init-indexer.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-storage-init.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-gnocchi-test.yaml │ │ ├── secret-db-indexer.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── service-api.yaml │ │ ├── service-ingress-api.yaml │ │ └── service-statsd.yaml │ └── values.yaml ├── grafana/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _db-session-sync.py.tpl │ │ │ ├── _grafana.sh.tpl │ │ │ ├── _selenium-tests.py.tpl │ │ │ └── _set-admin-password.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-dashboards.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-grafana.yaml │ │ ├── job-db-init-session.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-session-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-run-migrator.yaml │ │ ├── job-set-admin-user.yaml │ │ ├── network_policy.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-admin-creds.yaml │ │ ├── secret-db-session.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-prom-creds.yaml │ │ ├── secret-registry.yaml │ │ ├── secrets/ │ │ │ └── _my.cnf.tpl │ │ ├── service-ingress.yaml │ │ └── service.yaml │ └── values.yaml ├── heat/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _heat-api.sh.tpl │ │ │ ├── _heat-cfn.sh.tpl │ │ │ ├── _heat-engine-cleaner.sh.tpl │ │ │ ├── _heat-engine.sh.tpl │ │ │ ├── _heat-purge-deleted-active.sh.tpl │ │ │ └── _trusts.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-engine-cleaner.yaml │ │ ├── cron-job-purge-deleted.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-cfn.yaml │ │ ├── deployment-engine.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── ingress-cfn.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user-domain.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── job-trusts.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pdb-cfn.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ ├── service-cfn.yaml │ │ ├── service-ingress-api.yaml │ │ └── service-ingress-cfn.yaml │ └── values.yaml ├── helm-toolkit/ │ ├── Chart.yaml │ └── templates/ │ ├── endpoints/ │ │ ├── _authenticated_endpoint_uri_lookup.tpl │ │ ├── _authenticated_transport_endpoint_uri_lookup.tpl │ │ ├── _endpoint_host_lookup.tpl │ │ ├── _endpoint_port_lookup.tpl │ │ ├── _endpoint_token_lookup.tpl │ │ ├── _host_and_port_endpoint_uri_lookup.tpl │ │ ├── _hostname_fqdn_endpoint_lookup.tpl │ │ ├── _hostname_namespaced_endpoint_lookup.tpl │ │ ├── _hostname_namespaced_endpoint_namespace_lookup.tpl │ │ ├── _hostname_short_endpoint_lookup.tpl │ │ ├── _keystone_endpoint_name_lookup.tpl │ │ ├── _keystone_endpoint_path_lookup.tpl │ │ ├── _keystone_endpoint_scheme_lookup.tpl │ │ ├── _keystone_endpoint_uri_lookup.tpl │ │ └── _service_name_endpoint_with_namespace_lookup.tpl │ ├── manifests/ │ │ ├── _ceph-storageclass.tpl │ │ ├── _certificates.tpl │ │ ├── _configmap-oslo-policy.tpl │ │ ├── _ingress.tpl │ │ ├── _job-bootstrap.tpl │ │ ├── _job-db-drop-mysql.tpl │ │ ├── _job-db-init-mysql.tpl │ │ ├── _job-db-sync.tpl │ │ ├── _job-ks-endpoints.tpl │ │ ├── _job-ks-service.tpl │ │ ├── _job-ks-user.yaml.tpl │ │ ├── _job-rabbit-init.yaml.tpl │ │ ├── _job-s3-bucket.yaml.tpl │ │ ├── _job-s3-user.yaml.tpl │ │ ├── _job_image_repo_sync.tpl │ │ ├── _network_policy.tpl │ │ ├── _secret-ks-etc.yaml.tpl │ │ ├── _secret-registry.yaml.tpl │ │ ├── _secret-tls.yaml.tpl │ │ └── _service-ingress.tpl │ ├── scripts/ │ │ ├── _create-s3-user.sh.tpl │ │ ├── _db-drop.py.tpl │ │ ├── _db-init.py.tpl │ │ ├── _db-pg-init.sh.tpl │ │ ├── _image-repo-sync.sh.tpl │ │ ├── _ks-domain-user.sh.tpl │ │ ├── _ks-endpoints.sh.tpl │ │ ├── _ks-service.sh.tpl │ │ ├── _ks-user.sh.tpl │ │ ├── _rabbit-init.sh.tpl │ │ ├── _rally_test.sh.tpl │ │ └── db-backup-restore/ │ │ ├── _backup_main.sh.tpl │ │ └── _restore_main.sh.tpl │ ├── snippets/ │ │ ├── _custom_job_annotations.tpl │ │ ├── _custom_pod_annotations.tpl │ │ ├── _custom_secret_annotations.tpl │ │ ├── _image.tpl │ │ ├── _keystone_openrc_env_vars.tpl │ │ ├── _keystone_openrc_failover_env_vars.tpl │ │ ├── _keystone_secret_openrc.tpl │ │ ├── _keystone_user_create_env_vars.tpl │ │ ├── _kubernetes_apparmor_configmap.tpl │ │ ├── _kubernetes_apparmor_loader_init_container.tpl │ │ ├── _kubernetes_apparmor_volumes.tpl │ │ ├── _kubernetes_container_security_context.tpl │ │ ├── _kubernetes_entrypoint_init_container.tpl │ │ ├── _kubernetes_kubectl_params.tpl │ │ ├── _kubernetes_mandatory_access_control_annotation.tpl │ │ ├── _kubernetes_metadata_labels.tpl │ │ ├── _kubernetes_pod_anti_affinity.tpl │ │ ├── _kubernetes_pod_image_pull_secret.tpl │ │ ├── _kubernetes_pod_priority_class.tpl │ │ ├── _kubernetes_pod_rbac_roles.tpl │ │ ├── _kubernetes_pod_rbac_serviceaccount.tpl │ │ ├── _kubernetes_pod_runtime_class.tpl │ │ ├── _kubernetes_pod_security_context.tpl │ │ ├── _kubernetes_probes.tpl │ │ ├── _kubernetes_resources.tpl │ │ ├── _kubernetes_seccomp_annotation.tpl │ │ ├── _kubernetes_tolerations.tpl │ │ ├── _kubernetes_upgrades_daemonset.tpl │ │ ├── _kubernetes_upgrades_deployment.tpl │ │ ├── _kubernetes_upgrades_statefulset.tpl │ │ ├── _mon_host_from_k8s_ep.sh.tpl │ │ ├── _prometheus_pod_annotations.tpl │ │ ├── _prometheus_service_annotations.tpl │ │ ├── _release_uuid.tpl │ │ ├── _rgw_s3_admin_env_vars.tpl │ │ ├── _rgw_s3_bucket_user_env_vars_rook.tpl │ │ ├── _rgw_s3_secret_creds.tpl │ │ ├── _rgw_s3_user_env_vars.tpl │ │ ├── _service_params.tpl │ │ ├── _tls_volume.tpl │ │ ├── _tls_volume_mount.tpl │ │ └── _values_template_renderer.tpl │ ├── tls/ │ │ └── _tls_generate_certs.tpl │ └── utils/ │ ├── _comma_joined_service_list.tpl │ ├── _configmap_templater.tpl │ ├── _daemonset_overrides.tpl │ ├── _daemonset_overrides_root.tpl │ ├── _dependency_jobs.tpl │ ├── _dependency_resolver.tpl │ ├── _hash.tpl │ ├── _hash2.tpl │ ├── _host_list.tpl │ ├── _image_sync_list.tpl │ ├── _joinListWithComma.tpl │ ├── _joinListWithCommaAndSingleQuotes.tpl │ ├── _joinListWithPrefix.tpl │ ├── _joinListWithSpace.tpl │ ├── _merge.tpl │ ├── _template.tpl │ ├── _to_ini.tpl │ ├── _to_k8s_env_secret_vars.tpl │ ├── _to_k8s_env_vars.tpl │ ├── _to_kv_list.tpl │ └── _to_oslo_conf.tpl ├── horizon/ │ ├── .helmignore │ ├── Chart.yaml │ ├── releasenotes/ │ │ └── notes/ │ │ ├── horizon-023da44e7958de05.yaml │ │ └── horizon-4c5d5e3b58c700a0.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _django.wsgi.tpl │ │ │ ├── _horizon.sh.tpl │ │ │ ├── _manage.py.tpl │ │ │ └── _selenium-test.py.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── configmap-logo.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── pdb.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress.yaml │ │ └── service.yaml │ └── values.yaml ├── ironic/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _ironic-api.sh.tpl │ │ │ ├── _ironic-conductor-init.sh.tpl │ │ │ ├── _ironic-conductor.sh.tpl │ │ │ ├── _manage-cleaning-network.sh.tpl │ │ │ └── _retreive-swift-config.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-manage-cleaning-network.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ ├── service-ingress-api.yaml │ │ └── statefulset-conductor.yaml │ └── values.yaml ├── keystone/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _cred-clean.py.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _domain-manage-init.sh.tpl │ │ │ ├── _domain-manage.py.tpl │ │ │ ├── _domain-manage.sh.tpl │ │ │ ├── _fernet-manage.py.tpl │ │ │ └── _keystone-api.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-credential-rotate.yaml │ │ ├── cron-job-fernet-rotate.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-credential-cleanup.yaml │ │ ├── job-credential-setup.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-domain-manage.yaml │ │ ├── job-fernet-setup.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-credential-keys.yaml │ │ ├── secret-db.yaml │ │ ├── secret-fernet-keys.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ldap-tls.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── kibana/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _apache.sh.tpl │ │ │ ├── _create_kibana_index_patterns.sh.tpl │ │ │ ├── _flush_kibana_metadata.sh.tpl │ │ │ └── _kibana.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-kibana.yaml │ │ ├── job-flush-kibana-metadata.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-register-kibana-indexes.yaml │ │ ├── network_policy.yaml │ │ ├── secret-elasticsearch-creds.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress-kibana.yaml │ │ └── service.yaml │ └── values.yaml ├── kube-dns/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-bin.yaml │ │ ├── configmap-kube-dns.yaml │ │ ├── deployment-kube-dns.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-registry.yaml │ │ ├── service-kube-dns.yaml │ │ └── serviceaccount-kube-dns.yaml │ └── values.yaml ├── kubernetes-keystone-webhook/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _kubernetes-keystone-webhook-test.sh.tpl │ │ │ └── _start.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress.yaml │ │ ├── pod-test.yaml │ │ ├── secret-certificates.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress-api.yaml │ │ └── service.yaml │ └── values.yaml ├── kubernetes-node-problem-detector/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _node-problem-detector.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-registry.yaml │ │ └── service.yaml │ └── values.yaml ├── ldap/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── _helpers.tpl │ │ ├── bin/ │ │ │ └── _bootstrap.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── secret-registry.yaml │ │ ├── service.yaml │ │ └── statefulset.yaml │ └── values.yaml ├── libvirt/ │ ├── .helmignore │ ├── Chart.yaml │ ├── releasenotes/ │ │ └── notes/ │ │ └── libvirt-339936ca478fbf50.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _ceph-admin-keyring.sh.tpl │ │ │ ├── _ceph-keyring.sh.tpl │ │ │ └── _libvirt.sh.tpl │ │ ├── configmap-apparmor.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-libvirt.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network-policy.yaml │ │ ├── pod-monitor.yaml │ │ ├── role-cert-manager.yaml │ │ ├── secret-registry.yaml │ │ └── utils/ │ │ └── _to_libvirt_conf.tpl │ └── values.yaml ├── local-storage/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── extra-manifests.yaml │ │ ├── persistent-volumes.yaml │ │ └── storage-class.yaml │ └── values.yaml ├── local-volume-provisioner/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _fakemount.py.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-lvp.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-registry.yaml │ │ └── storageclasses.yaml │ └── values.yaml ├── magnum/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _magnum-api.sh.tpl │ │ │ ├── _magnum-conductor-init.sh.tpl │ │ │ └── _magnum-conductor.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user-domain.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── kubeconfig.tpl │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ ├── service-ingress-api.yaml │ │ └── statefulset-conductor.yaml │ └── values.yaml ├── manila/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _ceph-keyring.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _manila-api.sh.tpl │ │ │ ├── _manila-data.sh.tpl │ │ │ ├── _manila-scheduler.sh.tpl │ │ │ ├── _manila-share-init.sh.tpl │ │ │ └── _manila-share.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-data.yaml │ │ ├── deployment-scheduler.yaml │ │ ├── deployment-share.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── mariadb/ │ ├── .helmignore │ ├── Chart.yaml │ ├── README.rst │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _backup_mariadb.sh.tpl │ │ │ ├── _health.sh.tpl │ │ │ ├── _mariadb-wait-for-cluster.py.tpl │ │ │ ├── _mariadb_controller.py.tpl │ │ │ ├── _prometheus-create-mysql-user.sh.tpl │ │ │ ├── _prometheus-mysqld-exporter.sh.tpl │ │ │ ├── _restore_mariadb.sh.tpl │ │ │ ├── _start.py.tpl │ │ │ ├── _start_mariadb_verify_server.sh.tpl │ │ │ └── _test.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── configmap-services-tcp.yaml │ │ ├── cron-job-backup-mariadb.yaml │ │ ├── deployment-controller.yaml │ │ ├── exporter-configmap-bin.yaml │ │ ├── exporter-job-create-user.yaml │ │ ├── exporter-secrets-etc.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-cluster-wait.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-user.yaml │ │ ├── mariadb-backup-pvc.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-mariadb.yaml │ │ ├── pod-test.yaml │ │ ├── secret-backup-restore.yaml │ │ ├── secret-dbadmin-password.yaml │ │ ├── secret-dbaudit-password.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-rgw.yaml │ │ ├── secret-sst-password.yaml │ │ ├── secrets/ │ │ │ ├── _admin_user.cnf.tpl │ │ │ ├── _admin_user_internal.cnf.tpl │ │ │ └── _prometheus-exporter_user.cnf.tpl │ │ ├── secrets-etc.yaml │ │ ├── service-discovery.yaml │ │ ├── service-master.yaml │ │ ├── service.yaml │ │ └── statefulset.yaml │ └── values.yaml ├── mariadb-backup/ │ ├── Chart.yaml │ ├── README.rst │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _backup_mariadb.sh.tpl │ │ │ ├── _restore_mariadb.sh.tpl │ │ │ └── _start_mariadb_verify_server.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-backup-mariadb.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-user.yaml │ │ ├── mariadb-backup-pvc.yaml │ │ ├── secret-backup-restore.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-rgw.yaml │ │ ├── secrets/ │ │ │ ├── _admin_user.cnf.tpl │ │ │ └── _admin_user_internal.cnf.tpl │ │ └── secrets-etc.yaml │ └── values.yaml ├── mariadb-cluster/ │ ├── .helmignore │ ├── Chart.yaml │ ├── README.rst │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _liveness.sh.tpl │ │ │ ├── _readiness.sh.tpl │ │ │ └── _test.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-refresh-statefulset.yaml │ │ ├── mariadb.yaml │ │ ├── network_policy.yaml │ │ ├── pod-test.yaml │ │ ├── secret-dbadmin-password.yaml │ │ ├── secret-dbaudit-password.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-sst-password.yaml │ │ ├── secrets/ │ │ │ ├── _admin_user.cnf.tpl │ │ │ ├── _admin_user_internal.cnf.tpl │ │ │ └── _privileges.sql.tpl │ │ └── secrets-etc.yaml │ └── values.yaml ├── masakari/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _manage-db.sh.tpl │ │ │ ├── _masakari-api.sh.tpl │ │ │ ├── _masakari-engine.sh.tpl │ │ │ ├── _masakari-host-monitor.sh.tpl │ │ │ ├── _masakari-instance-monitor.sh.tpl │ │ │ ├── _masakari-introspective-instance-monitor.sh.tpl │ │ │ ├── _masakari-monitors-init.sh.tpl │ │ │ └── _masakari-process-monitor.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-host-monitor.yaml │ │ ├── daemonset-instance-monitor.yaml │ │ ├── daemonset-introspective-instance-monitor.yaml │ │ ├── daemonset-process-monitor.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-engine.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbitmq-init.yaml │ │ ├── pbd-api.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ └── service-api.yaml │ └── values.yaml ├── memcached/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _memcached.sh.tpl │ │ ├── configmap-apparmor.yaml │ │ ├── configmap-bin.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── secret-registry.yaml │ │ ├── service.yaml │ │ └── statefulset.yaml │ └── values.yaml ├── mistral/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _mistral-api.sh.tpl │ │ │ ├── _mistral-engine.sh.tpl │ │ │ ├── _mistral-event-engine.sh.tpl │ │ │ └── _mistral-executor.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-executor.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ ├── service-ingress-api.yaml │ │ ├── statefulset-engine.yaml │ │ └── statefulset-event-engine.yaml │ └── values.yaml ├── nagios/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _apache.sh.tpl │ │ │ ├── _nagios-readiness.sh.tpl │ │ │ └── _selenium-tests.py.tpl │ │ ├── configmap-additional-plugins.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-nagios.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-nagios.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress-nagios.yaml │ │ └── service.yaml │ └── values.yaml ├── namespace-config/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── extra-manifests.yaml │ │ └── limit-range.yaml │ └── values.yaml ├── neutron/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _health-probe.py.tpl │ │ │ ├── _neutron-bagpipe-bgp-init.sh.tpl │ │ │ ├── _neutron-bagpipe-bgp.sh.tpl │ │ │ ├── _neutron-bgp-dragent.sh.tpl │ │ │ ├── _neutron-dhcp-agent-init.sh.tpl │ │ │ ├── _neutron-dhcp-agent.sh.tpl │ │ │ ├── _neutron-ironic-agent-init.sh.tpl │ │ │ ├── _neutron-ironic-agent.sh.tpl │ │ │ ├── _neutron-l2gw-agent.sh.tpl │ │ │ ├── _neutron-l3-agent-init.sh.tpl │ │ │ ├── _neutron-l3-agent.sh.tpl │ │ │ ├── _neutron-linuxbridge-agent-init-modules.sh.tpl │ │ │ ├── _neutron-linuxbridge-agent-init.sh.tpl │ │ │ ├── _neutron-linuxbridge-agent.sh.tpl │ │ │ ├── _neutron-metadata-agent-init.sh.tpl │ │ │ ├── _neutron-metadata-agent.sh.tpl │ │ │ ├── _neutron-netns-cleanup-cron.sh.tpl │ │ │ ├── _neutron-openvswitch-agent-init-modules.sh.tpl │ │ │ ├── _neutron-openvswitch-agent-init-netoffload.sh.tpl │ │ │ ├── _neutron-openvswitch-agent-init.sh.tpl │ │ │ ├── _neutron-openvswitch-agent-liveness.sh.tpl │ │ │ ├── _neutron-openvswitch-agent-readiness.sh.tpl │ │ │ ├── _neutron-openvswitch-agent.sh.tpl │ │ │ ├── _neutron-ovn-db-sync.sh.tpl │ │ │ ├── _neutron-ovn-init.sh.tpl │ │ │ ├── _neutron-ovn-metadata-agent.sh.tpl │ │ │ ├── _neutron-ovn-vpn-agent-init.sh.tpl │ │ │ ├── _neutron-ovn-vpn-agent.sh.tpl │ │ │ ├── _neutron-rpc-server.sh.tpl │ │ │ ├── _neutron-server.sh.tpl │ │ │ ├── _neutron-sriov-agent-init.sh.tpl │ │ │ ├── _neutron-sriov-agent.sh.tpl │ │ │ ├── _neutron-test-force-cleanup.sh.tpl │ │ │ └── _nginx.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-ovn-db-sync.yaml │ │ ├── daemonset-bagpipe-bgp.yaml │ │ ├── daemonset-bgp-dragent.yaml │ │ ├── daemonset-dhcp-agent.yaml │ │ ├── daemonset-l2gw-agent.yaml │ │ ├── daemonset-l3-agent.yaml │ │ ├── daemonset-lb-agent.yaml │ │ ├── daemonset-metadata-agent.yaml │ │ ├── daemonset-netns-cleanup-cron.yaml │ │ ├── daemonset-neutron-ovn-vpn-agent.yaml │ │ ├── daemonset-ovn-metadata-agent.yaml │ │ ├── daemonset-ovs-agent.yaml │ │ ├── daemonset-sriov-agent.yaml │ │ ├── deployment-ironic-agent.yaml │ │ ├── deployment-rpc_server.yaml │ │ ├── deployment-server.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-server.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-server.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ks-etc.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress-neutron.yaml │ │ └── service-server.yaml │ └── values.yaml ├── nfs-provisioner/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-bin.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-registry.yaml │ │ ├── service.yaml │ │ ├── storage_class.yaml │ │ └── volume_claim.yaml │ └── values.yaml ├── nova/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _cell-setup-init.sh.tpl │ │ │ ├── _cell-setup.sh.tpl │ │ │ ├── _ceph-admin-keyring.sh.tpl │ │ │ ├── _ceph-keyring.sh.tpl │ │ │ ├── _db-archive-deleted-row.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _fake-iptables.sh.tpl │ │ │ ├── _health-probe.py.tpl │ │ │ ├── _iscsiadm.tpl │ │ │ ├── _multipath.tpl │ │ │ ├── _multipathd.tpl │ │ │ ├── _nova-api-metadata-init.sh.tpl │ │ │ ├── _nova-api-metadata.sh.tpl │ │ │ ├── _nova-api.sh.tpl │ │ │ ├── _nova-compute-init.sh.tpl │ │ │ ├── _nova-compute-ironic.sh.tpl │ │ │ ├── _nova-compute.sh.tpl │ │ │ ├── _nova-conductor.sh.tpl │ │ │ ├── _nova-console-compute-init.sh.tpl │ │ │ ├── _nova-console-proxy-init-assets.sh.tpl │ │ │ ├── _nova-console-proxy-init.sh.tpl │ │ │ ├── _nova-console-proxy.sh.tpl │ │ │ ├── _nova-scheduler.sh.tpl │ │ │ ├── _nova-service-cleaner.sh.tpl │ │ │ ├── _ssh-init.sh.tpl │ │ │ ├── _ssh-start.sh.tpl │ │ │ ├── _storage-init.sh.tpl │ │ │ └── _wait-for-computes-init.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-archive-deleted-rows.yaml │ │ ├── cron-job-cell-setup.yaml │ │ ├── cron-job-service-cleaner.yaml │ │ ├── daemonset-compute.yaml │ │ ├── deployment-api-metadata.yaml │ │ ├── deployment-api-osapi.yaml │ │ ├── deployment-conductor.yaml │ │ ├── deployment-novncproxy.yaml │ │ ├── deployment-scheduler.yaml │ │ ├── deployment-serialproxy.yaml │ │ ├── deployment-spiceproxy.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-metadata.yaml │ │ ├── ingress-novncproxy.yaml │ │ ├── ingress-osapi.yaml │ │ ├── ingress-serialproxy.yaml │ │ ├── ingress-spiceproxy.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-cell-setup.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-nova-storage-init.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── netpol-nova.yaml │ │ ├── pdb-metadata.yaml │ │ ├── pdb-osapi.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db-api.yaml │ │ ├── secret-db-cell0.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ks-etc.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-ssh.yaml │ │ ├── service-ingress-metadata.yaml │ │ ├── service-ingress-novncproxy.yaml │ │ ├── service-ingress-osapi.yaml │ │ ├── service-ingress-serialproxy.yaml │ │ ├── service-ingress-spiceproxy.yaml │ │ ├── service-metadata.yaml │ │ ├── service-novncproxy.yaml │ │ ├── service-osapi.yaml │ │ ├── service-serialproxy.yaml │ │ ├── service-spiceproxy.yaml │ │ ├── statefulset-compute-ironic.yaml │ │ ├── statefulset-conductor.yaml │ │ └── statefulset-scheduler.yaml │ └── values.yaml ├── octavia/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _octavia-api.sh.tpl │ │ │ ├── _octavia-driver-agent.sh.tpl │ │ │ ├── _octavia-health-manager-get-port.sh.tpl │ │ │ ├── _octavia-health-manager-nic-init.sh.tpl │ │ │ ├── _octavia-health-manager.sh.tpl │ │ │ ├── _octavia-housekeeping.sh.tpl │ │ │ ├── _octavia-worker-get-port.sh.tpl │ │ │ ├── _octavia-worker-nic-init.sh.tpl │ │ │ └── _octavia-worker.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-health-manager.yaml │ │ ├── daemonset-worker.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-driver-agent.yaml │ │ ├── deployment-housekeeping.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoint.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── secret-db-persistence.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── openvswitch/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _openvswitch-db-server.sh.tpl │ │ │ ├── _openvswitch-vswitchd-init-modules.sh.tpl │ │ │ └── _openvswitch-vswitchd.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── daemonset.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network-policy.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── ovn/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _ovn-controller-init.sh.tpl │ │ │ └── _ovn-network-logging-parser.sh.tpl │ │ ├── clusterrole-controller.yaml │ │ ├── clusterrolebinding-controller.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-controller.yaml │ │ ├── deployment-northd.yaml │ │ ├── extra-manifests.yaml │ │ ├── role-controller.yaml │ │ ├── role-northd.yaml │ │ ├── role-ovsdb.yaml │ │ ├── rolebinding-controller.yaml │ │ ├── rolebinding-northd.yaml │ │ ├── rolebinding-ovsdb.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-vector.yaml │ │ ├── service-ovsdb-nb.yaml │ │ ├── service-ovsdb-sb.yaml │ │ ├── statefulset-ovsdb-nb.yaml │ │ └── statefulset-ovsdb-sb.yaml │ └── values.yaml ├── placement/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _db-sync.sh.tpl │ │ │ └── _placement-api.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── network_policy.yaml │ │ ├── pdb.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ks-etc.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress.yaml │ │ └── service.yaml │ └── values.yaml ├── playbooks/ │ ├── build-chart.yaml │ ├── collect-logs.yaml │ ├── deploy-env-kubespray.yaml │ ├── deploy-env.yaml │ ├── enable-hugepages.yaml │ ├── inject-keys.yaml │ ├── lint.yaml │ ├── mount-volumes.yaml │ ├── osh-bandit.yaml │ ├── prepare-hosts.yaml │ ├── publish/ │ │ ├── post.yaml │ │ └── run.yaml │ └── run-scripts.yaml ├── postgresql/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _backup_postgresql.sh.tpl │ │ │ ├── _common_backup_restore.sh.tpl │ │ │ ├── _db_test.sh.tpl │ │ │ ├── _postgresql_archive_cleanup.sh.tpl │ │ │ ├── _readiness.sh.tpl │ │ │ ├── _remote_retrieve_postgresql.sh.tpl │ │ │ ├── _remote_store_postgresql.sh.tpl │ │ │ ├── _restore_postgresql.sh.tpl │ │ │ └── _start.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-backup-postgres.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-user.yaml │ │ ├── monitoring/ │ │ │ └── prometheus/ │ │ │ ├── bin/ │ │ │ │ └── _create-postgresql-exporter-user.sh.tpl │ │ │ ├── exporter-configmap-bin.yaml │ │ │ ├── exporter-configmap-etc.yaml │ │ │ ├── exporter-deployment.yaml │ │ │ ├── exporter-job-create-user.yaml │ │ │ ├── exporter-secrets-etc.yaml │ │ │ └── exporter-service.yaml │ │ ├── network_policy.yaml │ │ ├── pod-test.yaml │ │ ├── postgresql-backup-pvc.yaml │ │ ├── secret-admin.yaml │ │ ├── secret-audit.yaml │ │ ├── secret-backup-restore.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-rgw.yaml │ │ ├── secrets/ │ │ │ └── _admin_user.conf.tpl │ │ ├── secrets-etc.yaml │ │ ├── service-postgres.yaml │ │ ├── service-restapi.yaml │ │ └── statefulset.yaml │ └── values.yaml ├── powerdns/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _powerdns-mysql-sync.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-db.yaml │ │ ├── secret-registry.yaml │ │ └── service.yaml │ └── values.yaml ├── prometheus/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _apache.sh.tpl │ │ │ ├── _helm-tests.sh.tpl │ │ │ └── _prometheus.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-prometheus.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── pod-helm-tests.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-prometheus.yaml │ │ ├── secret-registry.yaml │ │ ├── secret-tls-configs.yaml │ │ ├── service-ingress-prometheus.yaml │ │ ├── service.yaml │ │ ├── statefulset.yaml │ │ └── utils/ │ │ └── _command_line_flags.tpl │ └── values.yaml ├── prometheus-alertmanager/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _alertmanager.sh.tpl │ │ │ └── _apache.sh.tpl │ │ ├── clusterrolebinding.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-alertmanager.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── secret-admin-user.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-registry.yaml │ │ ├── service-discovery.yaml │ │ ├── service-ingress-alertmanager.yaml │ │ ├── service.yaml │ │ └── statefulset.yaml │ └── values.yaml ├── prometheus-blackbox-exporter/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── secret-registry.yaml │ │ ├── secret.yaml │ │ └── service.yaml │ └── values.yaml ├── prometheus-kube-state-metrics/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-bin.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── secret-registry.yaml │ │ ├── service-controller-manager.yaml │ │ ├── service-kube-state-metrics.yaml │ │ └── service-scheduler.yaml │ └── values.yaml ├── prometheus-mysql-exporter/ │ ├── .helmignore │ ├── Chart.yaml │ ├── README.rst │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _create-mysql-user.sh.tpl │ │ │ └── _mysqld-exporter.sh.tpl │ │ ├── exporter-configmap-bin.yaml │ │ ├── exporter-deployment.yaml │ │ ├── exporter-job-create-user.yaml │ │ ├── exporter-network-policy.yaml │ │ ├── exporter-secrets-etc.yaml │ │ ├── exporter-service.yaml │ │ ├── extra-manifests.yaml │ │ └── secrets/ │ │ └── _exporter_user.cnf.tpl │ └── values.yaml ├── prometheus-node-exporter/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _node-exporter.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── daemonset.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── secret-registry.yaml │ │ └── service.yaml │ └── values.yaml ├── prometheus-openstack-exporter/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ └── _prometheus-openstack-exporter.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-user.yaml │ │ ├── network_policy.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-registry.yaml │ │ └── service.yaml │ └── values.yaml ├── prometheus-process-exporter/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── daemonset.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── secret-registry.yaml │ │ └── service.yaml │ └── values.yaml ├── rabbitmq/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _rabbitmq-cookie.sh.tpl │ │ │ ├── _rabbitmq-liveness.sh.tpl │ │ │ ├── _rabbitmq-password-hash.py.tpl │ │ │ ├── _rabbitmq-readiness.sh.tpl │ │ │ ├── _rabbitmq-start.sh.tpl │ │ │ ├── _rabbitmq-test.sh.tpl │ │ │ └── _rabbitmq-wait-for-cluster.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── etc/ │ │ │ └── _enabled_plugins.tpl │ │ ├── extra-manifests.yaml │ │ ├── ingress-management.yaml │ │ ├── job-cluster-wait.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── network_policy.yaml │ │ ├── pod-test.yaml │ │ ├── secret-erlang-cookie.yaml │ │ ├── secret-rabbit-admin.yaml │ │ ├── secret-rabbitmq-users-credentials.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress-management.yaml │ │ ├── service.yaml │ │ ├── statefulset.yaml │ │ └── utils/ │ │ └── _to_rabbit_config.tpl │ └── values.yaml ├── rally/ │ ├── Chart.yaml │ ├── README.rst │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _manage-db.sh.tpl │ │ │ └── _run-task.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── configmap-tasks.yaml │ │ ├── configmap-test-templates.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-init.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-manage-db.yaml │ │ ├── job-run-task.yaml │ │ ├── pdb-api.yaml │ │ ├── pvc-rally.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── redis/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── configmap-bin.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── pod_test.yaml │ │ ├── secret-registry.yaml │ │ ├── service.yaml │ │ └── test/ │ │ ├── _python_redis_tests.py.tpl │ │ └── _redis_test.sh.tpl │ └── values.yaml ├── registry/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _registry-proxy.sh.tpl │ │ │ └── _registry.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-registry-proxy.yaml │ │ ├── deployment-registry.yaml │ │ ├── etc/ │ │ │ └── _default.conf.tpl │ │ ├── extra-manifests.yaml │ │ ├── job-bootstrap.yaml │ │ ├── pvc-images.yaml │ │ ├── secret-registry.yaml │ │ └── service-registry.yaml │ └── values.yaml ├── release.asc ├── releasenotes/ │ ├── config.yaml │ ├── notes/ │ │ ├── added-nova-uid-parameter-to-ovs-chart-41d2b05b79300a31.yaml │ │ ├── aodh-0fe345390dd08642.yaml │ │ ├── aodh-1002dad350db1c60.yaml │ │ ├── aodh-bb91c011b0c7d911.yaml │ │ ├── aodh.yaml │ │ ├── barbican-669168de73ab5847.yaml │ │ ├── barbican-d291498fada9e601.yaml │ │ ├── barbican-ead8061b2a6b1b1b.yaml │ │ ├── barbican.yaml │ │ ├── blazar-73cedded47699964.yaml │ │ ├── blazar-a7b9b29ba15720c0.yaml │ │ ├── blazar-b7fc5016b49c8f59.yaml │ │ ├── ca-clusterissuer.yaml │ │ ├── ca-issuer.yaml │ │ ├── ceilometer-15768e1064d3339d.yaml │ │ ├── ceilometer-8fc69d6664cdf101.yaml │ │ ├── ceilometer-ab177a5c0aad98df.yaml │ │ ├── ceilometer-b03ea218e1e61f90.yaml │ │ ├── ceilometer-b86532145d088208.yaml │ │ ├── ceilometer-c08f029ffa1e122f.yaml │ │ ├── ceilometer.yaml │ │ ├── ceph-adapter-rook-2fd83689f9bf78fb.yaml │ │ ├── ceph-adapter-rook-f0855e8843fe615f.yaml │ │ ├── ceph-adapter-rook.yaml │ │ ├── ceph-client-055d675e86b2d0ea.yaml │ │ ├── ceph-client-f4c8397a4313c53a.yaml │ │ ├── ceph-client.yaml │ │ ├── ceph-mon-1a1ecc38a96bfead.yaml │ │ ├── ceph-mon-5ece5f0b0f571966.yaml │ │ ├── ceph-mon-a1f450d714b90cfb.yaml │ │ ├── ceph-mon-f029c2a86a0b7edd.yaml │ │ ├── ceph-mon.yaml │ │ ├── ceph-osd-294b73092b0b301b.yaml │ │ ├── ceph-osd-c897b82dd8d0104b.yaml │ │ ├── ceph-osd-e9bd9ab0cb036080.yaml │ │ ├── ceph-osd.yaml │ │ ├── ceph-provisioners-091a682dc01c219f.yaml │ │ ├── ceph-provisioners-c4334743e1cadc04.yaml │ │ ├── ceph-provisioners.yaml │ │ ├── ceph-rgw-1dc7fd498ff7ed46.yaml │ │ ├── ceph-rgw-9d99622a011584b0.yaml │ │ ├── ceph-rgw.yaml │ │ ├── cert-rotation-06fbf166bc55e372.yaml │ │ ├── cert-rotation.yaml │ │ ├── change-default-ovs-image-c1e24787f1b03170.yaml │ │ ├── change-memcache-backend-2d85a3c75b32db39.yaml │ │ ├── changed-ovs-dpdk-root-key-f8aaf3ad65189c8a.yaml │ │ ├── cinder-1db248fbc00e56ff.yaml │ │ ├── cinder-32aac095ffc09912.yaml │ │ ├── cinder-48232b427a294d57.yaml │ │ ├── cinder-4e17dd8ee84ca1a2.yaml │ │ ├── cinder-8f8fd56d2c9a5d75.yaml │ │ ├── cinder-92ee9aa061442690.yaml │ │ ├── cinder-a25114bef0ed2f56.yaml │ │ ├── cinder-a530fe90112c74d1.yaml │ │ ├── cinder-aca94f2247bcddcd.yaml │ │ ├── cinder-b605e2bc57b6d49f.yaml │ │ ├── cinder-ddd3bb79dff72ba6.yaml │ │ ├── cinder-ded5ec20ef58ac93.yaml │ │ ├── cinder-f177532ecd78dcec.yaml │ │ ├── cinder.yaml │ │ ├── cloudkitty-a95de06fbfeac965.yaml │ │ ├── cloudkitty-d61bea096f10b731.yaml │ │ ├── cloudkitty.yaml │ │ ├── common-695408be564c5d44.yaml │ │ ├── common-76e452ae14eb3707.yaml │ │ ├── common-8730c7058550f934.yaml │ │ ├── common-d6d7b93fcc7296e9.yaml │ │ ├── common-eb7338a63d83ad95.yaml │ │ ├── common-f19dec4799b18756.yaml │ │ ├── cyborg.yaml │ │ ├── designate-9ed4257ab657b224.yaml │ │ ├── designate-bc18055009645160.yaml │ │ ├── designate.yaml │ │ ├── elastic-apm-server.yaml │ │ ├── elastic-filebeat.yaml │ │ ├── elastic-metricbeat.yaml │ │ ├── elastic-packetbeat.yaml │ │ ├── elasticseach-625bc83028513f08.yaml │ │ ├── elasticsearch-127e34013b70451d.yaml │ │ ├── elasticsearch-1fb9cb9d0b6169a7.yaml │ │ ├── elasticsearch-4a005ef3cec5f170.yaml │ │ ├── elasticsearch-653d4b77cf26c277.yaml │ │ ├── elasticsearch-ba314935c85c3b25.yaml │ │ ├── elasticsearch-baf978b047efc111.yaml │ │ ├── elasticsearch.yaml │ │ ├── etcd.yaml │ │ ├── fluentbit.yaml │ │ ├── fluentd.yaml │ │ ├── freezer-3272cc6ed891f5a3.yaml │ │ ├── glance-1245a71c1694b79c.yaml │ │ ├── glance-79dad0da1e27df42.yaml │ │ ├── glance-9043d8c0a8119256.yaml │ │ ├── glance-cb814fab2bccc95e.yaml │ │ ├── glance-cbd61a1ae1e902b5.yaml │ │ ├── glance-e528d9f2473763a1.yaml │ │ ├── glance.yaml │ │ ├── gnocchi-37ba93d527c7ba75.yaml │ │ ├── gnocchi-71bec40a3416cb8a.yaml │ │ ├── gnocchi.yaml │ │ ├── grafana-b3fac6a311d115a6.yaml │ │ ├── grafana-d1a2049e057fe878.yaml │ │ ├── grafana.yaml │ │ ├── heat-5e861ec1ee8e2784.yaml │ │ ├── heat-7222563449ea848e.yaml │ │ ├── heat-a584fab629e1c4fc.yaml │ │ ├── heat.yaml │ │ ├── helm-toolkit-04996581655d9952.yaml │ │ ├── helm-toolkit-1ac16e62f779d907.yaml │ │ ├── helm-toolkit-49593d58783c3a97.yaml │ │ ├── helm-toolkit-5fa68b35be3378b3.yaml │ │ ├── helm-toolkit-81cf091a301877ff.yaml │ │ ├── helm-toolkit-9618f6c4379c13bc.yaml │ │ ├── helm-toolkit-a2810391532bd64a.yaml │ │ ├── helm-toolkit-acb954baa2fe7b2f.yaml │ │ ├── helm-toolkit-e84e695df114929d.yaml │ │ ├── helm-toolkit-fa49be61648b2d72.yaml │ │ ├── helm-toolkit.yaml │ │ ├── horizon-172a4ff3264fc495.yaml │ │ ├── horizon.yaml │ │ ├── increase-default-logging-31db0e9d3e51b429.yaml │ │ ├── ingress.yaml │ │ ├── ironic-0035b6286b1c6333.yaml │ │ ├── ironic-022571f573f6c430.yaml │ │ ├── ironic-2b9283c8924f8c63.yaml │ │ ├── ironic-2fcd7c5ae98b55f4.yaml │ │ ├── ironic-4963b8bfe3c212d0.yaml │ │ ├── ironic-4a1d33f9e4147b79.yaml │ │ ├── ironic-82bd78c64b57d2ce.yaml │ │ ├── ironic-adbba9c6718cc0d6.yaml │ │ ├── ironic-c0de8abe9970dca0.yaml │ │ ├── ironic.yaml │ │ ├── keystone-0e6674e1c443cd81.yaml │ │ ├── keystone-12efe8927d1a0934.yaml │ │ ├── keystone-17cdfeb53f6eb5dd.yaml │ │ ├── keystone-1aaec51f0512e445.yaml │ │ ├── keystone-56908951efdcc19e.yaml │ │ ├── keystone-5dd1eca70f3382d8.yaml │ │ ├── keystone-9bca09a40cc3dc68.yaml │ │ ├── keystone-dab27a4eeaab96d1.yaml │ │ ├── keystone-e2d6c0f6c85415ab.yaml │ │ ├── keystone-fb00add9c87916a3.yaml │ │ ├── keystone-healthcheck-1f72d266f886e735.yaml │ │ ├── keystone.yaml │ │ ├── kibana-053401293f7f508d.yaml │ │ ├── kibana-add46185e9a8d6af.yaml │ │ ├── kibana-c0b39f760a7c5b80.yaml │ │ ├── kibana.yaml │ │ ├── kube-dns.yaml │ │ ├── kubernetes-keystone-webhook.yaml │ │ ├── kubernetes-node-problem-detector.yaml │ │ ├── ldap-4737a2ba0a8a499f.yaml │ │ ├── ldap.yaml │ │ ├── libvirt-5bf3185fc00a9938.yaml │ │ ├── libvirt-85375c3ae369bc39.yaml │ │ ├── libvirt-ac59444a6623ddb9.yaml │ │ ├── libvirt-b5dc605552feb278.yaml │ │ ├── libvirt-e8ba1d91a8ca4999.yaml │ │ ├── libvirt-f81d6fc0b0094209.yaml │ │ ├── libvirt.yaml │ │ ├── local-storage.yaml │ │ ├── local-volume-provisioner.yaml │ │ ├── magnum.yaml │ │ ├── manila-23590e37667d10a5.yaml │ │ ├── manila-3a767553950629bd.yaml │ │ ├── manila-7bf5ad7472dbf691.yaml │ │ ├── manila-a5beeacdb577dd23.yaml │ │ ├── manila-f7286f302a9372eb.yaml │ │ ├── manila-f8ada2e675fcc308.yaml │ │ ├── manila.yaml │ │ ├── mariadb-0cb94bb0ae8cf38a.yaml │ │ ├── mariadb-2d75f250c1fbcd73.yaml │ │ ├── mariadb-7d8282a6eeb4d249.yaml │ │ ├── mariadb-840fccbf8f0e9d39.yaml │ │ ├── mariadb-b923ac9345734125.yaml │ │ ├── mariadb-backup-58c8a77f9c03bae8.yaml │ │ ├── mariadb-backup-af891fea0cfa3db5.yaml │ │ ├── mariadb-backup-c27eb2dc0a56a7ed.yaml │ │ ├── mariadb-backup.yaml │ │ ├── mariadb-cluster-4672d16769afdb47.yaml │ │ ├── mariadb-cluster.yaml │ │ ├── mariadb-dcd35d40fcd4a749.yaml │ │ ├── mariadb.yaml │ │ ├── masakari-ea8acf2427bc9811.yaml │ │ ├── masakari.yaml │ │ ├── memcached-1ae10613b2e36813.yaml │ │ ├── memcached.yaml │ │ ├── mistral.yaml │ │ ├── nagios-36a6b2cb6e9fc720.yaml │ │ ├── nagios.yaml │ │ ├── namespace-config.yaml │ │ ├── neutron-00a56405067b123d.yaml │ │ ├── neutron-013c9be46456b92c.yaml │ │ ├── neutron-288ac8b37720832e.yaml │ │ ├── neutron-2af36e49a0a377c3.yaml │ │ ├── neutron-2bb975307f0d27f2.yaml │ │ ├── neutron-2d4db97bc8900286.yaml │ │ ├── neutron-315f825e54d3f34c.yaml │ │ ├── neutron-32815761690bedf5.yaml │ │ ├── neutron-3c11cf48f8c7c592.yaml │ │ ├── neutron-3c33aea435f7ab8a.yaml │ │ ├── neutron-42b77d74ce8fe287.yaml │ │ ├── neutron-4f9263300df02c9b.yaml │ │ ├── neutron-659f0c21af1feaa0.yaml │ │ ├── neutron-670d4cd96f100dea.yaml │ │ ├── neutron-96d95ffbdeaaf29a.yaml │ │ ├── neutron-9dbb4250fd893743.yaml │ │ ├── neutron-add-uwsgi-start-time-d73ba462e1157dd2.yaml │ │ ├── neutron-b2247f89a5f258aa.yaml │ │ ├── neutron-b225c11a5e1d522d.yaml │ │ ├── neutron-c0c7ca4e49cbf03c.yaml │ │ ├── neutron-c451a4129f97e891.yaml │ │ ├── neutron-d39cc4643edac73c.yaml │ │ ├── neutron-f0674e08d80fc203.yaml │ │ ├── neutron-fca28403d7a0be3a.yaml │ │ ├── neutron.yaml │ │ ├── nfs-provisioner.yaml │ │ ├── nova-1a7fb130b261f92d.yaml │ │ ├── nova-29572c7b62b6ae0b.yaml │ │ ├── nova-2c10ffbcf8d2f838.yaml │ │ ├── nova-2e97a6de46b4c9b9.yaml │ │ ├── nova-3493b35ba8c4479a.yaml │ │ ├── nova-366b14dea33d416d.yaml │ │ ├── nova-467e6c34e9fd1b05.yaml │ │ ├── nova-476f40003a31bc77.yaml │ │ ├── nova-495c648112a2b539.yaml │ │ ├── nova-4b998ef222e57fd1.yaml │ │ ├── nova-5bb93c130c2a280d.yaml │ │ ├── nova-5d7903f3b97aa088.yaml │ │ ├── nova-60c926ac61319ba1.yaml │ │ ├── nova-69cb1a01b6f5c561.yaml │ │ ├── nova-6b1d99fb5c67b2dd.yaml │ │ ├── nova-7f3dbce1333752b8.yaml │ │ ├── nova-9df2dfa1e3521305.yaml │ │ ├── nova-b0749b6144e2b871.yaml │ │ ├── nova-b2ce6bcc83029d1b.yaml │ │ ├── nova-c59fc7469b3a8500.yaml │ │ ├── nova-dd4188dbc489977c.yaml │ │ ├── nova-e42deac3199480e6.yaml │ │ ├── nova-e8350419e59bc440.yaml │ │ ├── nova-fc00bda9bb69988e.yaml │ │ ├── nova.yaml │ │ ├── octavia-171c56de7891c86d.yaml │ │ ├── octavia-3c13346818a743cc.yaml │ │ ├── octavia-63cb483419410e3c.yaml │ │ ├── octavia-73c0f7c8c13c00a1.yaml │ │ ├── octavia-74938cd9ffae016b.yaml │ │ ├── octavia-875ff6ae26e5586c.yaml │ │ ├── octavia-a9a696fde141cd8b.yaml │ │ ├── octavia-b40e89ec5e5b5568.yaml │ │ ├── octavia-c0e8011e138832db.yaml │ │ ├── octavia-c952d2266d5dbd62.yaml │ │ ├── octavia-c9f2b0ece7ba8406.yaml │ │ ├── octavia-d22c4az0a92b7d16.yaml │ │ ├── octavia-f6afc93cf3ccc8f7.yaml │ │ ├── octavia-health-manager-net-caps-49adc645e1d03456.yaml │ │ ├── octavia.yaml │ │ ├── openstack.yaml │ │ ├── openvswitch-0b37403ffc75bb63.yaml │ │ ├── openvswitch-3401ba2f0dc8e1f6.yaml │ │ ├── openvswitch-3df8c5ca6034009f.yaml │ │ ├── openvswitch-5c0d74ca4f420e56.yaml │ │ ├── openvswitch-63f74f08815529dd.yaml │ │ ├── openvswitch-c123b289b476575a.yaml │ │ ├── openvswitch-e761d6733b84bdc7.yaml │ │ ├── openvswitch-e888d02378d4d044.yaml │ │ ├── openvswitch.yaml │ │ ├── other-23a753cb53b10bb8.yaml │ │ ├── ovn-3b9e82e5d469bc98.yaml │ │ ├── ovn-3e576a7be97232fe.yaml │ │ ├── ovn-50ba6d3611decff9.yaml │ │ ├── ovn-53e7ddb42d51e7c9.yaml │ │ ├── ovn-6c1c8afff28cf7f7.yaml │ │ ├── ovn-73332b0bc5d647f2.yaml │ │ ├── ovn-8b5cc103886f3b25.yaml │ │ ├── ovn-a82eced671495a3d.yaml │ │ ├── ovn-b172c29d8c0602b1.yaml │ │ ├── ovn-d195851d81d68036.yaml │ │ ├── ovn-ffd84bb8c9e73b64.yaml │ │ ├── ovn.yaml │ │ ├── panko.yaml │ │ ├── placement-2b023904bc06028b.yaml │ │ ├── placement-3115f3ce4c0801af.yaml │ │ ├── placement-a180f4e88ed81d30.yaml │ │ ├── placement.yaml │ │ ├── podsecuritypolicy.yaml │ │ ├── postgresql-4ee4e72706f17d8a.yaml │ │ ├── postgresql-e1a02dbbe6601b0f.yaml │ │ ├── postgresql.yaml │ │ ├── powerdns.yaml │ │ ├── prometeus-alertmanager-293616e8a47a12e8.yaml │ │ ├── prometeus-e9a80f262470313c.yaml │ │ ├── prometheus-alertmanager.yaml │ │ ├── prometheus-blackbox-exporter.yaml │ │ ├── prometheus-kube-state-metrics-b1fc3bf8e9109ae4.yaml │ │ ├── prometheus-kube-state-metrics.yaml │ │ ├── prometheus-mysql-exporter.yaml │ │ ├── prometheus-node-exporter.yaml │ │ ├── prometheus-openstack-exporter-39b2a7f52552033d.yaml │ │ ├── prometheus-openstack-exporter-d95d286faa68ea98.yaml │ │ ├── prometheus-openstack-exporter.yaml │ │ ├── prometheus-process-exporter.yaml │ │ ├── prometheus.yaml │ │ ├── rabbitmq-04d68343d1f9dbec.yaml │ │ ├── rabbitmq.yaml │ │ ├── rally.yaml │ │ ├── redis.yaml │ │ ├── registry-daf63a0fbe9771cb.yaml │ │ ├── registry.yaml │ │ ├── remove-legacy-volume-apis-12d2d1abbb7fbe61.yaml │ │ ├── remove-share-v1-api-d7b0b85e395bf131.yaml │ │ ├── rename-ceph-rbd-pool-app-name.yaml │ │ ├── skyline-0cc4caaea4f05714.yaml │ │ ├── skyline-4763b3a9c14ace98.yaml │ │ ├── skyline-794e9be9cc48f98d.yaml │ │ ├── skyline-db-sync-image-b56ba0a4cad85c9c.yaml │ │ ├── skyline-de744253bec9dfa3.yaml │ │ ├── tacker.yaml │ │ ├── tempest.yaml │ │ ├── trove-a1b2c3d4e5f6g7h8.yaml │ │ ├── trove.yaml │ │ ├── watcher.yaml │ │ └── zaqar-e43f9b2ace992d92.yaml │ ├── requirements.txt │ └── source/ │ ├── conf.py │ ├── current.rst │ ├── index.rst │ └── locale/ │ └── en_GB/ │ └── LC_MESSAGES/ │ └── releasenotes.po ├── roles/ │ ├── build-helm-packages/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ ├── main.yaml │ │ │ └── setup-helm-serve.yaml │ │ └── templates/ │ │ └── helm-serve.service.j2 │ ├── chart-testing/ │ │ ├── README.rst │ │ ├── defaults/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ └── main.yaml │ ├── clean-host/ │ │ └── tasks/ │ │ └── main.yaml │ ├── deploy-apparmor/ │ │ └── tasks/ │ │ └── main.yaml │ ├── deploy-docker/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ ├── tasks/ │ │ │ ├── deploy-ansible-docker-support.yaml │ │ │ └── main.yaml │ │ └── templates/ │ │ ├── centos-docker.service.j2 │ │ ├── fedora-docker.service.j2 │ │ ├── http-proxy.conf.j2 │ │ └── ubuntu-docker.service.j2 │ ├── deploy-env/ │ │ ├── README.md │ │ ├── defaults/ │ │ │ └── main.yaml │ │ ├── files/ │ │ │ ├── calico_patch.yaml │ │ │ ├── cluster_resolv.conf │ │ │ ├── containerd_config.toml │ │ │ ├── daemon.json │ │ │ ├── etc_default_kubelet.j2 │ │ │ ├── hosts │ │ │ ├── hosts.toml │ │ │ ├── kubeadm_config.yaml.j2 │ │ │ ├── loop-setup.service │ │ │ ├── nginx_tcp_proxy.conf │ │ │ ├── resolv.conf │ │ │ └── ssh_config │ │ ├── handlers/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ ├── buildset_registry_alias.yaml │ │ ├── calico.yaml │ │ ├── cilium.yaml │ │ ├── client_cluster_ssh.yaml │ │ ├── client_cluster_tunnel.yaml │ │ ├── containerd.yaml │ │ ├── coredns_resolver.yaml │ │ ├── env_inventory.yaml │ │ ├── flannel.yaml │ │ ├── floating_network.yaml │ │ ├── gatewayapi_envoy.yaml │ │ ├── ingress_haproxy.yaml │ │ ├── ingress_nginx.yaml │ │ ├── k8s_client.yaml │ │ ├── k8s_common.yaml │ │ ├── k8s_control_plane.yaml │ │ ├── loopback_devices.yaml │ │ ├── loopback_devices_mount.yaml │ │ ├── main.yaml │ │ ├── metallb.yaml │ │ ├── overlay.yaml │ │ ├── prerequisites.yaml │ │ └── public_endpoints.yaml │ ├── deploy-jq/ │ │ └── tasks/ │ │ └── main.yaml │ ├── deploy-package/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ └── tasks/ │ │ ├── dist.yaml │ │ └── pip.yaml │ ├── deploy-python/ │ │ └── tasks/ │ │ └── main.yaml │ ├── deploy-python-pip/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ └── tasks/ │ │ └── main.yaml │ ├── deploy-selenium/ │ │ └── tasks/ │ │ └── main.yaml │ ├── describe-kubernetes-objects/ │ │ └── tasks/ │ │ └── main.yaml │ ├── disable-local-nameserver/ │ │ └── tasks/ │ │ └── main.yaml │ ├── enable-hugepages/ │ │ ├── defaults/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ └── main.yaml │ ├── ensure-chart-testing/ │ │ ├── README.rst │ │ ├── defaults/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ └── main.yaml │ ├── gather-host-logs/ │ │ └── tasks/ │ │ └── main.yaml │ ├── gather-pod-logs/ │ │ └── tasks/ │ │ └── main.yaml │ ├── gather-prom-metrics/ │ │ └── tasks/ │ │ └── main.yaml │ ├── gather-selenium-data/ │ │ └── tasks/ │ │ └── main.yaml │ ├── helm-release-status/ │ │ └── tasks/ │ │ └── main.yaml │ ├── mount-extra-volume/ │ │ ├── defaults/ │ │ │ └── main.yml │ │ └── tasks/ │ │ └── main.yaml │ ├── osh-bandit/ │ │ ├── defaults/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ └── main.yaml │ ├── osh-run-script/ │ │ ├── defaults/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ └── main.yaml │ ├── osh-run-script-set/ │ │ ├── defaults/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ └── main.yaml │ ├── override-images/ │ │ ├── defaults/ │ │ │ └── main.yaml │ │ └── tasks/ │ │ └── main.yaml │ ├── setup-firewall/ │ │ └── tasks/ │ │ └── main.yaml │ └── upgrade-host/ │ ├── defaults/ │ │ └── main.yml │ └── tasks/ │ └── main.yaml ├── skyline/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _skyline-apiserver-init.sh.tpl │ │ │ └── _skyline-apiserver.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-ks-user.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-registry.yaml │ │ ├── service-ingress.yaml │ │ └── service.yaml │ └── values.yaml ├── swift/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _account-start.sh.tpl │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _container-start.sh.tpl │ │ │ ├── _ks-endpoints.sh.tpl │ │ │ ├── _ks-service.sh.tpl │ │ │ ├── _ks-user.sh.tpl │ │ │ ├── _object-start.sh.tpl │ │ │ ├── _proxy-start.sh.tpl │ │ │ ├── _ring-builder.sh.tpl │ │ │ ├── _ring-copy.sh.tpl │ │ │ ├── _storage-init.sh.tpl │ │ │ ├── _storage-start.sh.tpl │ │ │ └── _swift-test.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── daemonset-storage.yaml │ │ ├── deployment-proxy.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-proxy.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-ring-builder.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-proxy.yaml │ │ ├── pdb-storage.yaml │ │ ├── pod-test.yaml │ │ ├── pvc.yaml │ │ ├── secret-keystone.yaml │ │ ├── service-ingress-proxy.yaml │ │ └── service-proxy.yaml │ └── values.yaml ├── tacker/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _tacker-test.sh.tpl │ │ │ ├── _tacker_conductor.sh.tpl │ │ │ └── _tacker_server.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-conductor.yaml │ │ ├── deployment-server.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── pod-test.yaml │ │ ├── pvc.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── service-api.yaml │ │ ├── service-conductor.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── tempest/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── _helpers.tpl │ │ ├── bin/ │ │ │ └── _run-tests.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── extra-manifests.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-run-tests.yaml │ │ ├── pvc-tempest.yaml │ │ ├── secret-keystone.yaml │ │ └── secret-registry.yaml │ └── values.yaml ├── tests/ │ ├── dns-test.yaml │ └── pvc-test.yaml ├── tools/ │ ├── changelog.py │ ├── chart_version.sh │ ├── debug_sleep.sh │ ├── deployment/ │ │ ├── baremetal/ │ │ │ ├── 005-setup-nodes.sh │ │ │ ├── 010-setup-client.sh │ │ │ ├── 110-compute-kit.sh │ │ │ ├── 800-create-baremetal-host-aggregate.sh │ │ │ ├── 810-register-baremetal-nodes.sh │ │ │ ├── 820-create-baremetal-flavor.sh │ │ │ ├── 900-use-it.sh │ │ │ ├── fake-baremetal-1.xml │ │ │ └── heat-basic-bm-deployment.yaml │ │ ├── ceph/ │ │ │ ├── ceph-adapter-rook.sh │ │ │ ├── ceph-ns-activate.sh │ │ │ ├── ceph-radosgw.sh │ │ │ ├── ceph-rook.sh │ │ │ ├── ceph.sh │ │ │ ├── ceph_legacy.sh │ │ │ ├── migrate-after.sh │ │ │ ├── migrate-before.sh │ │ │ ├── migrate-to-rook-ceph.sh │ │ │ └── migrate-values.sh │ │ ├── common/ │ │ │ ├── cert-manager.sh │ │ │ ├── clean-it.sh │ │ │ ├── deploy-docker-registry.sh │ │ │ ├── env-variables.sh │ │ │ ├── force-cronjob-run.sh │ │ │ ├── heat-basic-vm-deployment.yaml │ │ │ ├── heat-public-net-deployment.yaml │ │ │ ├── heat-subnet-pool-deployment.yaml │ │ │ ├── heat-vm-volume-attach.yaml │ │ │ ├── namespace-config.sh │ │ │ ├── prepare-bashrc.sh │ │ │ ├── prepare-charts.sh │ │ │ ├── prepare-helm-repos-local.sh │ │ │ ├── prepare-helm-repos-public.sh │ │ │ ├── prepare-k8s.sh │ │ │ ├── pull-images.sh │ │ │ ├── rally-reports.yaml │ │ │ ├── run-helm-tests.sh │ │ │ ├── setup-certificates.sh │ │ │ ├── setup-client.sh │ │ │ ├── sleep.sh │ │ │ ├── test-networkpolicy.sh │ │ │ └── use-it.sh │ │ ├── component/ │ │ │ ├── aodh/ │ │ │ │ └── aodh.sh │ │ │ ├── barbican/ │ │ │ │ └── barbican.sh │ │ │ ├── blazar/ │ │ │ │ ├── blazar.sh │ │ │ │ └── blazar_smoke_test.sh │ │ │ ├── ceilometer/ │ │ │ │ └── ceilometer.sh │ │ │ ├── cinder/ │ │ │ │ └── cinder.sh │ │ │ ├── cloudkitty/ │ │ │ │ └── cloudkitty.sh │ │ │ ├── common/ │ │ │ │ ├── ldap.sh │ │ │ │ ├── memcached.sh │ │ │ │ ├── openstack.sh │ │ │ │ └── rabbitmq.sh │ │ │ ├── compute-kit/ │ │ │ │ ├── compute-kit-sr-iov.sh │ │ │ │ ├── compute-kit.sh │ │ │ │ ├── libvirt.sh │ │ │ │ └── openvswitch.sh │ │ │ ├── freezer/ │ │ │ │ ├── freezer.sh │ │ │ │ └── freezer_smoke_test.sh │ │ │ ├── glance/ │ │ │ │ └── glance.sh │ │ │ ├── heat/ │ │ │ │ └── heat.sh │ │ │ ├── horizon/ │ │ │ │ └── horizon.sh │ │ │ ├── keystone/ │ │ │ │ └── keystone.sh │ │ │ ├── magnum/ │ │ │ │ └── magnum.sh │ │ │ ├── manila/ │ │ │ │ └── manila.sh │ │ │ ├── mistral/ │ │ │ │ └── mistral.sh │ │ │ ├── nfs-provisioner/ │ │ │ │ └── nfs-provisioner.sh │ │ │ ├── octavia/ │ │ │ │ ├── create_dual_intermediate_CA.sh │ │ │ │ ├── heat_octavia_env.yaml │ │ │ │ ├── octavia.sh │ │ │ │ ├── octavia_certs.sh │ │ │ │ ├── octavia_resources.sh │ │ │ │ ├── octavia_test.sh │ │ │ │ └── openssl.cnf │ │ │ ├── ovn/ │ │ │ │ └── ovn.sh │ │ │ ├── redis/ │ │ │ │ └── redis.sh │ │ │ ├── skyline/ │ │ │ │ └── skyline.sh │ │ │ ├── swift/ │ │ │ │ └── swift.sh │ │ │ ├── tacker/ │ │ │ │ └── tacker.sh │ │ │ ├── trove/ │ │ │ │ └── trove.sh │ │ │ ├── watcher/ │ │ │ │ └── watcher.sh │ │ │ └── zaqar/ │ │ │ ├── zaqar.sh │ │ │ └── zaqar_smoke_test.sh │ │ ├── db/ │ │ │ ├── mariadb-backup.sh │ │ │ ├── mariadb-operator-cluster.sh │ │ │ ├── mariadb.sh │ │ │ └── postgresql.sh │ │ ├── logging/ │ │ │ ├── elasticsearch.sh │ │ │ ├── fluentbit.sh │ │ │ ├── fluentd.sh │ │ │ └── kibana.sh │ │ ├── monitoring/ │ │ │ ├── alertmanager.sh │ │ │ ├── blackbox-exporter.sh │ │ │ ├── grafana.sh │ │ │ ├── kube-state-metrics.sh │ │ │ ├── mysql-exporter.sh │ │ │ ├── nagios.sh │ │ │ ├── node-exporter.sh │ │ │ ├── node-problem-detector.sh │ │ │ ├── openstack-exporter.sh │ │ │ ├── process-exporter.sh │ │ │ └── prometheus.sh │ │ └── openstack/ │ │ └── keystone.sh │ └── gate/ │ └── selenium/ │ ├── grafana-selenium.sh │ ├── grafanaSelenium.py │ ├── kibana-selenium.sh │ ├── kibanaSelenium.py │ ├── nagios-selenium.sh │ ├── nagiosSelenium.py │ ├── prometheus-selenium.sh │ ├── prometheusSelenium.py │ ├── seleniumtester.py │ ├── skyline-selenium.sh │ └── skylineSelenium.py ├── tox.ini ├── trove/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _db-purge.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _trove-api.sh.tpl │ │ │ ├── _trove-conductor.sh.tpl │ │ │ └── _trove-taskmanager.sh.tpl │ │ ├── certificates.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── cron-job-trove-db-purge.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-conductor.yaml │ │ ├── deployment-taskmanager.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml ├── values_overrides/ │ ├── aodh/ │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ └── mariadb-operator.yaml │ ├── barbican/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── blazar/ │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── mariadb-operator.yaml │ ├── ceilometer/ │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ └── annotations.yaml │ ├── ceph-client/ │ │ └── apparmor.yaml │ ├── ceph-mon/ │ │ └── apparmor.yaml │ ├── ceph-osd/ │ │ └── apparmor.yaml │ ├── ceph-provisioners/ │ │ └── apparmor.yaml │ ├── ceph-rgw/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── netpol.yaml │ │ └── tls.yaml │ ├── cinder/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── backend_pure.yaml │ │ ├── external-ceph-backend.yaml │ │ ├── external-ceph-configmap.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── nfs-cinder-backup.yaml │ │ ├── qos.yaml │ │ ├── rabbitmq4.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── cloudkitty/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── mariadb-operator.yaml │ ├── cyborg/ │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ ├── mariadb-operator.yaml │ │ └── rabbitmq4.yaml │ ├── designate/ │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ └── mariadb-operator.yaml │ ├── elastic-apm-server/ │ │ └── apparmor.yaml │ ├── elastic-filebeat/ │ │ └── apparmor.yaml │ ├── elasticsearch/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── local-storage.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── remote-cluster.yaml │ │ └── tls.yaml │ ├── fluentd/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── tls.yaml │ ├── freezer/ │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── mariadb-operator.yaml │ ├── glance/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── bootstrap-ubuntu-image.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── rabbitmq4.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── gnocchi/ │ │ ├── gateway.yaml │ │ └── mariadb-operator.yaml │ ├── grafana/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── calico.yaml │ │ ├── ceph.yaml │ │ ├── containers.yaml │ │ ├── coredns.yaml │ │ ├── elasticsearch.yaml │ │ ├── gateway.yaml │ │ ├── home_dashboard.yaml │ │ ├── kubernetes.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── nginx.yaml │ │ ├── nodes.yaml │ │ ├── openstack.yaml │ │ ├── persistentvolume.yaml │ │ ├── prometheus.yaml │ │ ├── sqlite3.yaml │ │ └── tls.yaml │ ├── heat/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── rabbitmq4.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── horizon/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── logo.yaml │ │ ├── netpol.yaml │ │ └── tls.yaml │ ├── ironic/ │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ ├── mariadb-operator.yaml │ │ └── standalone.yaml │ ├── keystone/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── internal-reverse-proxy.yaml │ │ ├── ldap.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── rabbitmq4.yaml │ │ ├── tls-custom.yaml │ │ └── tls.yaml │ ├── kibana/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── tls.yaml │ ├── kubernetes-keystone-webhook/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ └── loci-2025.2-ubuntu_noble.yaml │ ├── kubernetes-node-problem-detector/ │ │ └── apparmor.yaml │ ├── libvirt/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── cinder-external-ceph-backend.yaml │ │ ├── inovex_exporter.yaml │ │ ├── netpol.yaml │ │ ├── node_overrides.yaml │ │ ├── ovn.yaml │ │ ├── ssl.yaml │ │ └── vexxhost_exporter.yaml │ ├── local-storage/ │ │ └── local-storage.yaml │ ├── magnum/ │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ └── mariadb-operator.yaml │ ├── manila/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── rabbitmq4.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── mariadb/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── backups.yaml │ │ ├── local-storage.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── netpol.yaml │ │ ├── remote_backups.yaml │ │ ├── staggered-backups.yaml │ │ ├── tls.yaml │ │ └── wait-for-cluster.yaml │ ├── mariadb-backup/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── backups.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── staggered-backups.yaml │ │ └── tls.yaml │ ├── mariadb-cluster/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── downscaled.yaml │ │ ├── local-storage.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── netpol.yaml │ │ ├── prometheus.yaml │ │ ├── tls.yaml │ │ └── upscaled.yaml │ ├── masakari/ │ │ ├── annotations.yaml │ │ └── mariadb-operator.yaml │ ├── memcached/ │ │ ├── apparmor.yaml │ │ ├── exporter.yaml │ │ └── netpol.yaml │ ├── mistral/ │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ └── mariadb-operator.yaml │ ├── nagios/ │ │ ├── apparmor.yaml │ │ ├── elasticsearch-objects.yaml │ │ ├── gateway.yaml │ │ ├── openstack-objects.yaml │ │ ├── postgresql-objects.yaml │ │ └── tls.yaml │ ├── neutron/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── bagpipe_bgp.yaml │ │ ├── dpdk-bond.yaml │ │ ├── dpdk.yaml │ │ ├── gate.yaml │ │ ├── gateway.yaml │ │ ├── l2gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── ovn.yaml │ │ ├── ovn_vpn.yaml │ │ ├── rabbitmq4.yaml │ │ ├── shared-sriov-ovs-dpdk-bond.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── nova/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── cntt.yaml │ │ ├── dpdk.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── opensuse_15.yaml │ │ ├── ovn.yaml │ │ ├── rabbitmq4.yaml │ │ ├── ssh.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── octavia/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── mariadb-operator.yaml │ ├── openvswitch/ │ │ ├── apparmor.yaml │ │ ├── dpdk-ubuntu_jammy.yaml │ │ ├── dpdk-ubuntu_noble.yaml │ │ ├── exporter.yaml │ │ ├── netpol.yaml │ │ ├── ovn.yaml │ │ ├── ubuntu_jammy.yaml │ │ ├── ubuntu_noble.yaml │ │ └── vswitchd-probes.yaml │ ├── ovn/ │ │ ├── ubuntu_jammy.yaml │ │ └── ubuntu_noble.yaml │ ├── placement/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── apparmor.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── mariadb-operator.yaml │ │ ├── netpol.yaml │ │ ├── tls-offloading.yaml │ │ └── tls.yaml │ ├── postgresql/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── backups.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── netpol.yaml │ │ ├── staggered-backups.yaml │ │ └── tls.yaml │ ├── powerdns/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ └── loci-2025.2-ubuntu_noble.yaml │ ├── prometheus/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── alertmanager.yaml │ │ ├── apparmor.yaml │ │ ├── ceph.yaml │ │ ├── elasticsearch.yaml │ │ ├── gateway.yaml │ │ ├── kubernetes.yaml │ │ ├── local-storage.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── nodes.yaml │ │ ├── openstack.yaml │ │ ├── postgresql.yaml │ │ └── tls.yaml │ ├── prometheus-alertmanager/ │ │ ├── apparmor.yaml │ │ └── gateway.yaml │ ├── prometheus-blackbox-exporter/ │ │ └── apparmor.yaml │ ├── prometheus-kube-state-metrics/ │ │ └── apparmor.yaml │ ├── prometheus-mysql-exporter/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── prometheus.yaml │ │ └── tls.yaml │ ├── prometheus-node-exporter/ │ │ └── apparmor.yaml │ ├── prometheus-openstack-exporter/ │ │ ├── apparmor.yaml │ │ ├── netpol.yaml │ │ └── tls.yaml │ ├── prometheus-process-exporter/ │ │ └── apparmor.yaml │ ├── rabbitmq/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── apparmor.yaml │ │ ├── builtin-metrics.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ ├── netpol.yaml │ │ ├── rabbitmq-exporter.yaml │ │ └── tls.yaml │ ├── rally/ │ │ ├── annotations.yaml │ │ ├── mariadb-operator.yaml │ │ └── tls-offloading.yaml │ ├── skyline/ │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── gateway.yaml │ │ └── loci-2025.2-ubuntu_noble.yaml │ ├── swift/ │ │ ├── 2025.2-ubuntu_noble.yaml │ │ └── gateway.yaml │ ├── tacker/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── mariadb-operator.yaml │ ├── tempest/ │ │ └── annotations.yaml │ ├── trove/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── annotations.yaml │ │ ├── gateway.yaml │ │ └── mariadb-operator.yaml │ ├── watcher/ │ │ ├── 2024.2-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_jammy.yaml │ │ ├── 2025.1-ubuntu_noble.yaml │ │ ├── 2025.2-ubuntu_noble.yaml │ │ ├── gateway.yaml │ │ ├── loci-2025.1-ubuntu_noble.yaml │ │ ├── loci-2025.2-ubuntu_noble.yaml │ │ └── mariadb-operator.yaml │ └── zaqar/ │ ├── 2025.1-ubuntu_jammy.yaml │ ├── 2025.1-ubuntu_noble.yaml │ ├── 2025.2-ubuntu_noble.yaml │ ├── gateway.yaml │ ├── loci-2025.1-ubuntu_noble.yaml │ └── loci-2025.2-ubuntu_noble.yaml ├── watcher/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _watcher-api.sh.tpl │ │ │ ├── _watcher-applier.sh.tpl │ │ │ └── _watcher-decision-engine.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── deployment-applier.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── job-rabbit-init.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-rally-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-rabbitmq.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ ├── service-ingress-api.yaml │ │ └── statefulset-decision-engine.yaml │ └── values.yaml ├── yamllint-templates.conf ├── yamllint.conf ├── zaqar/ │ ├── Chart.yaml │ ├── templates/ │ │ ├── bin/ │ │ │ ├── _bootstrap.sh.tpl │ │ │ ├── _db-sync.sh.tpl │ │ │ ├── _zaqar-test.sh.tpl │ │ │ └── _zaqar_api.sh.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── deployment-api.yaml │ │ ├── extra-manifests.yaml │ │ ├── ingress-api.yaml │ │ ├── job-bootstrap.yaml │ │ ├── job-db-drop.yaml │ │ ├── job-db-init.yaml │ │ ├── job-db-sync.yaml │ │ ├── job-image-repo-sync.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-user.yaml │ │ ├── network_policy.yaml │ │ ├── pdb-api.yaml │ │ ├── pod-rally-test.yaml │ │ ├── pod-test.yaml │ │ ├── secret-db.yaml │ │ ├── secret-ingress-tls.yaml │ │ ├── secret-keystone.yaml │ │ ├── secret-ks-etc.yaml │ │ ├── secret-registry.yaml │ │ ├── service-api.yaml │ │ └── service-ingress-api.yaml │ └── values.yaml └── zuul.d/ ├── 2024.2.yaml ├── 2025.1.yaml ├── 2025.2-ubuntu_noble.yaml ├── base.yaml ├── infra_jobs.yaml ├── nodesets.yaml └── project.yaml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.py[cod] # C extensions *.so # Packages *.egg* *.egg-info dist build eggs parts var sdist develop-eggs .installed.cfg lib lib64 # Installer logs pip-log.txt # Unit test / coverage reports cover/ .coverage* !.coveragerc .tox nosetests.xml .testrepository .venv # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # Complexity output/*.html output/*/index.html # Sphinx doc/build doc/source/chart/* !doc/source/chart/index.rst !doc/source/chart/openstack_charts.rst !doc/source/chart/infra_charts.rst # installed tools tools/helm-docs # pbr generates these AUTHORS ChangeLog # Editors *~ .*.swp .*sw? # Files created by releasenotes build releasenotes/build # Dev tools .idea/ .vscode/ .devcontainer/ **/.vagrant **/*.log # Helm internals *.lock */*.lock *.tgz **/*.tgz **/_partials.tpl **/_globals.tpl # Gate and Check Logs logs/ tools/gate/local-overrides/ playbooks/*.retry tmp/ # Helm-toolkit dev helm-toolkit/templates/test.yaml helm-toolkit/values.yaml ================================================ FILE: .gitreview ================================================ [gerrit] host=review.opendev.org port=29418 project=openstack/openstack-helm.git ================================================ FILE: .pre-commit-config.yaml ================================================ --- repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: trailing-whitespace - id: fix-byte-order-marker - id: mixed-line-ending args: ['--fix', 'lf'] - id: check-merge-conflict - repo: https://github.com/sphinx-contrib/sphinx-lint rev: v1.0.0 hooks: - id: sphinx-lint args: [--enable=default-role] files: ^doc/|releasenotes ================================================ FILE: CONTRIBUTING.rst ================================================ The source repository for this project can be found at: https://opendev.org/openstack/openstack-helm.git Pull requests submitted through GitHub are not monitored. To start contributing to OpenStack, follow the steps in the contribution guide to set up and use Gerrit: https://docs.openstack.org/contributors/code-and-documentation/quick-start.html Bugs should be filed on StoryBoard: https://storyboard.openstack.org/#!/project/openstack/openstack-helm ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: Makefile ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # It's necessary to set this because some environments don't link sh -> bash. SHELL := /bin/bash HELM := helm PYTHON := python3 TASK := build HELM_DOCS := tools/helm-docs UNAME_OS := $(shell uname -s) UNAME_ARCH := $(shell uname -m) # We generate CHANGELOG.md files by default which # requires reno>=4.1.0 installed. # To skip generating it use the following: # make all SKIP_CHANGELOG=1 SKIP_CHANGELOG ?= 0 PKG_ARGS = ifdef VERSION PKG_ARGS += --version $(VERSION) endif ifdef PACKAGE_DIR PKG_ARGS += --destination $(PACKAGE_DIR) endif BASE_VERSION ?= 2025.2.0 CHART_DIRS := $(subst /,,$(dir $(wildcard */Chart.yaml))) CHARTS := $(sort helm-toolkit $(CHART_DIRS)) .PHONY: $(CHARTS) all: $(CHARTS) charts: @echo $(CHART_DIRS) $(CHARTS): @if [ -d $@ ]; then \ echo; \ echo "===== Processing [$@] chart ====="; \ make $(TASK)-$@; \ fi HELM_DOCS_VERSION ?= 1.14.2 .PHONY: helm-docs ## Download helm-docs locally if necessary helm-docs: $(HELM_DOCS) $(HELM_DOCS): { \ curl -fsSL -o tools/helm-docs.tar.gz https://github.com/norwoodj/helm-docs/releases/download/v$(HELM_DOCS_VERSION)/helm-docs_$(HELM_DOCS_VERSION)_$(UNAME_OS)_$(UNAME_ARCH).tar.gz && \ tar -zxf tools/helm-docs.tar.gz -C tools helm-docs && \ rm -f tools/helm-docs.tar.gz && \ chmod +x tools/helm-docs; \ } init-%: if [ -f $*/Makefile ]; then make -C $*; fi if grep -qE "^dependencies:" $*/Chart.yaml; then $(HELM) dep up $*; fi lint-%: init-% if [ -d $* ]; then $(HELM) lint $*; fi # reno required for changelog generation %/CHANGELOG.md: if [ -d $* ]; then $(PYTHON) tools/changelog.py --charts $*; fi build-%: lint-% $(if $(filter-out 1,$(SKIP_CHANGELOG)),%/CHANGELOG.md) if [ -d $* ]; then \ $(HELM) package $* --version $$(tools/chart_version.sh $* $(BASE_VERSION)) $(PKG_ARGS); \ fi # This is used exclusively with helm3 building in the gate to publish package-%: init-% if [ -d $* ]; then $(HELM) package $* $(PKG_ARGS); fi clean: @echo "Clean all build artifacts" rm -f */templates/_partials.tpl */templates/_globals.tpl rm -f *tgz */charts/*tgz */requirements.lock rm -rf */charts */tmpcharts pull-all-images: @./tools/deployment/common/pull-images.sh pull-images: @./tools/deployment/common/pull-images.sh $(filter-out $@,$(MAKECMDGOALS)) dev-deploy: @./tools/gate/devel/start.sh $(filter-out $@,$(MAKECMDGOALS)) %: @: ================================================ FILE: README.rst ================================================ ============== OpenStack-Helm ============== Mission ------- The goal of OpenStack-Helm is to provide a collection of Helm charts that simply, resiliently, and flexibly deploy OpenStack and related services on Kubernetes. Versions supported ------------------ The table below shows the combinations of the Openstack/Platform/Kubernetes versions that are tested and proved to work. .. list-table:: :widths: 30 30 30 30 :header-rows: 1 * - Openstack version - Host OS - Image OS - Kubernetes version * - 2024.1 (Caracal) - Ubuntu Jammy - Ubuntu Jammy - >=1.29,<=1.31 * - 2024.2 (Dalmatian) - Ubuntu Jammy - Ubuntu Jammy - >=1.29,<=1.31 * - 2025.1 (Epoxy) - Ubuntu Jammy - Ubuntu Jammy - >=1.29,<=1.31 * - 2025.1 (Epoxy) - Ubuntu Noble - Ubuntu Noble - >=1.29,<=1.31 Communication ------------- * Join us on `IRC `_: ``#openstack-helm`` on oftc * Join us on `Slack `_ (this is preferable way of communication): ``#openstack-helm`` * Join us on `Openstack-discuss `_ mailing list (use subject prefix ``[openstack-helm]``) The list of Openstack-Helm core team members is available here `openstack-helm-core `_. Storyboard ---------- You found an issue and want to make sure we are aware of it? You can do so on our `Storyboard `_. Bugs should be filed as stories in Storyboard, not GitHub. Please be as much specific as possible while describing an issue. Usually having more context in the bug description means less efforts for a developer to reproduce the bug and understand how to fix it. Also before filing a bug to the Openstack-Helm `Storyboard `_ please try to identify if the issue is indeed related to the deployment process and not to the deployable software. Other links ----------- Our documentation is available `here `_. This project is under active development. We encourage anyone interested in OpenStack-Helm to review the `code changes `_ Our repositories: * OpenStack charts `openstack-helm `_ * OpenStack-Helm plugin `openstack-helm-plugin `_ * Build non-OpenStack images `openstack-helm-images `_ * Build Openstack images `loci `_ We welcome contributions in any form: code review, code changes, usage feedback, updating documentation. Release notes ------------- We use `reno `_ for managing release notes. If you update a chart, please add a release note using the following command: .. code-block:: bash reno new This will create a new release note file ``releasenotes/notes/-.yaml``. Fill in the necessary information and commit the release note file. If you update multiple charts in a single commit use the following command: .. code-block:: bash reno new common This will create a new release note file ``releasenotes/notes/common-.yaml``. In this case you can add multiple chart specific sections in this release note file. When building tarballs, we will use the ``reno`` features to combine release notes from all files and generate ``/CHANGELOG.md`` files. ================================================ FILE: aodh/Chart.yaml ================================================ # Copyright 2019 Wind River Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: Openstack-Helm Aodh name: aodh version: 2025.2.0 home: https://docs.openstack.org/aodh/latest/ sources: - https://opendev.org/openstack/aodh - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: aodh/templates/bin/_aodh-alarms-cleaner.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec aodh-expirer \ --config-file=/etc/aodh/aodh.conf \ --config-dir=/etc/aodh/aodh.conf.d ================================================ FILE: aodh/templates/bin/_aodh-api.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { cp -a $(type -p aodh-api) /var/www/cgi-bin/aodh/ if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars # The directory below has to be created due to the fact that # libapache2-mod-wsgi-py3 doesn't create it in contrary by libapache2-mod-wsgi if [ ! -d ${APACHE_RUN_DIR} ]; then mkdir -p ${APACHE_RUN_DIR} fi fi # Get rid of stale pid file if present. rm -f /var/run/apache2/*.pid # Start Apache2 exec apache2 -DFOREGROUND } function stop () { apachectl -k graceful-stop } $COMMAND ================================================ FILE: aodh/templates/bin/_aodh-evaluator.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec aodh-evaluator \ --config-file=/etc/aodh/aodh.conf \ --config-dir=/etc/aodh/aodh.conf.d ================================================ FILE: aodh/templates/bin/_aodh-listener.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec aodh-listener \ --config-file=/etc/aodh/aodh.conf \ --config-dir=/etc/aodh/aodh.conf.d ================================================ FILE: aodh/templates/bin/_aodh-notifier.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec aodh-notifier \ --config-file=/etc/aodh/aodh.conf \ --config-dir=/etc/aodh/aodh.conf.d ================================================ FILE: aodh/templates/bin/_aodh-test.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp echo "Test: create an alarm" aodh alarm create \ --name test_cpu_aggregation \ --type gnocchi_aggregation_by_resources_threshold \ --metric cpu --threshold 214106115 \ --comparison-operator lt \ --aggregation-method mean \ --granularity 300 \ --evaluation-periods 1 \ --alarm-action 'http://localhost:8776/alarm' \ --resource-type instance \ --query '{"=": {"flavor_name": "small"}}' sleep 5 echo "Test: list alarms" aodh alarm list sleep 5 echo "Test: show an alarm" ALARM_UUID=$(aodh alarm list -c alarm_id -f value | head -1) aodh alarm show ${ALARM_UUID} sleep 5 echo "Test: update an alarm" aodh alarm update ${ALARM_UUID} --comparison-operator gt sleep 5 echo "Test: delete an alarm" aodh alarm delete ${ALARM_UUID} exit 0 ================================================ FILE: aodh/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: aodh/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec aodh-dbsync ================================================ FILE: aodh/templates/configmap-bin.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: aodh-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} aodh-test.sh: | {{ tuple "bin/_aodh-test.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} aodh-api.sh: | {{ tuple "bin/_aodh-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} aodh-evaluator.sh: | {{ tuple "bin/_aodh-evaluator.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} aodh-listener.sh: | {{ tuple "bin/_aodh-listener.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} aodh-notifier.sh: | {{ tuple "bin/_aodh-notifier.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} aodh-alarms-cleaner.sh: | {{ tuple "bin/_aodh-alarms-cleaner.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: aodh/templates/configmap-etc.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.aodh.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.aodh.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.aodh.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.aodh.keystone_authtoken "region_name" .Values.endpoints.identity.auth.aodh.region_name -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.aodh.keystone_authtoken "project_name" .Values.endpoints.identity.auth.aodh.project_name -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.aodh.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.aodh.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.aodh.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.aodh.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.username -}} {{- $_ := set .Values.conf.aodh.keystone_authtoken "username" .Values.endpoints.identity.auth.aodh.username -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.password -}} {{- $_ := set .Values.conf.aodh.keystone_authtoken "password" .Values.endpoints.identity.auth.aodh.password -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.aodh.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.aodh.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.aodh.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.aodh.database.connection)) (empty .Values.conf.aodh.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "aodh" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set .Values.conf.aodh.database "connection" -}} {{- end -}} {{- if empty .Values.conf.aodh.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "aodh" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.aodh.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.aodh.service_credentials.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.aodh.service_credentials "auth_url" -}} {{- end -}} {{- if empty .Values.conf.aodh.service_credentials.region_name -}} {{- $_ := set .Values.conf.aodh.service_credentials "region_name" .Values.endpoints.identity.auth.aodh.region_name -}} {{- end -}} {{- if empty .Values.conf.aodh.service_credentials.project_name -}} {{- $_ := set .Values.conf.aodh.service_credentials "project_name" .Values.endpoints.identity.auth.aodh.project_name -}} {{- end -}} {{- if empty .Values.conf.aodh.service_credentials.project_domain_name -}} {{- $_ := set .Values.conf.aodh.service_credentials "project_domain_name" .Values.endpoints.identity.auth.aodh.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.aodh.service_credentials.user_domain_name -}} {{- $_ := set .Values.conf.aodh.service_credentials "user_domain_name" .Values.endpoints.identity.auth.aodh.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.aodh.service_credentials.username -}} {{- $_ := set .Values.conf.aodh.service_credentials "username" .Values.endpoints.identity.auth.aodh.username -}} {{- end -}} {{- if empty .Values.conf.aodh.service_credentials.password -}} {{- $_ := set .Values.conf.aodh.service_credentials "password" .Values.endpoints.identity.auth.aodh.password -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: aodh-etc type: Opaque data: aodh.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.aodh | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} {{ include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_aodh "key" "wsgi-aodh.conf" "format" "Secret" ) | indent 2 }} {{- end }} ================================================ FILE: aodh/templates/cron-job-alarms-cleaner.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_alarms_cleaner }} {{- $envAll := . }} {{- $mounts_aodh_alarms_cleaner := .Values.pod.mounts.aodh_alarms_cleaner.aodh_alarms_cleaner }} {{- $mounts_aodh_alarms_cleaner_init := .Values.pod.mounts.aodh_alarms_cleaner.init_container }} {{- $serviceAccountName := "aodh-alarms-cleaner" }} {{ tuple $envAll "alarms_cleaner" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.aodh_alarms_cleaner }} --- apiVersion: batch/v1 kind: CronJob metadata: name: aodh-alarms-cleaner annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.alarms_cleaner.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.alarms_cleaner.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.alarms_cleaner.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "aodh" "alarms-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "aodh" "alarms-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.aodh.enabled }} {{ tuple $envAll "aodh" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} initContainers: {{ tuple $envAll "alarms_cleaner" $mounts_aodh_alarms_cleaner_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: aodh-alarms-cleaner {{ tuple $envAll "aodh_alarms_cleaner" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.alarms_cleaner | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} command: - /tmp/aodh-alarms-cleaner.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: aodh-bin mountPath: /tmp/aodh-alarms-cleaner.sh subPath: aodh-alarms-cleaner.sh readOnly: true - name: pod-etc-aodh mountPath: /etc/aodh - name: aodh-etc mountPath: /etc/aodh/aodh.conf subPath: aodh.conf readOnly: true - name: aodh-etc-snippets mountPath: /etc/aodh/aodh.conf.d/ readOnly: true {{- if .Values.conf.aodh.DEFAULT.log_config_append }} - name: aodh-etc mountPath: {{ .Values.conf.aodh.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.aodh.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_aodh_alarms_cleaner.volumeMounts }}{{ toYaml $mounts_aodh_alarms_cleaner.volumeMounts | indent 16 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-aodh emptyDir: {} - name: aodh-etc secret: secretName: aodh-etc defaultMode: 0444 - name: aodh-et-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} - name: aodh-bin configMap: name: aodh-bin defaultMode: 0555 {{ if $mounts_aodh_alarms_cleaner.volumes }}{{ toYaml $mounts_aodh_alarms_cleaner.volumes | indent 12 }}{{ end }} {{- end }} ================================================ FILE: aodh/templates/deployment-api.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_aodh_api := .Values.pod.mounts.aodh_api.aodh_api }} {{- $mounts_aodh_api_init := .Values.pod.mounts.aodh_api.init_container }} {{- $serviceAccountName := "aodh-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.aodh_api }} --- apiVersion: apps/v1 kind: Deployment metadata: name: aodh-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "aodh" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "aodh" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "aodh" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "aodh_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "aodh" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "aodh" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.aodh.enabled }} {{ tuple $envAll "aodh" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_aodh_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: aodh-api {{ tuple $envAll "aodh_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "aodh" "container" "aodh_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/aodh-api.sh - start lifecycle: preStop: exec: command: - /tmp/aodh-api.sh - stop ports: - name: a-api containerPort: {{ tuple "alarming" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "alarming" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.aodh.oslo_concurrency.lock_path }} - name: wsgi-aodh mountPath: /var/www/cgi-bin/aodh - name: pod-etc-aodh mountPath: /etc/aodh - name: aodh-etc mountPath: /etc/aodh/aodh.conf subPath: aodh.conf readOnly: true - name: aodh-etc-snippets mountPath: /etc/aodh/aodh.conf.d/ readOnly: true {{- if .Values.conf.aodh.DEFAULT.log_config_append }} - name: aodh-etc mountPath: {{ .Values.conf.aodh.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.aodh.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: aodh-etc mountPath: /etc/aodh/api_paste.ini subPath: api-paste.ini readOnly: true - name: aodh-etc mountPath: /etc/aodh/policy.yaml subPath: policy.yaml readOnly: true - name: aodh-etc mountPath: /etc/apache2/conf-enabled/wsgi-aodh.conf subPath: wsgi-aodh.conf readOnly: true - name: aodh-bin mountPath: /tmp/aodh-api.sh subPath: aodh-api.sh readOnly: true {{ if $mounts_aodh_api.volumeMounts }}{{ toYaml $mounts_aodh_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: wsgi-aodh emptyDir: {} - name: pod-etc-aodh emptyDir: {} - name: aodh-etc secret: secretName: aodh-etc defaultMode: 0444 - name: aodh-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: aodh-bin configMap: name: aodh-bin defaultMode: 0555 {{ if $mounts_aodh_api.volumes }}{{ toYaml $mounts_aodh_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: aodh/templates/deployment-evaluator.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_evaluator }} {{- $envAll := . }} {{- $mounts_aodh_evaluator := .Values.pod.mounts.aodh_evaluator.aodh_evaluator }} {{- $mounts_aodh_evaluator_init := .Values.pod.mounts.aodh_evaluator.init_container }} {{- $serviceAccountName := "aodh-evaluator" }} {{ tuple $envAll "evaluator" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.aodh_evaluator }} --- apiVersion: apps/v1 kind: Deployment metadata: name: aodh-evaluator annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "aodh" "evaluator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.evaluator }} selector: matchLabels: {{ tuple $envAll "aodh" "evaluator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "aodh" "evaluator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "aodh_evaluator" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "aodh" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "aodh" "evaluator" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.evaluator.node_selector_key }}: {{ .Values.labels.evaluator.node_selector_value }} {{ if $envAll.Values.pod.tolerations.aodh.enabled }} {{ tuple $envAll "aodh" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "evaluator" $mounts_aodh_evaluator_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: aodh-evaluator {{ tuple $envAll "aodh_evaluator" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.evaluator | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "aodh" "container" "aodh_evaluator" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/aodh-evaluator.sh - start lifecycle: preStop: exec: command: - /tmp/aodh-evaluator.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.aodh.oslo_concurrency.lock_path }} - name: pod-etc-aodh mountPath: /etc/aodh - name: aodh-etc mountPath: /etc/aodh/aodh.conf subPath: aodh.conf readOnly: true - name: aodh-etc-snippets mountPath: /etc/aodh/aodh.conf.d/ readOnly: true {{- if .Values.conf.aodh.DEFAULT.log_config_append }} - name: aodh-etc mountPath: {{ .Values.conf.aodh.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.aodh.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: aodh-etc mountPath: /etc/aodh/policy.yaml subPath: policy.yaml readOnly: true - name: aodh-bin mountPath: /tmp/aodh-evaluator.sh subPath: aodh-evaluator.sh readOnly: true {{ if $mounts_aodh_evaluator.volumeMounts }}{{ toYaml $mounts_aodh_evaluator.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-aodh emptyDir: {} - name: aodh-etc secret: secretName: aodh-etc defaultMode: 0444 - name: aodh-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: aodh-bin configMap: name: aodh-bin defaultMode: 0555 {{ if $mounts_aodh_evaluator.volumes }}{{ toYaml $mounts_aodh_evaluator.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: aodh/templates/deployment-listener.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_listener }} {{- $envAll := . }} {{- $mounts_aodh_listener := .Values.pod.mounts.aodh_listener.aodh_listener }} {{- $mounts_aodh_listener_init := .Values.pod.mounts.aodh_listener.init_container }} {{- $serviceAccountName := "aodh-listener" }} {{ tuple $envAll "listener" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.aodh_listener }} --- apiVersion: apps/v1 kind: Deployment metadata: name: aodh-listener annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "aodh" "listener" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.listener }} selector: matchLabels: {{ tuple $envAll "aodh" "listener" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "aodh" "listener" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "aodh_listener" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "aodh" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "aodh" "listener" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.listener.node_selector_key }}: {{ .Values.labels.listener.node_selector_value }} {{ if $envAll.Values.pod.tolerations.aodh.enabled }} {{ tuple $envAll "aodh" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "listener" $mounts_aodh_listener_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: aodh-listener {{ tuple $envAll "aodh_listener" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.listener | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "aodh" "container" "aodh_listener" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/aodh-listener.sh - start lifecycle: preStop: exec: command: - /tmp/aodh-listener.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.aodh.oslo_concurrency.lock_path }} - name: pod-etc-aodh mountPath: /etc/aodh - name: aodh-etc mountPath: /etc/aodh/aodh.conf subPath: aodh.conf readOnly: true - name: aodh-etc-snippets mountPath: /etc/aodh/aodh.conf.d/ readOnly: true {{- if .Values.conf.aodh.DEFAULT.log_config_append }} - name: aodh-etc mountPath: {{ .Values.conf.aodh.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.aodh.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: aodh-etc mountPath: /etc/aodh/policy.yaml subPath: policy.yaml readOnly: true - name: aodh-bin mountPath: /tmp/aodh-listener.sh subPath: aodh-listener.sh readOnly: true {{ if $mounts_aodh_listener.volumeMounts }}{{ toYaml $mounts_aodh_listener.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-aodh emptyDir: {} - name: aodh-etc secret: secretName: aodh-etc defaultMode: 0444 - name: aodh-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: aodh-bin configMap: name: aodh-bin defaultMode: 0555 {{ if $mounts_aodh_listener.volumes }}{{ toYaml $mounts_aodh_listener.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: aodh/templates/deployment-notifier.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_notifier }} {{- $envAll := . }} {{- $mounts_aodh_notifier := .Values.pod.mounts.aodh_notifier.aodh_notifier }} {{- $mounts_aodh_notifier_init := .Values.pod.mounts.aodh_notifier.init_container }} {{- $serviceAccountName := "aodh-notifier" }} {{ tuple $envAll "notifier" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.aodh_notifier }} --- apiVersion: apps/v1 kind: Deployment metadata: name: aodh-notifier annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "aodh" "notifier" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.notifier }} selector: matchLabels: {{ tuple $envAll "aodh" "notifier" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "aodh" "notifier" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "aodh_notifier" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "aodh" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "aodh" "notifier" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.notifier.node_selector_key }}: {{ .Values.labels.notifier.node_selector_value }} {{ if $envAll.Values.pod.tolerations.aodh.enabled }} {{ tuple $envAll "aodh" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "notifier" $mounts_aodh_notifier_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: aodh-notifier {{ tuple $envAll "aodh_notifier" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.notifier | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "aodh" "container" "aodh_notifier" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/aodh-notifier.sh - start lifecycle: preStop: exec: command: - /tmp/aodh-notifier.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.aodh.oslo_concurrency.lock_path }} - name: pod-etc-aodh mountPath: /etc/aodh - name: aodh-etc mountPath: /etc/aodh/aodh.conf subPath: aodh.conf readOnly: true - name: aodh-etc-snippets mountPath: /etc/aodh/aodh.conf.d/ readOnly: true {{- if .Values.conf.aodh.DEFAULT.log_config_append }} - name: aodh-etc mountPath: {{ .Values.conf.aodh.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.aodh.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: aodh-etc mountPath: /etc/aodh/policy.yaml subPath: policy.yaml readOnly: true - name: aodh-bin mountPath: /tmp/aodh-notifier.sh subPath: aodh-notifier.sh readOnly: true {{ if $mounts_aodh_notifier.volumeMounts }}{{ toYaml $mounts_aodh_notifier.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-aodh emptyDir: {} - name: aodh-etc secret: secretName: aodh-etc defaultMode: 0444 - name: aodh-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: aodh-bin configMap: name: aodh-bin defaultMode: 0555 {{ if $mounts_aodh_notifier.volumes }}{{ toYaml $mounts_aodh_notifier.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: aodh/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: aodh/templates/ingress-api.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "alarming" "backendPort" "a-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: aodh/templates/job-bootstrap.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "aodh" "keystoneUser" .Values.bootstrap.ks_user -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: aodh/templates/job-db-drop.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "aodh" -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: aodh/templates/job-db-init.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "aodh" -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: aodh/templates/job-db-sync.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "aodh" -}} {{- $dbSyncJob := dict "envAll" . "serviceName" "aodh" "podVolMounts" .Values.pod.mounts.aodh_db_sync.aodh_db_sync.volumeMounts "podVols" .Values.pod.mounts.aodh_db_sync.aodh_db_sync.volumes -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: aodh/templates/job-image-repo-sync.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "aodh" -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: aodh/templates/job-ks-endpoints.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "aodh" "serviceTypes" ( tuple "alarming" ) -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: aodh/templates/job-ks-service.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "aodh" "serviceTypes" ( tuple "alarming" ) -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: aodh/templates/job-ks-user.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "aodh" -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: aodh/templates/job-rabbit-init.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "aodh" -}} {{- if .Values.pod.tolerations.aodh.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: aodh/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $opts := dict "envAll" . "name" "application" "label" "aodh" -}} {{ $opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: aodh/templates/pdb-api.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: aodh-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "aodh" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: aodh/templates/pod-aodh-test.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_aodh_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.aodh_tests.aodh_tests }} {{- $mounts_tests_init := .Values.pod.mounts.aodh_tests.init_container }} {{- $serviceAccountName := print $envAll.Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.Release.Name "-test" }} labels: {{ tuple $envAll "aodh" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: restartPolicy: Never nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.aodh.enabled }} {{ tuple $envAll "aodh" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: {{ .Release.Name }}-test {{ tuple $envAll "aodh_api" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} command: - /tmp/aodh-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: aodh-etc mountPath: /etc/aodh/aodh.conf subPath: aodh.conf readOnly: true - name: aodh-bin mountPath: /tmp/aodh-test.sh subPath: aodh-test.sh readOnly: true {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: aodh-etc secret: secretName: aodh-etc defaultMode: 0444 - name: aodh-bin configMap: name: aodh-bin defaultMode: 0555 {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: aodh/templates/secret-db.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "aodh" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: DB_CONNECTION: {{ tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc -}} {{- end }} {{- end }} ================================================ FILE: aodh/templates/secret-ingress-tls.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "alarming" ) }} {{- end }} ================================================ FILE: aodh/templates/secret-keystone.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "aodh" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: aodh/templates/secret-rabbitmq.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "aodh" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: aodh/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: aodh/templates/service-api.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "alarming" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: a-api port: {{ tuple "alarming" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "aodh" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: aodh/templates/service-ingress-api.yaml ================================================ {{/* Copyright 2019 Wind River Systems, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "alarming" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: aodh/values.yaml ================================================ # Copyright 2019 Wind River Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for aodh. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled evaluator: node_selector_key: openstack-control-plane node_selector_value: enabled listener: node_selector_key: openstack-control-plane node_selector_value: enabled notifier: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management aodh_db_sync: quay.io/airshipit/aodh:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble aodh_api: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_evaluator: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_listener: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_notifier: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_alarms_cleaner: quay.io/airshipit/aodh:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync jobs: alarms_cleaner: # daily cron: "0 */24 * * *" history: success: 3 failed: 1 pod: security_context: aodh: pod: runAsUser: 42402 container: aodh_api: runAsUser: 0 aodh_evaluator: readOnlyRootFilesystem: true allowPrivilegeEscalation: false aodh_notifier: readOnlyRootFilesystem: true allowPrivilegeEscalation: false aodh_listener: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: aodh: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: aodh_api: init_container: null aodh_api: volumeMounts: volumes: aodh_evaluator: init_container: null aodh_evaluator: volumeMounts: volumes: aodh_listener: init_container: null aodh_listener: volumeMounts: volumes: aodh_notifier: init_container: null aodh_notifier: volumeMounts: volumes: aodh_alarms_cleaner: init_container: null aodh_alarms_cleaner: volumeMounts: volumes: aodh_bootstrap: init_container: null aodh_bootstrap: volumeMounts: volumes: aodh_tests: init_container: null aodh_tests: volumeMounts: volumes: aodh_db_sync: aodh_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/aodh/aodh.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: aodh_api: [] aodh_evaluator: [] aodh_listener: [] aodh_notifier: [] aodh_alarms_cleaner: [] aodh_db_sync: [] replicas: api: 1 evaluator: 1 listener: 1 notifier: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" evaluator: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" listener: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" notifier: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" alarms_cleaner: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 8042 dependencies: dynamic: common: local_image_registry: jobs: - aodh-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - aodh-db-sync - aodh-ks-user - aodh-ks-endpoints services: - endpoint: internal service: oslo_db - endpoint: internal service: identity evaluator: jobs: - aodh-db-sync - aodh-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: alarming listener: jobs: - aodh-db-sync - aodh-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: alarming notifier: jobs: - aodh-db-sync - aodh-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: alarming rabbit_init: services: - service: oslo_messaging endpoint: internal db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - aodh-db-init services: - endpoint: internal service: oslo_db db_drop: services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - aodh-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity image_repo_sync: services: - endpoint: internal service: local_image_registry tests: jobs: - aodh-db-sync services: - endpoint: internal service: identity - endpoint: internal service: oslo_db - endpoint: internal service: alarming conf: wsgi_aodh: | Listen 0.0.0.0:{{ tuple "alarming" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded WSGIDaemonProcess aodh processes=2 threads=1 user=aodh group=aodh display-name=%{GROUP} WSGIProcessGroup aodh WSGIScriptAlias / /var/www/cgi-bin/aodh/aodh-api WSGIApplicationGroup %{GLOBAL} ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded paste: composite:aodh+noauth: use: egg:Paste#urlmap /: aodhversions_pipeline /v2: aodhv2_noauth_pipeline /healthcheck: healthcheck composite:aodh+keystone: use: egg:Paste#urlmap /: aodhversions_pipeline /v2: aodhv2_keystone_pipeline /healthcheck: healthcheck app:healthcheck: use: egg:oslo.middleware#healthcheck oslo_config_project: aodh pipeline:aodhversions_pipeline: pipeline: cors http_proxy_to_wsgi aodhversions app:aodhversions: paste.app_factory: aodh.api.app:app_factory root: aodh.api.controllers.root.VersionsController pipeline:aodhv2_keystone_pipeline: pipeline: cors http_proxy_to_wsgi request_id authtoken aodhv2 pipeline:aodhv2_noauth_pipeline: pipeline: cors http_proxy_to_wsgi request_id aodhv2 app:aodhv2: paste.app_factory: aodh.api.app:app_factory root: aodh.api.controllers.v2.root.V2Controller filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory oslo_config_project: aodh filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: aodh filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory oslo_config_project: aodh policy: {} aodh: DEFAULT: debug: false log_config_append: /etc/aodh/logging.conf oslo_middleware: enable_proxy_headers_parsing: true oslo_policy: policy_file: /etc/aodh/policy.yaml oslo_concurrency: lock_path: /var/lock database: alarm_history_time_to_live: 86400 max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: auth_version: v3 auth_type: password memcache_security_strategy: ENCRYPT service_type: alarming service_credentials: auth_type: password interface: internal auth_version: v3 logging: loggers: keys: - root - aodh handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_aodh: level: INFO handlers: - stdout qualname: aodh logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter formatter_default: format: "%(message)s" secrets: identity: admin: aodh-keystone-admin aodh: aodh-keystone-user oslo_db: admin: aodh-db-admin aodh: aodh-db-user oslo_messaging: admin: aodh-rabbitmq-admin aodh: aodh-rabbitmq-user tls: alarming: api: public: aodh-tls-public oci_image_registry: aodh: aodh-oci-image-registry bootstrap: enabled: false ks_user: aodh script: | openstack token issue # typically overriden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false aodh: username: aodh password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default aodh: role: admin region_name: RegionOne username: aodh password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 alarming: name: aodh hosts: default: aodh-api public: aodh host_fqdn_override: default: null # NOTE: this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: 'http' port: api: default: 8042 public: 80 oslo_db: auth: admin: username: root password: password aodh: username: aodh password: password hosts: default: mariadb host_fqdn_override: default: null path: /aodh scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: # NOTE: this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 oslo_messaging: auth: admin: username: rabbitmq password: password aodh: username: aodh password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /aodh scheme: rabbit port: amqp: default: 5672 http: default: 15672 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 network_policy: aodh: ingress: - {} egress: - {} manifests: configmap_bin: true configmap_etc: true cron_job_alarms_cleaner: true deployment_api: true deployment_evaluator: true deployment_listener: true deployment_notifier: true ingress_api: true job_bootstrap: true job_db_drop: false job_db_init: true job_image_repo_sync: true job_rabbit_init: true job_db_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true network_policy: false pdb_api: true pod_aodh_test: true secret_db: true secret_ingress_tls: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_api: true service_ingress_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: barbican/.helmignore ================================================ values_overrides ================================================ FILE: barbican/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Barbican name: barbican version: 2025.2.0 home: https://docs.openstack.org/barbican/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Barbican/OpenStack_Project_Barbican_vertical.png sources: - https://opendev.org/openstack/barbican - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: barbican/templates/bin/_barbican-test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex openstack secret list # Come up with a random payload PAYLOAD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` echo $PAYLOAD SECRET=`openstack secret store --name mysecret --payload ${PAYLOAD} | awk ' /href/ {print $5}'` openstack secret list openstack secret get $SECRET openstack secret get --payload $SECRET openstack secret delete $SECRET openstack secret list ================================================ FILE: barbican/templates/bin/_barbican.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/barbican/barbican-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: barbican/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: barbican/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex barbican-db-manage upgrade {{- $kek := (index (index .Values.conf.barbican "simple_crypto_plugin" | default dict) "kek") | default "" }} {{- $old_kek := index .Values.conf.simple_crypto_kek_rewrap "old_kek" | default ""}} {{- if and (not (empty $old_kek)) (not (empty $kek)) }} set +x echo "Ensuring that project KEKs are wrapped with the target global KEK" /tmp/simple_crypto_kek_rewrap.py --old-keks="$(cat /tmp/old_keks)" {{- end }} ================================================ FILE: barbican/templates/bin/_simple_crypto_kek_rewrap.py.tpl ================================================ #!/usr/bin/env python # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import argparse import base64 import sys from cryptography import fernet from oslo_db.sqlalchemy import session from sqlalchemy import orm from sqlalchemy.orm import scoping from barbican.common import utils from barbican.model import models from barbican.plugin.crypto import simple_crypto # Use config values from simple_crypto CONF = simple_crypto.CONF class KekRewrap(object): def __init__(self, conf, old_keks): self.dry_run = False self.db_engine = session.create_engine(conf.database.connection or conf.sql_connection) self._session_creator = scoping.scoped_session( orm.sessionmaker( bind=self.db_engine ) ) self.crypto_plugin = simple_crypto.SimpleCryptoPlugin(conf) self.plugin_name = utils.generate_fullname_for(self.crypto_plugin) if hasattr(self.crypto_plugin, 'master_kek'): self.encryptor = fernet.Fernet(self.crypto_plugin.master_kek) else: self.encryptor = fernet.MultiFernet( [fernet.Fernet(x) for x in self.crypto_plugin.master_keys] ) self.decryptor = fernet.MultiFernet( [fernet.Fernet(x.encode('utf-8')) for x in old_keks] ) def rewrap_kek(self, project, kek): db_begin_fn = self.db_session.begin_nested if ( self.db_session.in_transaction()) else self.db_session.begin with db_begin_fn(): plugin_meta = kek.plugin_meta # try to unwrap with the target kek, and if successful, skip try: if self.encryptor.decrypt(plugin_meta.encode('utf-8')): print('Project KEK {} is already wrapped with target KEK, skipping'.format(kek.id)) return except fernet.InvalidToken: pass # decrypt with the old kek print('Unwrapping Project KEK {}'.format(kek.id)) try: decrypted_plugin_meta = self.decryptor.decrypt(plugin_meta.encode('utf-8')) except fernet.InvalidToken: print('Failed to unwrap Project KEK {}'.format(kek.id)) raise # encrypt with the new kek print('Rewrapping Project KEK {}'.format(kek.id)) try: new_plugin_meta = self.encryptor.encrypt(decrypted_plugin_meta).decode('utf-8') except fernet.InvalidToken: print('Failed to wrap Project KEK {}'.format(kek.id)) raise if self.dry_run: return # Update KEK metadata in DB print('Storing updated Project KEK {}'.format(kek.id)) kek.plugin_meta = new_plugin_meta def get_keks_for_project(self, project): keks = [] db_begin_fn = self.db_session.begin_nested if ( self.db_session.in_transaction()) else self.db_session.begin with db_begin_fn() as transaction: print('Retrieving KEKs for Project {}'.format(project.external_id)) query = transaction.session.query(models.KEKDatum) query = query.filter_by(project_id=project.id) query = query.filter_by(plugin_name=self.plugin_name) keks = query.all() return keks def get_projects(self): print('Retrieving all available projects') projects = [] db_begin_fn = self.db_session.begin_nested if ( self.db_session.in_transaction()) else self.db_session.begin with db_begin_fn() as transaction: projects = transaction.session.query(models.Project).all() return projects @property def db_session(self): return self._session_creator() def execute(self, dry_run=True): self.dry_run = dry_run if self.dry_run: print('-- Running in dry-run mode --') projects = self.get_projects() successes = [] failures = [] for project in projects: keks = self.get_keks_for_project(project) for kek in keks: try: self.rewrap_kek(project, kek) successes.append(kek.id) except Exception: failures.append(kek.id) if successes: print('Sucessfully processed the following KEKs:') print('\n'.join(successes)) if failures: print('Failed to rewrap the following KEKs:') print('\n'.join(failures)) sys.exit(1) def main(): script_desc = 'Utility to re-wrap Project KEKs after rotating the global KEK.' parser = argparse.ArgumentParser(description=script_desc) parser.add_argument( '--dry-run', action='store_true', help='Displays changes that will be made (Non-destructive)' ) parser.add_argument( '--old-keks', default="dGhpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=", help='Old key encryption keys previously used by Simple Crypto Plugin. ' 'A comma separated string of list contain keys ' '( with formate 32 bytes and base64-encoded ). ' 'First key in list is used for ecnrypting new data. ' 'Additional keys used for decrypting existing data.' ) args = parser.parse_args() rewrapper = KekRewrap(CONF, args.old_keks.split(",")) rewrapper.execute(args.dry_run) if __name__ == '__main__': main() ================================================ FILE: barbican/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "key_manager" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: barbican/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: barbican-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} barbican-test.sh: | {{ tuple "bin/_barbican-test.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} barbican.sh: | {{ tuple "bin/_barbican.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} simple_crypto_kek_rewrap.py: | {{ tuple "bin/_simple_crypto_kek_rewrap.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: barbican/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.barbican.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.barbican.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.barbican.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.barbican.keystone_authtoken "region_name" .Values.endpoints.identity.auth.barbican.region_name -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.barbican.keystone_authtoken "project_name" .Values.endpoints.identity.auth.barbican.project_name -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.barbican.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.barbican.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.barbican.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.barbican.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.username -}} {{- $_ := set .Values.conf.barbican.keystone_authtoken "username" .Values.endpoints.identity.auth.barbican.username -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.password -}} {{- $_ := set .Values.conf.barbican.keystone_authtoken "password" .Values.endpoints.identity.auth.barbican.password -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.barbican.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.barbican.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.barbican.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.barbican.database.connection)) (empty .Values.conf.barbican.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "barbican" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.barbican.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.barbican.database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.barbican.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "barbican" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.barbican.DEFAULT "transport_url" -}} {{- end -}} {{- $barbicanPath := index .Values "endpoints" "key_manager" "path" "default" }} {{- if empty .Values.conf.barbican.DEFAULT.host_href -}} {{- $_ := tuple "key_manager" "public" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | trimSuffix $barbicanPath | set .Values.conf.barbican.DEFAULT "host_href" -}} {{- end -}} {{- if empty (index .Values.conf.barbican_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "key_manager" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.barbican_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: barbican-etc type: Opaque data: barbican.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.barbican | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} barbican-api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} api_audit_map.conf: {{ include "helm-toolkit.utils.to_ini" .Values.conf.audit_map | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} barbican-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.barbican_api_uwsgi | b64enc }} old_keks: {{ index .Values.conf.simple_crypto_kek_rewrap "old_kek" | default "" | b64enc | quote }} {{- end }} ================================================ FILE: barbican/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "probeTemplate" }} {{- $health_path := tuple "key_manager" "healthcheck" "internal" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} httpGet: scheme: {{ tuple "key_manager" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: {{ $health_path }} port: {{ tuple "key_manager" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_barbican_api := .Values.pod.mounts.barbican_api.barbican_api }} {{- $mounts_barbican_api_init := .Values.pod.mounts.barbican_api.init_container }} {{- $etcSources := .Values.pod.etcSources.barbican_api }} {{- $serviceAccountName := "barbican-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: barbican-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "barbican" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "barbican" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "barbican" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "barbican_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "barbican-api" "containerNames" (list "init" "barbican-api") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "barbican" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "barbican_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "barbican_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "barbican" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.barbican.enabled }} {{ tuple $envAll "barbican" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "api" $mounts_barbican_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: barbican-api {{ tuple $envAll "barbican_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "barbican" "container" "barbican_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "barbican-api" "type" "readiness" "probeTemplate" (include "probeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "barbican-api" "type" "liveness" "probeTemplate" (include "probeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/barbican.sh - start env: {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/barbican/certs/ca.crt" {{- end }} lifecycle: preStop: exec: command: - /tmp/barbican.sh - stop ports: - name: b-api containerPort: {{ tuple "key_manager" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.barbican.oslo_concurrency.lock_path }} - name: etcbarbican mountPath: /etc/barbican - name: barbican-etc mountPath: /etc/barbican/barbican-api-uwsgi.ini subPath: barbican-api-uwsgi.ini readOnly: true - name: barbican-etc mountPath: /etc/barbican/barbican.conf subPath: barbican.conf readOnly: true - name: barbican-etc-snippets mountPath: /etc/barbican/barbican.conf.d/ readOnly: true {{- if .Values.conf.barbican.DEFAULT.log_config_append }} - name: barbican-etc mountPath: {{ .Values.conf.barbican.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.barbican.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: barbican-etc mountPath: /etc/barbican/api_audit_map.conf subPath: api_audit_map.conf readOnly: true - name: barbican-etc mountPath: /etc/barbican/barbican-api-paste.ini subPath: barbican-api-paste.ini readOnly: true - name: barbican-etc mountPath: /etc/barbican/policy.yaml subPath: policy.yaml readOnly: true - name: barbican-bin mountPath: /tmp/barbican.sh subPath: barbican.sh readOnly: true {{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.key_manager.api.internal "path" "/etc/barbican/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.tls.oslo_messaging "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_barbican_api.volumeMounts }}{{ toYaml $mounts_barbican_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: etcbarbican emptyDir: {} - name: barbican-etc secret: secretName: barbican-etc defaultMode: 0444 - name: barbican-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: barbican-bin configMap: name: barbican-bin defaultMode: 0555 {{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.key_manager.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.tls.oslo_messaging "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_barbican_api.volumes }}{{ toYaml $mounts_barbican_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: barbican/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: barbican/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "key_manager" "backendPort" "b-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: barbican/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.bootstrap" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "5" {{- end }} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "barbican" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.barbican.DEFAULT.log_config_append "jobAnnotations" (include "metadata.annotations.job.bootstrap" . | fromYaml) -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.key_manager.api.internal -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: barbican/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "barbican" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: barbican/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "barbican" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: barbican/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- $podVolMounts := .Values.pod.mounts.barbican_db_sync.barbican_db_sync.volumeMounts | default list }} {{- $podVolMounts = append $podVolMounts (dict "name" "db-sync-sh" "mountPath" "/tmp/simple_crypto_kek_rewrap.py" "subPath" "simple_crypto_kek_rewrap.py" "readOnly" true) }} {{- $podVolMounts = append $podVolMounts (dict "name" "db-sync-conf" "mountPath" "/tmp/old_keks" "subPath" "old_keks" "readOnly" true) }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "barbican" "podVolMounts" $podVolMounts "podVols" .Values.pod.mounts.barbican_db_sync.barbican_db_sync.volumes "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: barbican/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "barbican" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: barbican/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "barbican" "serviceTypes" ( tuple "key-manager" ) "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.key_manager.api.internal -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: barbican/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "barbican" "serviceTypes" ( tuple "key-manager" ) "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.key_manager.api.internal -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: barbican/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "barbican" "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.key_manager.api.internal -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: barbican/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "barbican" "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) -}} {{- if and .Values.tls.oslo_messaging .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- $_ := set $rmqUserJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.barbican.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: barbican/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "barbican" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: barbican/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: barbican-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "barbican" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: barbican/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $dependencies := .Values.dependencies.static.tests }} {{- $mounts_barbican_tests := .Values.pod.mounts.barbican_tests.barbican_tests }} {{- $mounts_barbican_tests_init := .Values.pod.mounts.barbican_tests.init_container }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.Release.Name}}-test" labels: {{ tuple $envAll "barbican" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "barbican-test" "containerNames" (list "init" "barbican-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ tuple "barbican_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "barbican_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.barbican.enabled }} {{ tuple $envAll "barbican" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" $mounts_barbican_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: barbican-test {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "barbican_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} command: - /tmp/barbican-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: barbican-bin mountPath: /tmp/barbican-test.sh subPath: barbican-test.sh readOnly: true {{ if $mounts_barbican_tests.volumeMounts }}{{ toYaml $mounts_barbican_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: barbican-bin configMap: name: barbican-bin defaultMode: 0555 {{ if $mounts_barbican_tests.volumes }}{{ toYaml $mounts_barbican_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: barbican/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "barbican" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: barbican/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "key_manager" ) }} {{- end }} ================================================ FILE: barbican/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "barbican" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: barbican/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "barbican" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: barbican/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: barbican/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "key-manager" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: b-api port: {{ tuple "key-manager" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "barbican" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: barbican/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "key-manager" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: barbican/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for barbican. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy scripted_test: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble barbican_db_sync: quay.io/airshipit/barbican:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble barbican_api: quay.io/airshipit/barbican:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync pod: security_context: barbican: pod: runAsUser: 42424 container: barbican_api: allowPrivilegeEscalation: false readOnlyRootFilesystem: true test: pod: runAsUser: 42424 container: barbican_test: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: barbican: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: barbican_api: init_container: null barbican_api: volumeMounts: volumes: barbican_bootstrap: init_container: null barbican_bootstrap: volumeMounts: volumes: barbican_tests: init_container: null barbican_tests: volumeMounts: volumes: barbican_db_sync: barbican_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/barbican/barbican.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: barbican_api: [] barbican_db_sync: [] replicas: api: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 probes: api: barbican-api: readiness: enabled: true params: periodSeconds: 10 timeoutSeconds: 5 liveness: enabled: true params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30486 network_policy: barbican: ingress: - {} egress: - {} bootstrap: enabled: false ks_user: barbican script: | openstack token issue dependencies: dynamic: common: local_image_registry: jobs: - barbican-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - barbican-db-sync - barbican-ks-user - barbican-ks-endpoints - barbican-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - barbican-db-init services: - endpoint: internal service: oslo_db image_repo_sync: services: - endpoint: internal service: local_image_registry ks_endpoints: jobs: - barbican-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - endpoint: internal service: oslo_messaging conf: paste: composite:main: use: egg:Paste#urlmap /: barbican_version /v1: barbican-api-keystone /healthcheck: healthcheck pipeline:barbican_version: pipeline: cors http_proxy_to_wsgi versionapp pipeline:barbican_api: pipeline: cors http_proxy_to_wsgi unauthenticated-context apiapp pipeline:barbican-profile: pipeline: cors http_proxy_to_wsgi unauthenticated-context egg:Paste#cgitb egg:Paste#httpexceptions profile apiapp pipeline:barbican-api-keystone: pipeline: cors http_proxy_to_wsgi authtoken context apiapp pipeline:barbican-api-keystone-audit: pipeline: http_proxy_to_wsgi authtoken context audit apiapp app:apiapp: paste.app_factory: barbican.api.app:create_main_app app:versionapp: paste.app_factory: barbican.api.app:create_version_app app:healthcheck: paste.app_factory: oslo_middleware:Healthcheck.app_factory backends: disable_by_file disable_by_file_path: /etc/barbican/healthcheck_disable filter:simple: paste.filter_factory: barbican.api.middleware.simple:SimpleFilter.factory filter:unauthenticated-context: paste.filter_factory: barbican.api.middleware.context:UnauthenticatedContextMiddleware.factory filter:context: paste.filter_factory: barbican.api.middleware.context:ContextMiddleware.factory filter:audit: paste.filter_factory: keystonemiddleware.audit:filter_factory audit_map_file: /etc/barbican/api_audit_map.conf filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:profile: use: egg:repoze.profile log_filename: myapp.profile cachegrind_filename: cachegrind.out.myapp discard_first_request: true path: /__profile__ flush_at_shutdown: true unwind: false filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: barbican filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware:HTTPProxyToWSGI.factory policy: {} audit_map: DEFAULT: # default target endpoint type # should match the endpoint type defined in service catalog target_endpoint_type: key-manager custom_actions: # map urls ending with specific text to a unique action # Don't need custom mapping for other resource operations # Note: action should match action names defined in CADF taxonomy acl/get: read path_keywords: # path of api requests for CADF target typeURI # Just need to include top resource path to identify class of resources secrets: null containers: null orders: null cas: "None" quotas: null project-quotas: null service_endpoints: # map endpoint type defined in service catalog to CADF typeURI key-manager: service/security/keymanager barbican_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "barbiacan-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/barbican-wsgi-api processes: 1 stats: 0.0.0.0:1717 stats-http: true barbican: DEFAULT: transport_url: null log_config_append: /etc/barbican/logging.conf keystone_authtoken: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT memcache_secret_key: null service_type: key-manager database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" barbican_api: # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. bind_port: null oslo_policy: policy_file: /etc/barbican/policy.yaml oslo_concurrency: lock_path: /var/lock # When using the simple_crypto_plugin, a kek must be provided as: # .conf.barbican.simple_crypto_plugin.kek # If no kek is provided, barbican will use a well-known default. # If upgrading the chart with a new kek, the old kek must be provided in: # .conf.simple_crypto_plugin_rewrap.old_kek # Please refer to the .conf.simple_crypto_key_rewrap section below. # The barbican defaults are included here as a reference: # secretstore: # enabled_secretstore_plugins: # - store_crypto # crypto: # enabled_crypto_plugins: # - simple_crypto # simple_crypto_plugin: # # The kek should be a 32-byte value which is base64 encoded. # # First key is used for ecnrypting new data # kek: "dGhpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=" # # Additional keys used for decrypting existing data # kek: "xCDpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=" # KEK rotation for the simple_crypto plugin simple_crypto_kek_rewrap: # To allow for chart upgrades when modifying the Key Encryption Keys, the # db-sync job can rewrap the existing project keys with the new kek, leaving # each secret’s encrypted data unchanged. # This feature is enabled automatically, if a kek is specified at: # .conf.barbican.simple_crypto_plugin.kek # and the previous kek is also specified at: # .conf.simple_crypto_kek_rewrap.old_kek # The project keys are decrypted with 'old_kek' and re-encrypted with the # target kek (as defined in barbican.conf). # This resembles the lightweight rotation described here, which was never # implemented for the simple crypto plugin: # https://specs.openstack.org/openstack/barbican-specs/specs/liberty/add-crypto-mkek-rotation-support-lightweight.html # The KEK value "dGhpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=" matches the # plugin default, and is retained here for convenience, in case the chart was # previously installed without explicitly specifying a kek. # old_kek allows commna-separated string for keks # old_kek: # # First key is used for ecnrypting new data # # Additional keys used for decrypting existing data # - "dGhpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=,dDDpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=" old_kek: "dGhpcnR5X3R3b19ieXRlX2tleWJsYWhibGFoYmxhaGg=" logging: loggers: keys: - root - barbican handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_barbican: level: INFO handlers: - stdout qualname: barbican logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: barbican-keystone-admin barbican: barbican-keystone-user oslo_db: admin: barbican-db-admin barbican: barbican-db-user oslo_messaging: admin: barbican-rabbitmq-admin barbican: barbican-rabbitmq-user tls: key_manager: api: public: barbican-tls-public internal: barbican-tls-internal oci_image_registry: barbican: barbican-oci-image-registry endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false barbican: username: barbican password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default barbican: role: admin region_name: RegionOne username: barbican password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 key_manager: name: barbican hosts: default: barbican-api public: barbican host_fqdn_override: default: tls: secretName: barbican-tls-internal issuerRef: kind: ClusterIssuer name: ca-clusterissuer path: default: / healthcheck: /healthcheck scheme: default: http service: http port: api: default: 9311 public: 80 service: 9311 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct barbican: username: barbican password: password hosts: default: mariadb host_fqdn_override: default: null path: /barbican scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct barbican: username: barbican password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /barbican scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false configmap_bin: true configmap_etc: true deployment_api: true ingress_api: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_rabbit_init: true job_ks_endpoints: true job_ks_service: true job_ks_user: true pdb_api: true pod_test: true secret_db: true network_policy: false secret_ingress_tls: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_ingress_api: true service_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: bindep.txt ================================================ # This file facilitates OpenStack-CI package installation # before the execution of any tests. # Required to build language docs gettext ================================================ FILE: blazar/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack Resource Reservation Service name: blazar type: application version: 2025.2.0 home: https://docs.openstack.org/blazar/ icon: https://openmetal.io/wp-content/uploads/2024/10/OpenStack_Project_Blazar-300x300.jpg sources: - https://opendev.org/openstack/blazar keywords: - openstack - reservation - helm maintainers: - name: OpenStack Helm Team email: openstack-helm@lists.openstack.org dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: blazar/templates/bin/_blazar_api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec blazar-api \ --config-file /etc/blazar/blazar.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: blazar/templates/bin/_blazar_manager.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec blazar-manager \ --config-file /etc/blazar/blazar.conf ================================================ FILE: blazar/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex blazar-db-manage \ --config-file /etc/blazar/blazar.conf \ upgrade head ================================================ FILE: blazar/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: blazar-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} rally-test.sh: | {{ tuple .Values.conf.rally_tests | include "helm-toolkit.scripts.rally_test" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} blazar-api.sh: | {{ tuple "bin/_blazar_api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} blazar-manager.sh: | {{ tuple "bin/_blazar_manager.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- if .Values.manifests.job_rabbit_init }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} {{- end }} ... ================================================ FILE: blazar/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- define "blazar.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty .Values.conf.blazar.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.blazar.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.blazar.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.blazar.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.blazar.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.blazar.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.blazar.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.blazar.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.blazar.database.connection)) (empty .Values.conf.blazar.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "blazar" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set .Values.conf.blazar.database "connection" -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "blazar" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.blazar.DEFAULT "transport_url" -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} {{- if empty .Values.conf.blazar.oslo_messaging_notifications.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "blazar" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.blazar.oslo_messaging_notifications "transport_url" -}} {{- end -}} {{/* Openstack auth */}} {{- if empty .Values.conf.blazar.DEFAULT.os_auth_host -}} {{- $_ := tuple "identity" "internal" . | include "helm-toolkit.endpoints.endpoint_host_lookup" | set .Values.conf.blazar.DEFAULT "os_auth_host" -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_auth_port -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.blazar.DEFAULT "os_auth_port" -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_auth_protocol -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | set .Values.conf.blazar.DEFAULT "os_auth_protocol" -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_region_name -}} {{- $_ := set .Values.conf.blazar.DEFAULT "os_region_name" .Values.endpoints.identity.auth.admin.region_name -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_admin_project_name -}} {{- $_ := set .Values.conf.blazar.DEFAULT "os_admin_project_name" .Values.endpoints.identity.auth.admin.project_name -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_admin_project_domain_name -}} {{- $_ := set .Values.conf.blazar.DEFAULT "os_admin_project_domain_name" .Values.endpoints.identity.auth.admin.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_admin_user_domain_name -}} {{- $_ := set .Values.conf.blazar.DEFAULT "os_admin_user_domain_name" .Values.endpoints.identity.auth.admin.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_admin_username -}} {{- $_ := set .Values.conf.blazar.DEFAULT "os_admin_username" .Values.endpoints.identity.auth.admin.username -}} {{- end -}} {{- if empty .Values.conf.blazar.DEFAULT.os_admin_password -}} {{- $_ := set .Values.conf.blazar.DEFAULT "os_admin_password" .Values.endpoints.identity.auth.admin.password -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} blazar.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.blazar | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.api_paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "blazar-etc" . | include "blazar.configmap.etc" }} {{- end }} ... ================================================ FILE: blazar/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "blazarApiLivenessProbeTemplate" }} tcpSocket: port: {{ tuple "reservation" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "blazarApiReadinessProbeTemplate" }} tcpSocket: port: {{ tuple "reservation" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_blazar_api := .Values.pod.mounts.blazar_api.blazar_api }} {{- $mounts_blazar_api_init := .Values.pod.mounts.blazar_api.init_container }} {{- $serviceAccountName := "blazar-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: blazar-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "blazar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "blazar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "blazar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "blazar_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "blazar-api" "containerNames" (list "blazar-api" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "blazar_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "blazar_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "blazar" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "blazar" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.blazar.enabled }} {{ tuple $envAll "blazar" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_blazar_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: blazar-api {{ tuple $envAll "blazar_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "blazar" "container" "blazar_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/blazar/certs/ca.crt" {{- end }} command: - /tmp/blazar-api.sh - start lifecycle: preStop: exec: command: - /tmp/blazar-api.sh - stop ports: - name: b-api containerPort: {{ tuple "reservation" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "api" "container" "default" "type" "liveness" "probeTemplate" (include "blazarApiLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "default" "type" "readiness" "probeTemplate" (include "blazarApiReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.blazar.oslo_concurrency.lock_path }} - name: pod-etc-blazar mountPath: /etc/blazar - name: blazar-bin mountPath: /tmp/blazar-api.sh subPath: blazar-api.sh readOnly: true - name: blazar-etc mountPath: /etc/blazar/blazar.conf subPath: blazar.conf readOnly: true - name: blazar-etc-snippets mountPath: /etc/blazar/blazar.conf.d/ readOnly: true {{- if .Values.conf.blazar.DEFAULT.log_config_append }} - name: blazar-etc mountPath: {{ .Values.conf.blazar.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.blazar.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: blazar-etc mountPath: /etc/blazar/api-paste.ini subPath: api-paste.ini readOnly: true - name: blazar-etc mountPath: /etc/blazar/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.reservation.api.internal "path" "/etc/blazar/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_blazar_api.volumeMounts }}{{ toYaml $mounts_blazar_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-blazar emptyDir: {} - name: blazar-bin configMap: name: blazar-bin defaultMode: 0555 - name: blazar-etc secret: secretName: blazar-etc defaultMode: 0444 - name: blazar-etc-snippets projected: sources: - secret: name: blazar-ks-etc {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.reservation.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_blazar_api.volumes }}{{ toYaml $mounts_blazar_api.volumes | indent 8 }}{{ end }} {{- end }} ... ================================================ FILE: blazar/templates/deployment-manager.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_manager }} {{- $envAll := . }} {{- $mounts := .Values.pod.mounts.blazar_manager.blazar_manager }} {{- $mounts_init := .Values.pod.mounts.blazar_manager.init_container }} {{- $serviceAccountName := "blazar-manager" }} {{ tuple $envAll "manager" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: blazar-manager annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "blazar" "manager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.manager }} selector: matchLabels: {{ tuple $envAll "blazar" "manager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "blazar" "manager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "blazar-manager" "containerNames" (list "blazar-manager" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "blazar" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "blazar" "manager" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.manager.node_selector_key }}: {{ .Values.labels.manager.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.manager.timeout | default "30" }} initContainers: {{ tuple $envAll "manager" $mounts_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: blazar-manager {{ tuple $envAll "blazar_manager" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.manager | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "blazar" "container" "blazar_manager" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/blazar-manager.sh env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.blazar }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.blazar.oslo_concurrency.lock_path }} - name: pod-etc-blazar mountPath: /etc/blazar - name: blazar-bin mountPath: /tmp/blazar-manager.sh subPath: blazar-manager.sh readOnly: true - name: blazar-etc mountPath: /etc/blazar/blazar.conf subPath: blazar.conf readOnly: true {{- if .Values.conf.blazar.DEFAULT.log_config_append }} - name: blazar-etc mountPath: {{ .Values.conf.blazar.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.blazar.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: blazar-etc mountPath: /etc/blazar/policy.yaml subPath: policy.yaml readOnly: true {{- if $mounts.volumeMounts }} {{ toYaml $mounts.volumeMounts | indent 12 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-blazar emptyDir: {} - name: blazar-bin configMap: name: blazar-bin defaultMode: 0555 - name: blazar-etc secret: secretName: blazar-etc defaultMode: 0444 {{- if $mounts.volumes }} {{ toYaml $mounts.volumes | indent 8 }} {{- end }} {{- end }} ... ================================================ FILE: blazar/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: blazar/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "api" "backendServiceType" "reservation" "backendPort" "b-api" -}} {{- $secretName := index $envAll.Values.secrets.tls.reservation.api ($envAll.Values.network.api.ingress.classes.namespace | replace "-" "_") -}} {{- if $envAll.Values.tls.identity -}} {{- $_ := set $ingressOpts "certIssuer" $envAll.Values.endpoints.identity.auth.blazar.tls.ca -}} {{- end -}} {{- if hasKey $envAll.Values.secrets.tls.reservation.api $envAll.Values.network.api.ingress.classes.namespace -}} {{- $_ := set $ingressOpts "tlsSecret" $secretName -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: blazar/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "blazar" "keystoneUser" .Values.bootstrap.ks_user -}} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: blazar/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "blazar" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: blazar/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "blazar" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: blazar/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "blazar" "podVolMounts" .Values.pod.mounts.blazar_db_sync.blazar_db_sync.volumeMounts "podVols" .Values.pod.mounts.blazar_db_sync.blazar_db_sync.volumes -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: blazar/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksEndpointsJob := dict "envAll" . "serviceName" "blazar" "serviceTypes" ( tuple "reservation" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksEndpointsJob "tlsSecret" .Values.secrets.tls.reservation.api.internal -}} {{- end -}} {{- $_ := set $ksEndpointsJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $ksEndpointsJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksEndpointsJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: blazar/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "blazar" "serviceTypes" ( tuple "reservation" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.reservation.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: blazar/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "blazar" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.reservation.api.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: blazar/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "blazar" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $rmqUserJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $rmqUserJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{- if .Values.pod.tolerations.blazar.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: blazar/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: blazar-api labels: {{ tuple $envAll "blazar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{- if .Values.pod.lifecycle.disruption_budget.api.min_available }} minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} {{- else }} maxUnavailable: {{ .Values.pod.lifecycle.disruption_budget.api.max_unavailable | default 1 }} {{- end }} selector: matchLabels: {{ tuple $envAll "blazar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ... ================================================ FILE: blazar/templates/pdb-manager.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_manager }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: blazar-manager labels: {{ tuple $envAll "blazar" "manager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{- if .Values.pod.lifecycle.disruption_budget.manager.min_available }} minAvailable: {{ .Values.pod.lifecycle.disruption_budget.manager.min_available }} {{- else }} maxUnavailable: {{ .Values.pod.lifecycle.disruption_budget.manager.max_unavailable | default 1 }} {{- end }} selector: matchLabels: {{ tuple $envAll "blazar" "manager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ... ================================================ FILE: blazar/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_blazar_tests := .Values.pod.mounts.blazar_tests.blazar_tests }} {{- $mounts_blazar_tests_init := .Values.pod.mounts.blazar_tests.init_container }} {{- $serviceAccountName := print $envAll.deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.Chart.Name "-test" }} labels: {{ tuple $envAll "blazar" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "blazar-test" "containerNames" (list "init" "blazar-test" "blazar-test-ks-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ if $envAll.Values.pod.tolerations.blazar.enabled }} {{ tuple $envAll "blazar" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} restartPolicy: Never {{ tuple "blazar_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "blazar_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_blazar_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: blazar-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "blazar_test_ks_user" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: blazar-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{ dict "enabled" .Values.manifests.certificates "name" $envAll.Values.secrets.tls.reservation.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: blazar-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "blazar_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.Chart.Name}} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: blazar-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: blazar-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} - name: blazar-etc mountPath: {{ $value.name }} subPath: {{ printf "test_template_%d" $key }} readOnly: true {{- end }} - name: rally-work mountPath: /home/rally/.rally {{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.reservation.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_blazar_tests.volumeMounts }}{{ toYaml $mounts_blazar_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: blazar-etc secret: secretName: blazar-etc defaultMode: 0444 - name: blazar-bin configMap: name: blazar-bin defaultMode: 0555 - name: rally-db emptyDir: {} - name: rally-work emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.reservation.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_blazar_tests.volumes }}{{ toYaml $mounts_blazar_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: blazar/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "blazar" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ... ================================================ FILE: blazar/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "blazar" "service" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ... ================================================ FILE: blazar/templates/secret-ks-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ks_etc }} {{- $envAll := . -}} {{/* the endpoints.identity.auth sections with the oslo conf sections they get rendered to */}} {{- $ksUsers := dict "blazar" "keystone_authtoken" -}} {{ dict "envAll" $envAll "serviceName" "blazar" "serviceUserSections" $ksUsers | include "helm-toolkit.manifests.secret_ks_etc" }} {{- end }} ================================================ FILE: blazar/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "blazar" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ... ================================================ FILE: blazar/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "reservation" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: b-api port: {{ tuple "reservation" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{- end }} selector: {{ tuple $envAll "blazar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if .Values.network.api.node_port.enabled }} type: NodePort {{- if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{- end }} {{- end }} {{- end }} ... ================================================ FILE: blazar/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "reservation" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: blazar/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- release_group: null labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled manager: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy rabbit_init: docker.io/rabbitmq:3.13-management blazar_db_sync: quay.io/airshipit/blazar:2025.1-ubuntu_jammy blazar_api: quay.io/airshipit/blazar:2025.1-ubuntu_jammy blazar_manager: quay.io/airshipit/blazar:2025.1-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30788 manager: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30789 dependencies: dynamic: common: local_image_registry: jobs: - blazar-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - blazar-db-sync - blazar-ks-user - blazar-ks-endpoints - blazar-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging manager: jobs: - blazar-db-sync - blazar-ks-user - blazar-ks-endpoints - blazar-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging bootstrap: services: - endpoint: internal service: identity - endpoint: internal service: reservation db_init: services: - endpoint: internal service: oslo_db db_drop: services: - endpoint: internal service: oslo_db db_sync: jobs: - blazar-db-init services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - blazar-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - endpoint: internal service: oslo_messaging tests: jobs: - blazar-db-sync services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: reservation - endpoint: internal service: compute image_repo_sync: services: - endpoint: internal service: local_image_registry secrets: identity: admin: blazar-keystone-admin blazar: blazar-keystone-user service: blazar-keystone-service test: blazar-keystone-test oslo_db: admin: blazar-db-admin blazar: blazar-db-user oslo_messaging: admin: blazar-rabbitmq-admin blazar: blazar-rabbitmq-user tls: reservation: api: public: blazar-tls-public internal: blazar-tls-internal nginx: blazar-tls-nginx nginx_cluster: blazar-tls-nginx-cluster endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default blazar: role: admin region_name: RegionOne username: blazar password: password project_name: service user_domain_name: service project_domain_name: service service: role: admin,service region_name: RegionOne username: blazar_service_user password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: blazar-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 reservation: name: blazar hosts: default: blazar-api public: blazar host_fqdn_override: default: null path: default: /v1 scheme: default: 'http' service: 'http' port: api: default: 1234 public: 80 service: 1234 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct blazar: username: blazar password: password hosts: default: mariadb host_fqdn_override: default: null path: /blazar scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct blazar: username: blazar password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /blazar scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 compute: name: nova hosts: default: nova-api internal: nova-api host_fqdn_override: default: null path: default: "/v2.1" scheme: default: http port: api: default: 80 internal: 8774 public: 80 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 pod: probes: rpc_timeout: 60 rpc_retries: 2 api: default: liveness: enabled: True params: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 readiness: enabled: True params: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 security_context: blazar: pod: runAsUser: 42424 container: blazar_api: runAsUser: 0 blazar_manager: readOnlyRootFilesystem: true allowPrivilegeEscalation: false test: pod: runAsUser: 42424 container: blazar_test_ks_user: readOnlyRootFilesystem: true allowPrivilegeEscalation: false blazar_test: runAsUser: 65500 readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: blazar: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: blazar_api: init_container: null blazar_api: volumeMounts: volumes: blazar_manager: init_container: null blazar_manager: volumeMounts: volumes: blazar_bootstrap: init_container: null blazar_bootstrap: volumeMounts: volumes: blazar_db_sync: blazar_db_sync: volumeMounts: volumes: blazar_tests: init_container: null blazar_tests: volumeMounts: volumes: replicas: api: 1 manager: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 manager: min_available: 0 termination_grace_period: api: timeout: 30 manager: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" manager: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: backoffLimit: 5 activeDeadlineSeconds: 600 db_init: backoffLimit: 5 activeDeadlineSeconds: 600 db_drop: backoffLimit: 5 activeDeadlineSeconds: 600 db_sync: backoffLimit: 5 activeDeadlineSeconds: 600 ks_endpoints: backoffLimit: 5 activeDeadlineSeconds: 600 ks_service: backoffLimit: 5 activeDeadlineSeconds: 600 ks_user: backoffLimit: 5 activeDeadlineSeconds: 600 rabbit_init: backoffLimit: 5 activeDeadlineSeconds: 600 conf: blazar: DEFAULT: debug: false log_config_append: /etc/blazar/logging.conf api_paste_config: /etc/blazar/api-paste.ini os_auth_protocol: os_auth_host: os_auth_port: os_region_name: os_admin_username: os_admin_password: os_admin_project_name: os_admin_user_domain_name: os_admin_project_domain_name: database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: service_token_roles: service service_token_roles_required: true auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT service_type: reservation oslo_messaging_notifications: driver: messagingv2 oslo_messaging_rabbit: rabbit_ha_queues: true oslo_concurrency: lock_path: /var/lock manager: plugins: physical.host.plugin,virtual.instance.plugin,flavor.instance.plugin,virtual.floatingip.plugin enforcement: enabled_filters: - MaxLeaseDurationFilter max_lease_duration: 86400 physical_host_plugin: aggregate_freepool_name: freepool blazar_username: blazar blazar_password: password blazar_project_name: service blazar_user_domain_name: service blazar_project_domain_name: service nova_client_timeout: 30 enable_host_reservation: true logging: loggers: keys: - root - blazar handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: "null" logger_blazar: level: INFO handlers: - stdout qualname: blazar logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" api_paste: composite:reservation: use: "egg:Paste#urlmap" "/": blazarversions "/v1": blazarapi_v1 "/v2": blazarapi_v2 composite:blazarapi_v1: use: "call:blazar.api.middleware:pipeline_factory" noauth: "request_id faultwrap sizelimit noauth blazarapi_v1" keystone: "request_id faultwrap sizelimit authtoken keystonecontext blazarapi_v1" composite:blazarapi_v2: use: "call:blazar.api.middleware:pipeline_factory" noauth: "request_id faultwrap sizelimit noauth blazarapi_v2" keystone: "request_id faultwrap sizelimit authtoken keystonecontext blazarapi_v2" app:blazarversions: paste.app_factory: "blazar.api.versions:Versions.factory" app:blazarapi_v1: paste.app_factory: "blazar.api.v1.app:make_app" app:blazarapi_v2: paste.app_factory: "blazar.api.v2.app:make_app" filter:request_id: paste.filter_factory: "oslo_middleware:RequestId.factory" filter:faultwrap: paste.filter_factory: "blazar.api.middleware:FaultWrapper.factory" filter:noauth: paste.filter_factory: "blazar.api.middleware:NoAuthMiddleware.factory" filter:sizelimit: paste.filter_factory: "oslo_middleware:RequestBodySizeLimiter.factory" filter:authtoken: paste.filter_factory: "keystonemiddleware.auth_token:filter_factory" filter:keystonecontext: paste.filter_factory: "blazar.api.middleware:KeystoneContextMiddleware.factory" policy: {} rabbitmq: policies: - vhost: "blazar" name: "ha_ttl_blazar" pattern: '^(?!(amq\.|reply_)).*' definition: ha-mode: "all" ha-sync-mode: "automatic" message-ttl: 70000 priority: 0 apply-to: all rally_tests: run_tempest: false tests: # NOTE:This is a dummy test added as a placeholder and currently, Rally does not support Blazar scenarios. Dummy.dummy: - args: sleep: 5 runner: type: "constant" times: 20 concurrency: 5 sla: failure_rate: max: 0 templates: [] bootstrap: enabled: false ks_user: blazar script: | openstack token issue manifests: certificates: false configmap_bin: true configmap_etc: true deployment_api: true deployment_manager: true ingress_api: true job_bootstrap: true job_db_init: true job_db_drop: false job_db_sync: true job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pdb_api: true pdb_manager: true pod_rally_test: true secret_db: true secret_keystone: true secret_ks_etc: true secret_rabbitmq: true service_api: true service_ingress_api: true network_policy: blazar: ingress: - {} egress: - {} tls: identity: false oslo_messaging: false oslo_db: false reservation: api: public: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ca-clusterissuer/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: "1.0" description: Certificate Issuer chart for OSH home: https://cert-manager.io/ name: ca-clusterissuer version: 2025.2.0 dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ca-clusterissuer/templates/clusterissuer-ca.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.clusterissuer }} {{- $envAll := . }} --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: {{ .Values.conf.ca.issuer.name }} labels: {{ tuple $envAll "cert-manager" "clusterissuer" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: ca: secretName: {{ .Values.conf.ca.secret.name }} ... {{- end }} ================================================ FILE: ca-clusterissuer/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ca-clusterissuer/templates/secret-ca.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ca }} --- apiVersion: v1 kind: Secret metadata: name: {{ .Values.conf.ca.secret.name }} namespace: {{ .Values.conf.ca.secret.namespace }} data: tls.crt: {{ .Values.conf.ca.secret.crt | default "" | b64enc }} tls.key: {{ .Values.conf.ca.secret.key | default "" | b64enc }} ... {{- end }} ================================================ FILE: ca-clusterissuer/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- conf: ca: issuer: name: ca-clusterissuer secret: name: secret-name # Namespace where cert-manager is deployed. namespace: cert-manager crt: null key: null manifests: clusterissuer: true secret_ca: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ca-issuer/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: "1.0" description: Certificate Issuer chart for OSH home: https://cert-manager.io/ name: ca-issuer version: 2025.2.0 dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ca-issuer/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ca-issuer/templates/issuer-ca.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.issuer }} {{- $envAll := . }} --- {{- if semverCompare "< v1.0.0" .Values.cert_manager_version }} apiVersion: cert-manager.io/v1alpha3 {{- else }} apiVersion: cert-manager.io/v1 {{- end }} kind: Issuer metadata: name: {{ .Values.conf.ca.issuer.name }} namespace: {{ .Release.Namespace }} labels: {{ tuple $envAll "cert-manager" "issuer" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: ca: secretName: {{ .Values.conf.ca.secret.name }} ... {{- end }} ================================================ FILE: ca-issuer/templates/secret-ca.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ca }} --- apiVersion: v1 kind: Secret metadata: name: {{ .Values.conf.ca.secret.name }} namespace: {{ .Release.Namespace }} data: tls.crt: {{ .Values.conf.ca.secret.crt | default "" | b64enc }} tls.key: {{ .Values.conf.ca.secret.key | default "" | b64enc }} ... {{- end }} ================================================ FILE: ca-issuer/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- conf: ca: issuer: name: ca-issuer secret: name: secret-name crt: null key: null # Default Version of jetstack/cert-manager being deployed. # Starting at v1.0.0, api-version: cert-manager.io/v1 is used # For previous apiVersion: cert-manager.io/v1alpha3, change to older version (such as v0.15.0) cert_manager_version: v1.0.0 manifests: issuer: true secret_ca: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ceilometer/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Ceilometer name: ceilometer version: 2025.2.0 home: https://docs.openstack.org/ceilometer/latest/ sources: - https://opendev.org/openstack/ceilometer - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ceilometer/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: ceilometer/templates/bin/_ceilometer-central.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec ceilometer-polling \ --polling-namespaces central \ --config-file /etc/ceilometer/ceilometer.conf \ --config-dir /etc/ceilometer/ceilometer.conf.d ================================================ FILE: ceilometer/templates/bin/_ceilometer-compute.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec ceilometer-polling \ --polling-namespaces compute \ --config-file /etc/ceilometer/ceilometer.conf \ --config-dir /etc/ceilometer/ceilometer.conf.d ================================================ FILE: ceilometer/templates/bin/_ceilometer-ipmi.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec ceilometer-polling \ --polling-namespaces ipmi \ --config-file /etc/ceilometer/ceilometer.conf \ --config-dir /etc/ceilometer/ceilometer.conf.d ================================================ FILE: ceilometer/templates/bin/_ceilometer-notification.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec ceilometer-agent-notification \ --config-file /etc/ceilometer/ceilometer.conf \ --config-dir /etc/ceilometer/ceilometer.conf.d ================================================ FILE: ceilometer/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec ceilometer-upgrade ================================================ FILE: ceilometer/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: ceilometer-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} ceilometer-central.sh: | {{ tuple "bin/_ceilometer-central.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ceilometer-compute.sh: | {{ tuple "bin/_ceilometer-compute.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ceilometer-notification.sh: | {{ tuple "bin/_ceilometer-notification.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: ceilometer/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.ceilometer.cache.memcache_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.ceilometer.cache "memcache_servers" -}} {{- end -}} {{- if empty .Values.conf.ceilometer.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "ceilometer" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.ceilometer.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.ceilometer.oslo_messaging_notifications.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "ceilometer" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.ceilometer.oslo_messaging_notifications "transport_url" -}} {{- end -}} {{- if empty .Values.conf.ceilometer.notification.messaging_urls -}} {{- $_ := tuple "oslo_messaging" "internal" "ceilometer" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.ceilometer.notification "messaging_urls" -}} {{- end -}} {{- if empty .Values.conf.ceilometer.service_credentials.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.ceilometer.service_credentials "auth_url" -}} {{- end -}} {{- if empty .Values.conf.ceilometer.service_credentials.region_name -}} {{- $_ := set .Values.conf.ceilometer.service_credentials "region_name" .Values.endpoints.identity.auth.ceilometer.region_name -}} {{- end -}} {{- if empty .Values.conf.ceilometer.service_credentials.project_name -}} {{- $_ := set .Values.conf.ceilometer.service_credentials "project_name" .Values.endpoints.identity.auth.ceilometer.project_name -}} {{- end -}} {{- if empty .Values.conf.ceilometer.service_credentials.project_domain_name -}} {{- $_ := set .Values.conf.ceilometer.service_credentials "project_domain_name" .Values.endpoints.identity.auth.ceilometer.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.ceilometer.service_credentials.user_domain_name -}} {{- $_ := set .Values.conf.ceilometer.service_credentials "user_domain_name" .Values.endpoints.identity.auth.ceilometer.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.ceilometer.service_credentials.username -}} {{- $_ := set .Values.conf.ceilometer.service_credentials "username" .Values.endpoints.identity.auth.ceilometer.username -}} {{- end -}} {{- if empty .Values.conf.ceilometer.service_credentials.password -}} {{- $_ := set .Values.conf.ceilometer.service_credentials "password" .Values.endpoints.identity.auth.ceilometer.password -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: ceilometer-etc type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests | b64enc }} ceilometer.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.ceilometer | b64enc }} event_pipeline.yaml: {{ toYaml .Values.conf.event_pipeline | b64enc }} pipeline.yaml: {{ toYaml .Values.conf.pipeline | b64enc }} event_definitions.yaml: {{ toYaml .Values.conf.event_definitions | b64enc }} gnocchi_resources.yaml: {{ toYaml .Values.conf.gnocchi_resources | b64enc }} meters.yaml: {{ toYaml .Values.conf.meters | b64enc }} polling.yaml: {{ toYaml .Values.conf.polling | b64enc }} {{- if .Values.conf.security }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.security "key" "security.conf" "format" "Secret" ) | indent 2 }} {{- end}} {{ include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_ceilometer "key" "wsgi-ceilometer.conf" "format" "Secret" ) | indent 2 }} {{- end }} ================================================ FILE: ceilometer/templates/daemonset-compute.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset_compute }} {{- $envAll := . }} {{- $mounts_ceilometer_compute := .Values.pod.mounts.ceilometer_compute.ceilometer_compute }} {{- $mounts_ceilometer_compute_init := .Values.pod.mounts.ceilometer_compute.init_container }} {{- $serviceAccountName := "ceilometer-compute" }} {{ tuple $envAll "compute" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.ceilometer_compute }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: ceilometer-compute annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceilometer" "compute" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "ceilometer" "compute" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "compute" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "ceilometer" "compute" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "ceilometer_compute" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceilometer" "compute" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} hostNetwork: true hostPID: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: {{ .Values.labels.compute.node_selector_key }}: {{ .Values.labels.compute.node_selector_value }} {{ if $envAll.Values.pod.tolerations.ceilometer.enabled }} {{ tuple $envAll "ceilometer" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "compute" $mounts_ceilometer_compute_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceilometer-compute {{ tuple $envAll "ceilometer_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.compute | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/ceilometer-compute.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.ceilometer.oslo_concurrency.lock_path }} - name: pod-etc-ceilometer mountPath: /etc/ceilometer - name: ceilometer-etc mountPath: /etc/ceilometer/ceilometer.conf subPath: ceilometer.conf readOnly: true - name: ceilometer-etc-snippets mountPath: /etc/ceilometer/ceilometer.conf.d/ readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/api_paste.ini subPath: api_paste.ini readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/policy.yaml subPath: policy.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_definitions.yaml subPath: event_definitions.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_pipeline.yaml subPath: event_pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/pipeline.yaml subPath: pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/gnocchi_resources.yaml subPath: gnocchi_resources.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/polling.yaml subPath: polling.yaml readOnly: true - name: ceilometer-bin mountPath: /tmp/ceilometer-compute.sh subPath: ceilometer-compute.sh readOnly: true - name: varlibnova mountPath: /var/lib/nova - name: varliblibvirt mountPath: /var/lib/libvirt - name: run mountPath: /run - name: cgroup mountPath: /sys/fs/cgroup - name: machine-id mountPath: /etc/machine-id readOnly: true {{ if $mounts_ceilometer_compute.volumeMounts }}{{ toYaml $mounts_ceilometer_compute.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-ceilometer emptyDir: {} - name: ceilometer-etc secret: secretName: ceilometer-etc defaultMode: 0444 - name: ceilometer-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: ceilometer-bin configMap: name: ceilometer-bin defaultMode: 0555 - name: varlibnova hostPath: path: /var/lib/nova - name: varliblibvirt hostPath: path: /var/lib/libvirt - name: run hostPath: path: /run - name: cgroup hostPath: path: /sys/fs/cgroup - name: machine-id hostPath: path: /etc/machine-id {{ if $mounts_ceilometer_compute.volumes }}{{ toYaml $mounts_ceilometer_compute.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: ceilometer/templates/daemonset-ipmi.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset_ipmi }} {{- $envAll := . }} {{- $mounts_ceilometer_ipmi := .Values.pod.mounts.ceilometer_ipmi.ceilometer_ipmi }} {{- $mounts_ceilometer_ipmi_init := .Values.pod.mounts.ceilometer_ipmi.init_container }} {{- $serviceAccountName := "ceilometer-ipmi" }} {{ tuple $envAll "ipmi" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.ceilometer_ipmi }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: ceilometer-ipmi annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceilometer" "ipmi" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "ceilometer" "ipmi" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "ipmi" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "ceilometer" "ipmi" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "ceilometer_ipmi" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceilometer" "ipmi" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} hostNetwork: true hostPID: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: {{ .Values.labels.ipmi.node_selector_key }}: {{ .Values.labels.ipmi.node_selector_value }} {{ if $envAll.Values.pod.tolerations.ceilometer.enabled }} {{ tuple $envAll "ceilometer" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "ipmi" $mounts_ceilometer_ipmi_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceilometer-ipmi {{ tuple $envAll "ceilometer_ipmi" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ipmi | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: privileged: true command: - /tmp/ceilometer-ipmi.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.ceilometer.oslo_concurrency.lock_path }} - name: pod-etc-ceilometer mountPath: /etc/ceilometer - name: ceilometer-etc mountPath: /etc/ceilometer/ceilometer.conf subPath: ceilometer.conf readOnly: true - name: ceilometer-etc-snippets mountPath: /etc/ceilometer/ceilometer.conf.d/ readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/api_paste.ini subPath: api_paste.ini readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/policy.yaml subPath: policy.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_definitions.yaml subPath: event_definitions.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_pipeline.yaml subPath: event_pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/pipeline.yaml subPath: pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/gnocchi_resources.yaml subPath: gnocchi_resources.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/polling.yaml subPath: polling.yaml readOnly: true - name: ceilometer-bin mountPath: /tmp/ceilometer-ipmi.sh subPath: ceilometer-ipmi.sh readOnly: true - name: ipmi-device mountPath: {{ .Values.ipmi_device }} readOnly: true {{ if $mounts_ceilometer_ipmi.volumeMounts }}{{ toYaml $mounts_ceilometer_ipmi.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-ceilometer emptyDir: {} - name: ceilometer-etc secret: secretName: ceilometer-etc defaultMode: 0444 - name: ceilometer-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: ceilometer-bin configMap: name: ceilometer-bin defaultMode: 0555 - name: ipmi-device hostPath: path: {{ .Values.ipmi_device }} {{ if $mounts_ceilometer_ipmi.volumes }}{{ toYaml $mounts_ceilometer_ipmi.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: ceilometer/templates/deployment-central.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_central }} {{- $envAll := . }} {{- $mounts_ceilometer_central := .Values.pod.mounts.ceilometer_central.ceilometer_central }} {{- $mounts_ceilometer_central_init := .Values.pod.mounts.ceilometer_central.init_container }} {{- $serviceAccountName := "ceilometer-central" }} {{ tuple $envAll "central" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.ceilometer_central }} --- apiVersion: apps/v1 kind: Deployment metadata: name: ceilometer-central annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceilometer" "central" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.central }} selector: matchLabels: {{ tuple $envAll "ceilometer" "central" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "ceilometer" "central" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "ceilometer_central" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceilometer" "central" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.central.node_selector_key }}: {{ .Values.labels.central.node_selector_value }} {{ if $envAll.Values.pod.tolerations.ceilometer.enabled }} {{ tuple $envAll "ceilometer" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "central" $mounts_ceilometer_central_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceilometer-central {{ tuple $envAll "ceilometer_central" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.central | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/ceilometer-central.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.ceilometer.oslo_concurrency.lock_path }} - name: pod-etc-ceilometer mountPath: /etc/ceilometer - name: ceilometer-etc mountPath: /etc/ceilometer/ceilometer.conf subPath: ceilometer.conf readOnly: true - name: ceilometer-etc-snippets mountPath: /etc/ceilometer/ceilometer.conf.d/ readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/api_paste.ini subPath: api_paste.ini readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/policy.yaml subPath: policy.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_definitions.yaml subPath: event_definitions.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_pipeline.yaml subPath: event_pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/pipeline.yaml subPath: pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/gnocchi_resources.yaml subPath: gnocchi_resources.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/polling.yaml subPath: polling.yaml readOnly: true - name: ceilometer-bin mountPath: /tmp/ceilometer-central.sh subPath: ceilometer-central.sh readOnly: true {{ if $mounts_ceilometer_central.volumeMounts }}{{ toYaml $mounts_ceilometer_central.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-ceilometer emptyDir: {} - name: ceilometer-etc secret: secretName: ceilometer-etc defaultMode: 0444 - name: ceilometer-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: ceilometer-bin configMap: name: ceilometer-bin defaultMode: 0555 {{ if $mounts_ceilometer_central.volumes }}{{ toYaml $mounts_ceilometer_central.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: ceilometer/templates/deployment-notification.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_notification }} {{- $envAll := . }} {{- $mounts_ceilometer_notification := .Values.pod.mounts.ceilometer_notification.ceilometer_notification }} {{- $mounts_ceilometer_notification_init := .Values.pod.mounts.ceilometer_notification.init_container }} {{- $serviceAccountName := "ceilometer-notification" }} {{ tuple $envAll "notification" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.ceilometer_notification }} --- apiVersion: apps/v1 kind: Deployment metadata: name: ceilometer-notification annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceilometer" "notification" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.notification }} selector: matchLabels: {{ tuple $envAll "ceilometer" "notification" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "ceilometer" "notification" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "ceilometer_notification" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceilometer" "notification" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.notification.node_selector_key }}: {{ .Values.labels.notification.node_selector_value }} {{ if $envAll.Values.pod.tolerations.ceilometer.enabled }} {{ tuple $envAll "ceilometer" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "notification" $mounts_ceilometer_notification_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceilometer-notification {{ tuple $envAll "ceilometer_notification" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.notification | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/ceilometer-notification.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.ceilometer.oslo_concurrency.lock_path }} - name: pod-etc-ceilometer mountPath: /etc/ceilometer - name: ceilometer-etc mountPath: /etc/ceilometer/ceilometer.conf subPath: ceilometer.conf readOnly: true - name: ceilometer-etc-snippets mountPath: /etc/ceilometer/ceilometer.conf.d/ readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/api_paste.ini subPath: api_paste.ini readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/policy.yaml subPath: policy.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_definitions.yaml subPath: event_definitions.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/event_pipeline.yaml subPath: event_pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/pipeline.yaml subPath: pipeline.yaml readOnly: true - name: ceilometer-etc mountPath: /etc/ceilometer/gnocchi_resources.yaml subPath: gnocchi_resources.yaml readOnly: true - name: etc-ceilometer-meters mountPath: /etc/ceilometer/meters.d - name: ceilometer-etc mountPath: /etc/ceilometer/meters.d/meters.yaml subPath: meters.yaml readOnly: true - name: ceilometer-bin mountPath: /tmp/ceilometer-notification.sh subPath: ceilometer-notification.sh readOnly: true {{ if $mounts_ceilometer_notification.volumeMounts }}{{ toYaml $mounts_ceilometer_notification.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-ceilometer emptyDir: {} - name: etc-ceilometer-meters emptyDir: {} - name: ceilometer-etc secret: secretName: ceilometer-etc defaultMode: 0444 - name: ceilometer-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: ceilometer-bin configMap: name: ceilometer-bin defaultMode: 0555 {{ if $mounts_ceilometer_notification.volumes }}{{ toYaml $mounts_ceilometer_notification.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: ceilometer/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ceilometer/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "ceilometer" "keystoneUser" .Values.bootstrap.ks_user -}} {{- if .Values.pod.tolerations.ceilometer.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: ceilometer/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "ceilometer" "podVolMounts" .Values.pod.mounts.ceilometer_db_sync.ceilometer_db_sync.volumeMounts "podVols" .Values.pod.mounts.ceilometer_db_sync.ceilometer_db_sync.volumes -}} {{- if .Values.pod.tolerations.ceilometer.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: ceilometer/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ceilometer" -}} {{- if .Values.pod.tolerations.ceilometer.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: ceilometer/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "ceilometer" -}} {{- if .Values.pod.tolerations.ceilometer.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: ceilometer/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "ceilometer" -}} {{- if .Values.pod.tolerations.ceilometer.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: ceilometer/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "ceilometer" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: ceilometer/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "ceilometer" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: ceilometer/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "ceilometer" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: ceilometer/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: ceilometer/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for ceilometer. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null labels: compute: node_selector_key: openstack-compute-node node_selector_value: enabled central: node_selector_key: openstack-control-plane node_selector_value: enabled ipmi: node_selector_key: openstack-node node_selector_value: enabled notification: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ceilometer_central: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ceilometer_compute: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ceilometer_ipmi: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ceilometer_notification: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync ipmi_device: /dev/ipmi0 conf: ceilometer: DEFAULT: transport_url: null service_credentials: auth_type: password interface: internal notification: messaging_urls: type: multistring values: - rabbit://rabbitmq:password@rabbitmq.openstack.svc.cluster.local:5672/ceilometer - rabbit://rabbitmq:password@rabbitmq.openstack.svc.cluster.local:5672/cinder - rabbit://rabbitmq:password@rabbitmq.openstack.svc.cluster.local:5672/glance - rabbit://rabbitmq:password@rabbitmq.openstack.svc.cluster.local:5672/nova - rabbit://rabbitmq:password@rabbitmq.openstack.svc.cluster.local:5672/keystone - rabbit://rabbitmq:password@rabbitmq.openstack.svc.cluster.local:5672/neutron - rabbit://rabbitmq:password@rabbitmq.openstack.svc.cluster.local:5672/heat oslo_messaging_notifications: driver: messagingv2 topics: - notifications - profiler oslo_concurrency: lock_path: /var/lock cache: enabled: true backend: dogpile.cache.memcached expiration_time: 86400 event_definitions: - event_type: 'compute.instance.*' traits: &instance_traits tenant_id: fields: payload.tenant_id user_id: fields: payload.user_id instance_id: fields: payload.instance_id resource_id: fields: payload.instance_id host: fields: publisher_id.`split(., 1, 1)` service: fields: publisher_id.`split(., 0, -1)` memory_mb: type: int fields: payload.memory_mb disk_gb: type: int fields: payload.disk_gb root_gb: type: int fields: payload.root_gb ephemeral_gb: type: int fields: payload.ephemeral_gb vcpus: type: int fields: payload.vcpus instance_type_id: type: int fields: payload.instance_type_id instance_type: fields: payload.instance_type state: fields: payload.state os_architecture: fields: payload.image_meta.'org.openstack__1__architecture' os_version: fields: payload.image_meta.'org.openstack__1__os_version' os_distro: fields: payload.image_meta.'org.openstack__1__os_distro' launched_at: type: datetime fields: payload.launched_at deleted_at: type: datetime fields: payload.deleted_at - event_type: compute.instance.update traits: <<: *instance_traits old_state: fields: payload.old_state - event_type: compute.instance.exists traits: <<: *instance_traits audit_period_beginning: type: datetime fields: payload.audit_period_beginning audit_period_ending: type: datetime fields: payload.audit_period_ending - event_type: ['volume.exists', 'volume.create.*', 'volume.delete.*', 'volume.resize.*', 'volume.attach.*', 'volume.detach.*', 'volume.update.*', 'snapshot.exists', 'snapshot.create.*', 'snapshot.delete.*', 'snapshot.update.*'] traits: &cinder_traits user_id: fields: payload.user_id project_id: fields: payload.tenant_id availability_zone: fields: payload.availability_zone display_name: fields: payload.display_name replication_status: fields: payload.replication_status status: fields: payload.status created_at: fields: payload.created_at - event_type: ['volume.exists', 'volume.create.*', 'volume.delete.*', 'volume.resize.*', 'volume.attach.*', 'volume.detach.*', 'volume.update.*'] traits: <<: *cinder_traits resource_id: fields: payload.volume_id host: fields: payload.host size: fields: payload.size type: fields: payload.volume_type replication_status: fields: payload.replication_status - event_type: ['snapshot.exists', 'snapshot.create.*', 'snapshot.delete.*', 'snapshot.update.*'] traits: <<: *cinder_traits resource_id: fields: payload.snapshot_id volume_id: fields: payload.volume_id - event_type: ['image_volume_cache.*'] traits: image_id: fields: payload.image_id host: fields: payload.host - event_type: ['image.create', 'image.update', 'image.upload', 'image.delete'] traits: &glance_crud project_id: fields: payload.owner resource_id: fields: payload.id name: fields: payload.name status: fields: payload.status created_at: fields: payload.created_at user_id: fields: payload.owner deleted_at: fields: payload.deleted_at size: fields: payload.size - event_type: image.send traits: &glance_send receiver_project: fields: payload.receiver_tenant_id receiver_user: fields: payload.receiver_user_id user_id: fields: payload.owner_id image_id: fields: payload.image_id destination_ip: fields: payload.destination_ip bytes_sent: type: int fields: payload.bytes_sent - event_type: orchestration.stack.* traits: &orchestration_crud project_id: fields: payload.tenant_id user_id: fields: ['_context_trustor_user_id', '_context_user_id'] resource_id: fields: payload.stack_identity - event_type: sahara.cluster.* traits: &sahara_crud project_id: fields: payload.project_id user_id: fields: _context_user_id resource_id: fields: payload.cluster_id - event_type: sahara.cluster.health traits: &sahara_health <<: *sahara_crud verification_id: fields: payload.verification_id health_check_status: fields: payload.health_check_status health_check_name: fields: payload.health_check_name health_check_description: fields: payload.health_check_description created_at: type: datetime fields: payload.created_at updated_at: type: datetime fields: payload.updated_at - event_type: ['identity.user.*', 'identity.project.*', 'identity.group.*', 'identity.role.*', 'identity.OS-TRUST:trust.*', 'identity.region.*', 'identity.service.*', 'identity.endpoint.*', 'identity.policy.*'] traits: &identity_crud resource_id: fields: payload.resource_info initiator_id: fields: payload.initiator.id project_id: fields: payload.initiator.project_id domain_id: fields: payload.initiator.domain_id - event_type: identity.role_assignment.* traits: &identity_role_assignment role: fields: payload.role group: fields: payload.group domain: fields: payload.domain user: fields: payload.user project: fields: payload.project - event_type: identity.authenticate traits: &identity_authenticate typeURI: fields: payload.typeURI id: fields: payload.id action: fields: payload.action eventType: fields: payload.eventType eventTime: fields: payload.eventTime outcome: fields: payload.outcome initiator_typeURI: fields: payload.initiator.typeURI initiator_id: fields: payload.initiator.id initiator_name: fields: payload.initiator.name initiator_host_agent: fields: payload.initiator.host.agent initiator_host_addr: fields: payload.initiator.host.address target_typeURI: fields: payload.target.typeURI target_id: fields: payload.target.id observer_typeURI: fields: payload.observer.typeURI observer_id: fields: payload.observer.id - event_type: objectstore.http.request traits: &objectstore_request typeURI: fields: payload.typeURI id: fields: payload.id action: fields: payload.action eventType: fields: payload.eventType eventTime: fields: payload.eventTime outcome: fields: payload.outcome initiator_typeURI: fields: payload.initiator.typeURI initiator_id: fields: payload.initiator.id initiator_project_id: fields: payload.initiator.project_id target_typeURI: fields: payload.target.typeURI target_id: fields: payload.target.id target_action: fields: payload.target.action target_metadata_path: fields: payload.target.metadata.path target_metadata_version: fields: payload.target.metadata.version target_metadata_container: fields: payload.target.metadata.container target_metadata_object: fields: payload.target.metadata.object observer_id: fields: payload.observer.id - event_type: ['network.*', 'subnet.*', 'port.*', 'router.*', 'floatingip.*', 'pool.*', 'vip.*', 'member.*', 'health_monitor.*', 'healthmonitor.*', 'listener.*', 'loadbalancer.*', 'firewall.*', 'firewall_policy.*', 'firewall_rule.*', 'vpnservice.*', 'ipsecpolicy.*', 'ikepolicy.*', 'ipsec_site_connection.*'] traits: &network_traits user_id: fields: _context_user_id project_id: fields: _context_tenant_id - event_type: network.* traits: <<: *network_traits resource_id: fields: ['payload.network.id', 'payload.id'] - event_type: subnet.* traits: <<: *network_traits resource_id: fields: ['payload.subnet.id', 'payload.id'] - event_type: port.* traits: <<: *network_traits resource_id: fields: ['payload.port.id', 'payload.id'] - event_type: router.* traits: <<: *network_traits resource_id: fields: ['payload.router.id', 'payload.id'] - event_type: floatingip.* traits: <<: *network_traits resource_id: fields: ['payload.floatingip.id', 'payload.id'] - event_type: pool.* traits: <<: *network_traits resource_id: fields: ['payload.pool.id', 'payload.id'] - event_type: vip.* traits: <<: *network_traits resource_id: fields: ['payload.vip.id', 'payload.id'] - event_type: member.* traits: <<: *network_traits resource_id: fields: ['payload.member.id', 'payload.id'] - event_type: health_monitor.* traits: <<: *network_traits resource_id: fields: ['payload.health_monitor.id', 'payload.id'] - event_type: healthmonitor.* traits: <<: *network_traits resource_id: fields: ['payload.healthmonitor.id', 'payload.id'] - event_type: listener.* traits: <<: *network_traits resource_id: fields: ['payload.listener.id', 'payload.id'] - event_type: loadbalancer.* traits: <<: *network_traits resource_id: fields: ['payload.loadbalancer.id', 'payload.id'] - event_type: firewall.* traits: <<: *network_traits resource_id: fields: ['payload.firewall.id', 'payload.id'] - event_type: firewall_policy.* traits: <<: *network_traits resource_id: fields: ['payload.firewall_policy.id', 'payload.id'] - event_type: firewall_rule.* traits: <<: *network_traits resource_id: fields: ['payload.firewall_rule.id', 'payload.id'] - event_type: vpnservice.* traits: <<: *network_traits resource_id: fields: ['payload.vpnservice.id', 'payload.id'] - event_type: ipsecpolicy.* traits: <<: *network_traits resource_id: fields: ['payload.ipsecpolicy.id', 'payload.id'] - event_type: ikepolicy.* traits: <<: *network_traits resource_id: fields: ['payload.ikepolicy.id', 'payload.id'] - event_type: ipsec_site_connection.* traits: <<: *network_traits resource_id: fields: ['payload.ipsec_site_connection.id', 'payload.id'] - event_type: '*http.*' traits: &http_audit project_id: fields: payload.initiator.project_id user_id: fields: payload.initiator.id typeURI: fields: payload.typeURI eventType: fields: payload.eventType action: fields: payload.action outcome: fields: payload.outcome id: fields: payload.id eventTime: fields: payload.eventTime requestPath: fields: payload.requestPath observer_id: fields: payload.observer.id target_id: fields: payload.target.id target_typeURI: fields: payload.target.typeURI target_name: fields: payload.target.name initiator_typeURI: fields: payload.initiator.typeURI initiator_id: fields: payload.initiator.id initiator_name: fields: payload.initiator.name initiator_host_address: fields: payload.initiator.host.address - event_type: '*http.response' traits: <<: *http_audit reason_code: fields: payload.reason.reasonCode - event_type: ['dns.domain.create', 'dns.domain.update', 'dns.domain.delete'] traits: &dns_domain_traits status: fields: payload.status retry: fields: payload.retry description: fields: payload.description expire: fields: payload.expire email: fields: payload.email ttl: fields: payload.ttl action: fields: payload.action name: fields: payload.name resource_id: fields: payload.id created_at: fields: payload.created_at updated_at: fields: payload.updated_at version: fields: payload.version parent_domain_id: fields: parent_domain_id serial: fields: payload.serial - event_type: dns.domain.exists traits: <<: *dns_domain_traits audit_period_beginning: type: datetime fields: payload.audit_period_beginning audit_period_ending: type: datetime fields: payload.audit_period_ending - event_type: trove.* traits: &trove_base_traits instance_type: fields: payload.instance_type user_id: fields: payload.user_id resource_id: fields: payload.instance_id instance_type_id: fields: payload.instance_type_id launched_at: type: datetime fields: payload.launched_at instance_name: fields: payload.instance_name state: fields: payload.state nova_instance_id: fields: payload.nova_instance_id service_id: fields: payload.service_id created_at: type: datetime fields: payload.created_at region: fields: payload.region - event_type: ['trove.instance.create', 'trove.instance.modify_volume', 'trove.instance.modify_flavor', 'trove.instance.delete'] traits: &trove_common_traits name: fields: payload.name availability_zone: fields: payload.availability_zone instance_size: type: int fields: payload.instance_size volume_size: type: int fields: payload.volume_size nova_volume_id: fields: payload.nova_volume_id - event_type: trove.instance.create traits: <<: [*trove_base_traits, *trove_common_traits] - event_type: trove.instance.modify_volume traits: <<: [*trove_base_traits, *trove_common_traits] old_volume_size: type: int fields: payload.old_volume_size modify_at: type: datetime fields: payload.modify_at - event_type: trove.instance.modify_flavor traits: <<: [*trove_base_traits, *trove_common_traits] old_instance_size: type: int fields: payload.old_instance_size modify_at: type: datetime fields: payload.modify_at - event_type: trove.instance.delete traits: <<: [*trove_base_traits, *trove_common_traits] deleted_at: type: datetime fields: payload.deleted_at - event_type: trove.instance.exists traits: <<: *trove_base_traits display_name: fields: payload.display_name audit_period_beginning: type: datetime fields: payload.audit_period_beginning audit_period_ending: type: datetime fields: payload.audit_period_ending - event_type: profiler.* traits: project: fields: payload.project service: fields: payload.service name: fields: payload.name base_id: fields: payload.base_id trace_id: fields: payload.trace_id parent_id: fields: payload.parent_id timestamp: fields: payload.timestamp host: fields: payload.info.host path: fields: payload.info.request.path query: fields: payload.info.request.query method: fields: payload.info.request.method scheme: fields: payload.info.request.scheme db.statement: fields: payload.info.db.statement db.params: fields: payload.info.db.params - event_type: 'magnum.bay.*' traits: &magnum_bay_crud id: fields: payload.id typeURI: fields: payload.typeURI eventType: fields: payload.eventType eventTime: fields: payload.eventTime action: fields: payload.action outcome: fields: payload.outcome initiator_id: fields: payload.initiator.id initiator_typeURI: fields: payload.initiator.typeURI initiator_name: fields: payload.initiator.name initiator_host_agent: fields: payload.initiator.host.agent initiator_host_address: fields: payload.initiator.host.address target_id: fields: payload.target.id target_typeURI: fields: payload.target.typeURI observer_id: fields: payload.observer.id observer_typeURI: fields: payload.observer.typeURI event_pipeline: sinks: - name: event_sink publishers: - notifier:// - gnocchi:// sources: - events: - '*' name: event_source sinks: - event_sink gnocchi_resources: archive_policy_default: ceilometer-low archive_policies: - name: ceilometer-low aggregation_methods: - mean back_window: 0 definition: - granularity: 5 minutes timespan: 30 days resources: - metrics: - identity.authenticate.success - identity.authenticate.pending - identity.authenticate.failure - identity.user.created - identity.user.deleted - identity.user.updated - identity.group.created - identity.group.deleted - identity.group.updated - identity.role.created - identity.role.deleted - identity.role.updated - identity.project.created - identity.project.deleted - identity.project.updated - identity.trust.created - identity.trust.deleted - identity.role_assignment.created - identity.role_assignment.deleted resource_type: identity - metrics: - radosgw.objects - radosgw.objects.size - radosgw.objects.containers - radosgw.api.request - radosgw.containers.objects - radosgw.containers.objects.size resource_type: ceph_account - attributes: display_name: resource_metadata.display_name flavor_id: resource_metadata.(instance_flavor_id|(flavor.id)) host: resource_metadata.(instance_host|host) image_ref: resource_metadata.image_ref server_group: resource_metadata.user_metadata.server_group event_associated_resources: instance_disk: '{"=": {"instance_id": "%s"}}' instance_network_interface: '{"=": {"instance_id": "%s"}}' event_attributes: id: instance_id event_delete: compute.instance.delete.start metrics: - memory - memory.usage - memory.resident - vcpus - cpu - cpu.delta - cpu_util - disk.root.size - disk.ephemeral.size - disk.read.requests - disk.read.requests.rate - disk.write.requests - disk.write.requests.rate - disk.read.bytes - disk.read.bytes.rate - disk.write.bytes - disk.write.bytes.rate - disk.latency - disk.iops - disk.capacity - disk.allocation - disk.usage - compute.instance.booting.time - perf.cpu.cycles - perf.instructions - perf.cache.references - perf.cache.misses resource_type: instance - attributes: instance_id: resource_metadata.instance_id name: resource_metadata.vnic_name metrics: - network.outgoing.packets.rate - network.incoming.packets.rate - network.outgoing.packets - network.outgoing.packets.drop - network.incoming.packets.drop - network.outgoing.packets.error - network.incoming.packets.error - network.outgoing.bytes.rate - network.incoming.bytes.rate - network.outgoing.bytes - network.incoming.bytes resource_type: instance_network_interface - attributes: instance_id: resource_metadata.instance_id name: resource_metadata.disk_name metrics: - disk.device.read.requests - disk.device.read.requests.rate - disk.device.write.requests - disk.device.write.requests.rate - disk.device.read.bytes - disk.device.read.bytes.rate - disk.device.write.bytes - disk.device.write.bytes.rate - disk.device.latency - disk.device.iops - disk.device.capacity - disk.device.allocation - disk.device.usage resource_type: instance_disk - attributes: container_format: resource_metadata.container_format disk_format: resource_metadata.disk_format name: resource_metadata.name event_attributes: id: resource_id event_delete: image.delete metrics: - image.size - image.download - image.serve resource_type: image - metrics: - hardware.ipmi.node.power - hardware.ipmi.node.temperature - hardware.ipmi.node.inlet_temperature - hardware.ipmi.node.outlet_temperature - hardware.ipmi.node.fan - hardware.ipmi.node.current - hardware.ipmi.node.voltage - hardware.ipmi.node.airflow - hardware.ipmi.node.cups - hardware.ipmi.node.cpu_util - hardware.ipmi.node.mem_util - hardware.ipmi.node.io_util resource_type: ipmi - event_delete: floatingip.delete.end event_attributes: id: resource_id metrics: - bandwidth - network - network.create - network.update - subnet - subnet.create - subnet.update - port - port.create - port.update - router - router.create - router.update - ip.floating - ip.floating.create - ip.floating.update resource_type: network - metrics: - stack.create - stack.update - stack.delete - stack.resume - stack.suspend resource_type: stack - metrics: - storage.objects.incoming.bytes - storage.objects.outgoing.bytes - storage.api.request - storage.objects.size - storage.objects - storage.objects.containers - storage.containers.objects - storage.containers.objects.size resource_type: swift_account - attributes: display_name: resource_metadata.display_name volume_type: resource_metadata.volume_type event_delete: volume.delete.start event_attributes: id: resource_id metrics: - volume - volume.size - snapshot.size - volume.snapshot.size - volume.backup.size resource_type: volume - attributes: host_name: resource_metadata.resource_url metrics: - hardware.cpu.load.1min - hardware.cpu.load.5min - hardware.cpu.load.15min - hardware.cpu.util - hardware.memory.total - hardware.memory.used - hardware.memory.swap.total - hardware.memory.swap.avail - hardware.memory.buffer - hardware.memory.cached - hardware.network.ip.outgoing.datagrams - hardware.network.ip.incoming.datagrams - hardware.system_stats.cpu.idle - hardware.system_stats.io.outgoing.blocks - hardware.system_stats.io.incoming.blocks resource_type: host - attributes: device_name: resource_metadata.device host_name: resource_metadata.resource_url metrics: - hardware.disk.size.total - hardware.disk.size.used resource_type: host_disk - attributes: device_name: resource_metadata.name host_name: resource_metadata.resource_url metrics: - hardware.network.incoming.bytes - hardware.network.outgoing.bytes - hardware.network.outgoing.errors resource_type: host_network_interface meters: metric: - name: "image.size" event_type: - "image.upload" - "image.delete" - "image.update" type: "gauge" unit: B volume: $.payload.size resource_id: $.payload.id project_id: $.payload.owner - name: "image.download" event_type: "image.send" type: "delta" unit: "B" volume: $.payload.bytes_sent resource_id: $.payload.image_id user_id: $.payload.receiver_user_id project_id: $.payload.receiver_tenant_id - name: "image.serve" event_type: "image.send" type: "delta" unit: "B" volume: $.payload.bytes_sent resource_id: $.payload.image_id project_id: $.payload.owner_id - name: 'volume.size' event_type: - 'volume.exists' - 'volume.create.*' - 'volume.delete.*' - 'volume.resize.*' - 'volume.attach.*' - 'volume.detach.*' - 'volume.update.*' type: 'gauge' unit: 'GB' volume: $.payload.size user_id: $.payload.user_id project_id: $.payload.tenant_id resource_id: $.payload.volume_id metadata: display_name: $.payload.display_name volume_type: $.payload.volume_type - name: 'snapshot.size' event_type: - 'snapshot.exists' - 'snapshot.create.*' - 'snapshot.delete.*' type: 'gauge' unit: 'GB' volume: $.payload.volume_size user_id: $.payload.user_id project_id: $.payload.tenant_id resource_id: $.payload.snapshot_id metadata: display_name: $.payload.display_name - name: 'backup.size' event_type: - 'backup.exists' - 'backup.create.*' - 'backup.delete.*' - 'backup.restore.*' type: 'gauge' unit: 'GB' volume: $.payload.size user_id: $.payload.user_id project_id: $.payload.tenant_id resource_id: $.payload.backup_id metadata: display_name: $.payload.display_name - name: $.payload.metrics.[*].name event_type: 'magnum.bay.metrics.*' type: 'gauge' unit: $.payload.metrics.[*].unit volume: $.payload.metrics.[*].value user_id: $.payload.user_id project_id: $.payload.project_id resource_id: $.payload.resource_id lookup: ['name', 'unit', 'volume'] - name: $.payload.measurements.[*].metric.[*].name event_type: 'objectstore.http.request' type: 'delta' unit: $.payload.measurements.[*].metric.[*].unit volume: $.payload.measurements.[*].result resource_id: $.payload.target.id user_id: $.payload.initiator.id project_id: $.payload.initiator.project_id lookup: ['name', 'unit', 'volume'] - name: 'memory' event_type: 'compute.instance.*' type: 'gauge' unit: 'MB' volume: $.payload.memory_mb user_id: $.payload.user_id project_id: $.payload.tenant_id resource_id: $.payload.instance_id user_metadata: $.payload.metadata metadata: &instance_meta host: $.payload.host flavor_id: $.payload.instance_flavor_id flavor_name: $.payload.instance_type display_name: $.payload.display_name image_ref: $.payload.image_meta.base_image_ref - name: 'vcpus' event_type: 'compute.instance.*' type: 'gauge' unit: 'vcpu' volume: $.payload.vcpus user_id: $.payload.user_id project_id: $.payload.tenant_id resource_id: $.payload.instance_id user_metadata: $.payload.metadata metadata: <<: *instance_meta - name: 'compute.instance.booting.time' event_type: 'compute.instance.create.end' type: 'gauge' unit: 'sec' volume: fields: [$.payload.created_at, $.payload.launched_at] plugin: 'timedelta' project_id: $.payload.tenant_id resource_id: $.payload.instance_id user_metadata: $.payload.metadata metadata: <<: *instance_meta - name: 'disk.root.size' event_type: 'compute.instance.*' type: 'gauge' unit: 'GB' volume: $.payload.root_gb user_id: $.payload.user_id project_id: $.payload.tenant_id resource_id: $.payload.instance_id user_metadata: $.payload.metadata metadata: <<: *instance_meta - name: 'disk.ephemeral.size' event_type: 'compute.instance.*' type: 'gauge' unit: 'GB' volume: $.payload.ephemeral_gb user_id: $.payload.user_id project_id: $.payload.tenant_id resource_id: $.payload.instance_id user_metadata: $.payload.metadata metadata: <<: *instance_meta - name: 'bandwidth' event_type: 'l3.meter' type: 'delta' unit: 'B' volume: $.payload.bytes project_id: $.payload.tenant_id resource_id: $.payload.label_id - name: 'compute.node.cpu.frequency' event_type: 'compute.metrics.update' type: 'gauge' unit: 'MHz' volume: $.payload.metrics[?(@.name='cpu.frequency')].value resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.frequency')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.frequency')].source - name: 'compute.node.cpu.user.time' event_type: 'compute.metrics.update' type: 'cumulative' unit: 'ns' volume: $.payload.metrics[?(@.name='cpu.user.time')].value resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.user.time')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.user.time')].source - name: 'compute.node.cpu.kernel.time' event_type: 'compute.metrics.update' type: 'cumulative' unit: 'ns' volume: $.payload.metrics[?(@.name='cpu.kernel.time')].value resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.kernel.time')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.kernel.time')].source - name: 'compute.node.cpu.idle.time' event_type: 'compute.metrics.update' type: 'cumulative' unit: 'ns' volume: $.payload.metrics[?(@.name='cpu.idle.time')].value resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.idle.time')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.idle.time')].source - name: 'compute.node.cpu.iowait.time' event_type: 'compute.metrics.update' type: 'cumulative' unit: 'ns' volume: $.payload.metrics[?(@.name='cpu.iowait.time')].value resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.iowait.time')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.iowait.time')].source - name: 'compute.node.cpu.kernel.percent' event_type: 'compute.metrics.update' type: 'gauge' unit: 'percent' volume: $.payload.metrics[?(@.name='cpu.kernel.percent')].value * 100 resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.kernel.percent')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.kernel.percent')].source - name: 'compute.node.cpu.idle.percent' event_type: 'compute.metrics.update' type: 'gauge' unit: 'percent' volume: $.payload.metrics[?(@.name='cpu.idle.percent')].value * 100 resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.idle.percent')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.idle.percent')].source - name: 'compute.node.cpu.user.percent' event_type: 'compute.metrics.update' type: 'gauge' unit: 'percent' volume: $.payload.metrics[?(@.name='cpu.user.percent')].value * 100 resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.user.percent')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.user.percent')].source - name: 'compute.node.cpu.iowait.percent' event_type: 'compute.metrics.update' type: 'gauge' unit: 'percent' volume: $.payload.metrics[?(@.name='cpu.iowait.percent')].value * 100 resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.iowait.percent')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.iowait.percent')].source - name: 'compute.node.cpu.percent' event_type: 'compute.metrics.update' type: 'gauge' unit: 'percent' volume: $.payload.metrics[?(@.name='cpu.percent')].value * 100 resource_id: $.payload.host + "_" + $.payload.nodename timestamp: $.payload.metrics[?(@.name='cpu.percent')].timestamp metadata: event_type: $.event_type host: $.publisher_id source: $.payload.metrics[?(@.name='cpu.percent')].source - name: $.payload.outcome - $.payload.outcome + 'identity.authenticate.' + $.payload.outcome type: 'delta' unit: 'user' volume: 1 event_type: - 'identity.authenticate' resource_id: $.payload.initiator.id user_id: $.payload.initiator.id - name: 'dns.domain.exists' event_type: 'dns.domain.exists' type: 'cumulative' unit: 's' volume: fields: [$.payload.audit_period_beginning, $.payload.audit_period_ending] plugin: 'timedelta' project_id: $.payload.tenant_id resource_id: $.payload.id user_id: $._context_user metadata: status: $.payload.status pool_id: $.payload.pool_id host: $.publisher_id - name: 'trove.instance.exists' event_type: 'trove.instance.exists' type: 'cumulative' unit: 's' volume: fields: [$.payload.audit_period_beginning, $.payload.audit_period_ending] plugin: 'timedelta' project_id: $.payload.tenant_id resource_id: $.payload.instance_id user_id: $.payload.user_id metadata: nova_instance_id: $.payload.nova_instance_id state: $.payload.state service_id: $.payload.service_id instance_type: $.payload.instance_type instance_type_id: $.payload.instance_type_id polling: sources: - name: all_pollsters interval: 600 meters: - "*" pipeline: sinks: - name: meter_sink publishers: - notifier:// - gnocchi:// sources: - meters: - "*" name: meter_source sinks: - meter_sink dependencies: dynamic: common: local_image_registry: jobs: - ceilometer-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - ceilometer-db-sync - ceilometer-rabbit-init - ceilometer-ks-user - ceilometer-ks-endpoints services: - endpoint: internal service: identity - endpoint: internal service: metric central: jobs: - ceilometer-db-sync - ceilometer-rabbit-init - ceilometer-ks-user - ceilometer-ks-endpoints services: - endpoint: internal service: identity - endpoint: internal service: oslo_db - endpoint: internal service: metric ipmi: jobs: - ceilometer-db-sync - ceilometer-rabbit-init - ceilometer-ks-user - ceilometer-ks-endpoints services: - endpoint: internal service: identity - endpoint: internal service: oslo_db - endpoint: internal service: metric compute: jobs: - ceilometer-db-sync - ceilometer-rabbit-init - ceilometer-ks-user - ceilometer-ks-endpoints services: - endpoint: internal service: identity - endpoint: internal service: oslo_db - endpoint: internal service: metric db_sync: services: - endpoint: internal service: metric ks_user: services: - endpoint: internal service: identity rabbit_init: services: - service: oslo_messaging endpoint: internal notification: jobs: - ceilometer-db-sync - ceilometer-rabbit-init - ceilometer-ks-user - ceilometer-ks-endpoints services: - endpoint: internal service: identity - endpoint: internal service: oslo_db - endpoint: internal service: metric tests: services: - endpoint: internal service: identity - endpoint: internal service: metering - endpoint: internal service: metric image_repo_sync: services: - endpoint: internal service: local_image_registry # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: ceilometer-keystone-admin ceilometer: ceilometer-keystone-user test: ceilometer-keystone-test oslo_messaging: admin: ceilometer-rabbitmq-admin ceilometer: ceilometer-rabbitmq-user oci_image_registry: ceilometer: ceilometer-oci-image-registry bootstrap: enabled: false ks_user: ceilometer script: | openstack token issue # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ceilometer: username: ceilometer password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default ceilometer: role: admin region_name: RegionOne username: ceilometer password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: ceilometer-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 metric: name: gnocchi hosts: default: gnocchi-api public: gnocchi host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 8041 public: 80 alarming: name: aodh hosts: default: aodh-api public: aodh host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 8042 public: 80 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 oslo_messaging: auth: admin: username: rabbitmq password: password ceilometer: username: ceilometer password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /ceilometer scheme: rabbit port: amqp: default: 5672 http: default: 15672 pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: ceilometer: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: ceilometer_tests: init_container: null ceilometer_tests: volumeMounts: volumes: ceilometer_compute: init_container: null ceilometer_compute: volumeMounts: volumes: ceilometer_central: init_container: null ceilometer_central: volumeMounts: volumes: ceilometer_ipmi: init_container: null ceilometer_ipmi: volumeMounts: volumes: ceilometer_notification: init_container: null ceilometer_notification: volumeMounts: volumes: ceilometer_db_sync: ceilometer_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/ceilometer/ceilometer.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: ceilometer_compute: [] ceilometer_central: [] ceilometer_ipmi: [] ceilometer_notification: [] ceilometer_db_sync: [] replicas: central: 1 notification: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 daemonsets: pod_replacement_strategy: RollingUpdate compute: enabled: true min_ready_seconds: 0 max_unavailable: 1 resources: enabled: true compute: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" notification: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" central: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ipmi: requests: memory: "124Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" manifests: configmap_bin: true configmap_etc: true deployment_central: true daemonset_compute: true daemonset_ipmi: false deployment_notification: true job_bootstrap: true job_db_sync: true job_image_repo_sync: true job_ks_user: true job_rabbit_init: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_api: true service_ingress_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ceph-adapter-rook/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Ceph Adapter Rook name: ceph-adapter-rook version: 2025.2.0 home: https://github.com/ceph/ceph dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ceph-adapter-rook/README.md ================================================ # Summary This is the minimal set of templates necessary to make the rest of Openstack-Helm charts work with Ceph clusters managed by the Rook operator. Rook operator not only deploys Ceph clusters but also provides convenience when interfacing with those clusters via CRDs which can be used for managing pools/keys/users etc. However Openstack-Helm charts do not utilize Rook CRDs but instead manage Ceph assets like pools/keyrings/users/buckets etc. by means of running bootstrap scripts. Before using Openstack-Helm charts we have to provision a minimal set of assets like Ceph admin key and Ceph client config. # Usage ``` helm upgrade --install ceph-adapter-rook ./ceph-adapter-rook \ --namespace=openstack ``` Once all the jobs are finished you can deploy other Openstack-Helm charts. ================================================ FILE: ceph-adapter-rook/templates/bin/_config-manager.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- $envAll := . }} ENDPOINTS=$(kubectl --namespace ${CEPH_CLUSTER_NAMESPACE} get configmap rook-ceph-mon-endpoints -o jsonpath='{.data.data}' | sed 's/.=//g') kubectl get cm ${CEPH_CONF_ETC} -n ${DEPLOYMENT_NAMESPACE} -o yaml | \ sed "s#mon_host.*#mon_host = ${ENDPOINTS}#g" | \ kubectl apply -f - kubectl get cm ${CEPH_CONF_ETC} -n ${DEPLOYMENT_NAMESPACE} -o yaml ================================================ FILE: ceph-adapter-rook/templates/bin/_key-manager.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- $envAll := . }} # We expect rook-ceph-tools pod to be up and running ROOK_CEPH_TOOLS_POD=$(kubectl -n ${CEPH_CLUSTER_NAMESPACE} get pods --no-headers | awk '/rook-ceph-tools/{print $1}') CEPH_ADMIN_KEY=$(kubectl -n ${CEPH_CLUSTER_NAMESPACE} exec ${ROOK_CEPH_TOOLS_POD} -- ceph auth ls | grep -A1 "client.admin" | awk '/key:/{print $2}') ceph_activate_namespace() { kube_namespace=$1 secret_type=$2 secret_name=$3 ceph_key=$4 { cat <= 0.1.0" ... ================================================ FILE: ceph-client/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: ceph-client/templates/bin/_helm-tests.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex function check_cluster_status() { echo "#### Start: Checking Ceph cluster status ####" ceph_status_output=$(ceph -s -f json | jq -r '.health') ceph_health_status=$(echo $ceph_status_output | jq -r '.status') if [ "x${ceph_health_status}" == "xHEALTH_OK" ]; then echo "Ceph status is HEALTH_OK" else echo "Ceph cluster status is not HEALTH_OK, checking PG states" pg_validation fi } function check_recovery_flags() { echo "### Start: Checking for flags that will prevent recovery" # Ensure there are no flags set that will prevent recovery of degraded PGs if [[ $(ceph osd stat | grep "norecover\|nobackfill\|norebalance") ]]; then ceph osd stat echo "Flags are set that prevent recovery of degraded PGs" exit 1 fi } function check_osd_count() { echo "#### Start: Checking OSD count ####" noup_flag=$(ceph osd stat | awk '/noup/ {print $2}') osd_stat=$(ceph osd stat -f json-pretty) num_osd=$(awk '/"num_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) num_in_osds=$(awk '/"num_in_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) num_up_osds=$(awk '/"num_up_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) MIN_OSDS=$((${num_osd}*$REQUIRED_PERCENT_OF_OSDS/100)) if [ ${MIN_OSDS} -lt 1 ]; then MIN_OSDS=1 fi if [ "${noup_flag}" ]; then osd_status=$(ceph osd dump -f json | jq -c '.osds[] | .state') count=0 for osd in $osd_status; do if [[ "$osd" == *"up"* || "$osd" == *"new"* ]]; then ((count=count+1)) fi done echo "Caution: noup flag is set. ${count} OSDs in up/new state. Required number of OSDs: ${MIN_OSDS}." if [ $MIN_OSDS -gt $count ]; then exit 1 fi else if [ "${num_osd}" -eq 0 ]; then echo "There are no osds in the cluster" exit 1 elif [ "${num_in_osds}" -ge "${MIN_OSDS}" ] && [ "${num_up_osds}" -ge "${MIN_OSDS}" ]; then echo "Required number of OSDs (${MIN_OSDS}) are UP and IN status" else echo "Required number of OSDs (${MIN_OSDS}) are NOT UP and IN status. Cluster shows OSD count=${num_osd}, UP=${num_up_osds}, IN=${num_in_osds}" exit 1 fi fi } function check_failure_domain_count_per_pool() { echo "#### Start: Checking failure domain count per pool ####" pools=$(ceph osd pool ls) for pool in ${pools} do crush_rule=$(ceph osd pool get ${pool} crush_rule | awk '{print $2}') bucket_type=$(ceph osd crush rule dump ${crush_rule} | grep '"type":' | awk -F'"' 'NR==2 {print $4}') num_failure_domains=$(ceph osd tree | grep ${bucket_type} | wc -l) pool_replica_size=$(ceph osd pool get ${pool} size | awk '{print $2}') if [[ ${num_failure_domains} -ge ${pool_replica_size} ]]; then echo "--> Info: Pool ${pool} is configured with enough failure domains ${num_failure_domains} to satisfy pool replica size ${pool_replica_size}" else echo "--> Error : Pool ${pool} is NOT configured with enough failure domains ${num_failure_domains} to satisfy pool replica size ${pool_replica_size}" exit 1 fi done } function mgr_validation() { echo "#### Start: MGR validation ####" mgr_dump=$(ceph mgr dump -f json-pretty) echo "Checking for ${MGR_COUNT} MGRs" mgr_avl=$(echo ${mgr_dump} | jq -r '.["available"]') if [ "x${mgr_avl}" == "xtrue" ]; then mgr_active=$(echo ${mgr_dump} | jq -r '.["active_name"]') echo "Out of ${MGR_COUNT}, 1 MGR is active" # Now lets check for standby managers mgr_stdby_count=$(echo ${mgr_dump} | jq -r '.["standbys"]' | jq length) #Total MGR Count - 1 Active = Expected MGRs expected_standbys=$(( MGR_COUNT -1 )) if [ $mgr_stdby_count -eq $expected_standbys ] then echo "Cluster has 1 Active MGR, $mgr_stdby_count Standbys MGR" else echo "Warning. Cluster Standbys MGR: Expected count= $expected_standbys Available=$mgr_stdby_count" echo "If this is not expected behavior, please investigate and take some additional actions." fi else echo "No Active Manager found, Expected 1 MGR to be active out of ${MGR_COUNT}" retcode=1 fi if [ "x${retcode}" == "x1" ] then exit 1 fi } function pool_validation() { echo "#### Start: Checking Ceph pools ####" echo "From env variables, RBD pool replication count is: ${RBD}" # Assuming all pools have same replication count as RBD # If RBD replication count is greater then 1, POOLMINSIZE should be 1 less then replication count # If RBD replication count is not greate then 1, then POOLMINSIZE should be 1 if [ ${RBD} -gt 1 ]; then EXPECTED_POOLMINSIZE=$[${RBD}-1] else EXPECTED_POOLMINSIZE=1 fi echo "EXPECTED_POOLMINSIZE: ${EXPECTED_POOLMINSIZE}" expectedCrushRuleId="" nrules=$(echo ${OSD_CRUSH_RULE_DUMP} | jq length) c=$[nrules-1] for n in $(seq 0 ${c}) do osd_crush_rule_obj=$(echo ${OSD_CRUSH_RULE_DUMP} | jq -r .[${n}]) name=$(echo ${osd_crush_rule_obj} | jq -r .rule_name) echo "Expected Crushrule: ${EXPECTED_CRUSHRULE}, Pool Crushmap: ${name}" if [ "x${EXPECTED_CRUSHRULE}" == "x${name}" ]; then expectedCrushRuleId=$(echo ${osd_crush_rule_obj} | jq .rule_id) echo "Checking against rule: id: ${expectedCrushRuleId}, name:${name}" else echo "Didn't match" fi done echo "Checking cluster for size:${RBD}, min_size:${EXPECTED_POOLMINSIZE}, crush_rule:${EXPECTED_CRUSHRULE}, crush_rule_id:${expectedCrushRuleId}" npools=$(echo ${OSD_POOLS_DETAILS} | jq length) i=$[npools - 1] for n in $(seq 0 ${i}) do pool_obj=$(echo ${OSD_POOLS_DETAILS} | jq -r ".[${n}]") size=$(echo ${pool_obj} | jq -r .size) min_size=$(echo ${pool_obj} | jq -r .min_size) pg_num=$(echo ${pool_obj} | jq -r .pg_num) pg_placement_num=$(echo ${pool_obj} | jq -r .pg_placement_num) crush_rule=$(echo ${pool_obj} | jq -r .crush_rule) name=$(echo ${pool_obj} | jq -r .pool_name) pg_autoscale_mode=$(echo ${pool_obj} | jq -r .pg_autoscale_mode) if [[ "${ENABLE_AUTOSCALER}" == "true" ]]; then if [[ "${pg_autoscale_mode}" != "on" ]]; then echo "pg autoscaler not enabled on ${name} pool" exit 1 fi fi if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]]; then if [ "x${size}" != "x${RBD}" ] || [ "x${min_size}" != "x${EXPECTED_POOLMINSIZE}" ] \ || [ "x${crush_rule}" != "x${expectedCrushRuleId}" ]; then echo "Pool ${name} has incorrect parameters!!! Size=${size}, Min_Size=${min_size}, Rule=${crush_rule}, PG_Autoscale_Mode=${pg_autoscale_mode}" exit 1 else echo "Pool ${name} seems configured properly. Size=${size}, Min_Size=${min_size}, Rule=${crush_rule}, PG_Autoscale_Mode=${pg_autoscale_mode}" fi else if [ "x${size}" != "x${RBD}" ] || [ "x${min_size}" != "x${EXPECTED_POOLMINSIZE}" ] \ || [ "x${pg_num}" != "x${pg_placement_num}" ] || [ "x${crush_rule}" != "x${expectedCrushRuleId}" ]; then echo "Pool ${name} has incorrect parameters!!! Size=${size}, Min_Size=${min_size}, PG=${pg_num}, PGP=${pg_placement_num}, Rule=${crush_rule}" exit 1 else echo "Pool ${name} seems configured properly. Size=${size}, Min_Size=${min_size}, PG=${pg_num}, PGP=${pg_placement_num}, Rule=${crush_rule}" fi fi done } function pool_failuredomain_validation() { echo "#### Start: Checking Pools are configured with specific failure domain ####" expectedCrushRuleId="" nrules=$(echo ${OSD_CRUSH_RULE_DUMP} | jq length) c=$[nrules-1] for n in $(seq 0 ${c}) do osd_crush_rule_obj=$(echo ${OSD_CRUSH_RULE_DUMP} | jq -r .[${n}]) name=$(echo ${osd_crush_rule_obj} | jq -r .rule_name) if [ "x${EXPECTED_CRUSHRULE}" == "x${name}" ]; then expectedCrushRuleId=$(echo ${osd_crush_rule_obj} | jq .rule_id) echo "Checking against rule: id: ${expectedCrushRuleId}, name:${name}" fi done echo "Checking OSD pools are configured with Crush rule name:${EXPECTED_CRUSHRULE}, id:${expectedCrushRuleId}" npools=$(echo ${OSD_POOLS_DETAILS} | jq length) i=$[npools-1] for p in $(seq 0 ${i}) do pool_obj=$(echo ${OSD_POOLS_DETAILS} | jq -r ".[${p}]") pool_crush_rule_id=$(echo $pool_obj | jq -r .crush_rule) pool_name=$(echo $pool_obj | jq -r .pool_name) if [ "x${pool_crush_rule_id}" == "x${expectedCrushRuleId}" ]; then echo "--> Info: Pool ${pool_name} is configured with the correct rule ${pool_crush_rule_id}" else echo "--> Error : Pool ${pool_name} is NOT configured with the correct rule ${pool_crush_rule_id}" exit 1 fi done } function check_transient_pgs_file() { current_time=$1 pg_failed_list=() # Remove the lines NOT having the word "current" as these are the old # PGs that are no longer in transition. sed -i '/current/!d' ${transient_pgs_file} # For all remaining lines (PGs currently inactive), check for PGs which # are older than the limit. IFS=$'\n' read -d '' -r -a lines < ${transient_pgs_file} || true for pg_data in "${lines[@]}"; do pg=$(echo ${pg_data} | awk '{print $1}') pg_ts=$(echo ${pg_data} | awk '{print $2}') if [[ $((${current_time} - ${pg_ts})) -gt ${pg_inactive_timeout} ]]; then pg_failed_list+=("${pg}") fi done # Remove the current designation for all PGs, as we no longer need it # for this check. sed -i 's/ current//g' ${transient_pgs_file} cat ${transient_pgs_file} if [[ ${#pg_failed_list[@]} -gt 0 ]]; then echo "The following PGs have been in a transient state for longer than ${pg_inactive_timeout} seconds:" echo ${pg_failed_list[*]} exit 1 fi } function update_transient_pgs_file() { pg=$1 current_ts=$2 pg_data=$(grep "${pg} " ${transient_pgs_file} || true) if [[ "${pg_data}" == "" ]]; then echo "${pg} ${current_ts} current" >> ${transient_pgs_file} else # Add the word "current" to the end of the line which has this PG sed -i '/^'"${pg} "'/s/$/ current/' ${transient_pgs_file} fi } function check_transient_pgs() { local -n pg_array=$1 # Use a temporary transient PGs file to track the amount of time PGs # are spending in a transitional state. now=$(date +%s) for pg in "${pg_array[@]}"; do update_transient_pgs_file ${pg} ${now} done check_transient_pgs_file ${now} } function check_pgs() { pgs_transitioning=false ceph --cluster ${CLUSTER} pg dump_stuck inactive -f json-pretty > ${stuck_pgs_file} # Check if there are any stuck PGs, which could indicate a serious problem # if it does not resolve itself soon. stuck_pgs=(`cat ${stuck_pgs_file} | awk -F "\"" '/pgid/{print $4}'`) if [[ ${#stuck_pgs[*]} -gt 0 ]]; then # We have at least one stuck pg echo "Some PGs are stuck: " echo ${stuck_pgs[*]} # Not a critical error - yet pgs_transitioning=true # Check to see if any transitioning PG has been stuck for too long check_transient_pgs stuck_pgs else # Examine the PGs that have non-active states. Consider those PGs that # are in a "premerge" state to be similar to active. "premerge" PGs may # stay in that state for several minutes, and this is considered ok. ceph --cluster ${CLUSTER} pg ls -f json-pretty | grep '"pgid":\|"state":' | grep -v -E "active|premerge" | grep -B1 '"state":' > ${inactive_pgs_file} || true # If the inactive pgs file is non-empty, there are some inactive pgs in the cluster. inactive_pgs=(`cat ${inactive_pgs_file} | awk -F "\"" '/pgid/{print $4}'`) echo "This is the list of inactive pgs in the cluster: " echo ${inactive_pgs[*]} echo "Checking to see if the cluster is rebalancing or recovering some PG's..." # Check for PGs that are down. These are critical errors. down_pgs=(`cat ${inactive_pgs_file} | grep -B1 'down' | awk -F "\"" '/pgid/{print $4}'`) if [[ ${#down_pgs[*]} -gt 0 ]]; then # Some PGs could be down. This is really bad situation and test must fail. echo "Some PGs are down: " echo ${down_pgs[*]} echo "This is critical error, exiting. " exit 1 fi # Check for PGs that are in some transient state due to rebalancing, # peering or backfilling. If we see other states which are not in the # following list of states, then we likely have a problem and need to # exit. transient_states='peer|recover|activating|creating|unknown' non_transient_pgs=(`cat ${inactive_pgs_file} | grep '"state":' | grep -v -E "${transient_states}" || true`) if [[ ${#non_transient_pgs[*]} -gt 0 ]]; then # Some PGs could be inactive and not peering. Better we fail. echo "We don't have down/stuck PGs, but we have some inactive pgs that" echo "are not in the list of allowed transient states: " pg_list=(`sed -n '/peer\|recover\|activating\|creating\|unknown/{s/.*//;x;d;};x;p;${x;p;}' ${inactive_pgs_file} | sed '/^$/d' | awk -F "\"" '/pgid/{print $4}'`) echo ${pg_list[*]} echo ${non_transient_pgs[*]} # Critical error. Fail/exit the script exit 1 fi # Check and note which PGs are in a transient state. This script # will allow these transient states for a period of time # (time_between_retries * max_retries seconds). transient_pgs=(`cat ${inactive_pgs_file} | grep -B1 -E "${transient_states}" | awk -F "\"" '/pgid/{print $4}'`) if [[ ${#transient_pgs[*]} -gt 0 ]]; then # Some PGs are not in an active state but peering and/or cluster is recovering echo "Some PGs are peering and/or cluster is recovering: " echo ${transient_pgs[*]} echo "This is normal but will wait a while to verify the PGs are not stuck in a transient state." # not critical, just wait pgs_transitioning=true # Check to see if any transitioning PG has been stuck for too long check_transient_pgs transient_pgs fi fi } function pg_validation() { retries=0 time_between_retries=3 max_retries=60 pg_inactive_timeout=30 pgs_transitioning=false stuck_pgs_file=$(mktemp -p /tmp) inactive_pgs_file=$(mktemp -p /tmp) transient_pgs_file=$(mktemp -p /tmp) # Check this over a period of retries. Fail/stop if any critical errors found. while check_pgs && [[ "${pgs_transitioning}" == "true" ]] && [[ retries -lt ${max_retries} ]]; do echo "Sleep for a bit waiting on the pg(s) to become active/unstuck..." sleep ${time_between_retries} ((retries=retries+1)) done # Check if transitioning PGs have gone active after retries have expired if [[ retries -ge ${max_retries} ]]; then ((timeout_sec=${time_between_retries}*${max_retries})) echo "Some PGs have not become active after ${timeout_sec} seconds. Exiting..." # This is ok, as the autoscaler might still be adjusting the PGs. fi } function check_ceph_osd_crush_weight(){ OSDS_WITH_ZERO_WEIGHT=(`ceph --cluster ${CLUSTER} osd df -f json-pretty | awk -F"[, ]*" '/"crush_weight":/{if ($3 == 0) print $3}'`) if [[ ${#OSDS_WITH_ZERO_WEIGHT[*]} -eq 0 ]]; then echo "All OSDs from namespace have crush weight!" else echo "OSDs from namespace have zero crush weight" exit 1 fi } check_osd_count mgr_validation OSD_POOLS_DETAILS=$(ceph osd pool ls detail -f json-pretty) OSD_CRUSH_RULE_DUMP=$(ceph osd crush rule dump -f json-pretty) PG_STAT=$(ceph pg stat -f json-pretty) ceph -s pg_validation pool_validation pool_failuredomain_validation check_failure_domain_count_per_pool check_cluster_status check_recovery_flags check_ceph_osd_crush_weight ================================================ FILE: ceph-client/templates/bin/_init-dirs.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C : "${HOSTNAME:=$(uname -n)}" : "${MGR_NAME:=${HOSTNAME}}" : "${MDS_NAME:=mds-${HOSTNAME}}" : "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" : "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" for keyring in ${OSD_BOOTSTRAP_KEYRING} ${MDS_BOOTSTRAP_KEYRING}; do mkdir -p "$(dirname "$keyring")" done # Let's create the ceph directories for DIRECTORY in mds tmp mgr crash; do mkdir -p "/var/lib/ceph/${DIRECTORY}" done # Create socket directory mkdir -p /run/ceph # Create the MDS directory mkdir -p "/var/lib/ceph/mds/${CLUSTER}-${MDS_NAME}" # Create the MGR directory mkdir -p "/var/lib/ceph/mgr/${CLUSTER}-${MGR_NAME}" # Adjust the owner of all those directories chown -R ceph. /run/ceph/ /var/lib/ceph/* ================================================ FILE: ceph-client/templates/bin/mds/_start.sh.tpl ================================================ #!/bin/bash set -ex export LC_ALL=C : "${HOSTNAME:=$(uname -n)}" : "${CEPHFS_CREATE:=0}" : "${CEPHFS_NAME:=cephfs}" : "${CEPHFS_DATA_POOL:=${CEPHFS_NAME}_data}" : "${CEPHFS_DATA_POOL_PG:=8}" : "${CEPHFS_METADATA_POOL:=${CEPHFS_NAME}_metadata}" : "${CEPHFS_METADATA_POOL_PG:=8}" : "${MDS_NAME:=mds-${HOSTNAME}}" : "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" : "${MDS_KEYRING:=/var/lib/ceph/mds/${CLUSTER}-${MDS_NAME}/keyring}" : "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} if [[ ! -e ${CEPH_CONF}.template ]]; then echo "ERROR- ${CEPH_CONF}.template must exist; get it from your existing mon" exit 1 else ENDPOINT=$(mon_host_from_k8s_ep "${NAMESPACE}" ceph-mon-discovery) if [[ "${ENDPOINT}" == "" ]]; then /bin/sh -c -e "cat ${CEPH_CONF}.template | tee ${CEPH_CONF}" || true else /bin/sh -c -e "cat ${CEPH_CONF}.template | sed 's#mon_host.*#mon_host = ${ENDPOINT}#g' | tee ${CEPH_CONF}" || true fi fi # Check to see if we are a new MDS if [ ! -e "${MDS_KEYRING}" ]; then if [ -e "${ADMIN_KEYRING}" ]; then KEYRING_OPT=(--name client.admin --keyring "${ADMIN_KEYRING}") elif [ -e "${MDS_BOOTSTRAP_KEYRING}" ]; then KEYRING_OPT=(--name client.bootstrap-mds --keyring "${MDS_BOOTSTRAP_KEYRING}") else echo "ERROR- Failed to bootstrap MDS: could not find admin or bootstrap-mds keyring. You can extract it from your current monitor by running 'ceph auth get client.bootstrap-mds -o ${MDS_BOOTSTRAP_KEYRING}" exit 1 fi timeout 10 ceph --cluster "${CLUSTER}" "${KEYRING_OPT[@]}" health || exit 1 # Generate the MDS key ceph --cluster "${CLUSTER}" "${KEYRING_OPT[@]}" auth get-or-create "mds.${MDS_NAME}" osd 'allow rwx' mds 'allow' mon 'allow profile mds' -o "${MDS_KEYRING}" chown ceph. "${MDS_KEYRING}" chmod 600 "${MDS_KEYRING}" fi # NOTE (leseb): having the admin keyring is really a security issue # If we need to bootstrap a MDS we should probably create the following on the monitors # I understand that this handy to do this here # but having the admin key inside every container is a concern # Create the Ceph filesystem, if necessary if [ $CEPHFS_CREATE -eq 1 ]; then if [[ ! -e ${ADMIN_KEYRING} ]]; then echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" exit 1 fi if [[ "$(ceph --cluster "${CLUSTER}" fs ls | grep -c name:.${CEPHFS_NAME},)" -eq 0 ]]; then # Make sure the specified data pool exists if ! ceph --cluster "${CLUSTER}" osd pool stats ${CEPHFS_DATA_POOL} > /dev/null 2>&1; then ceph --cluster "${CLUSTER}" osd pool create ${CEPHFS_DATA_POOL} ${CEPHFS_DATA_POOL_PG} fi # Make sure the specified metadata pool exists if ! ceph --cluster "${CLUSTER}" osd pool stats ${CEPHFS_METADATA_POOL} > /dev/null 2>&1; then ceph --cluster "${CLUSTER}" osd pool create ${CEPHFS_METADATA_POOL} ${CEPHFS_METADATA_POOL_PG} fi ceph --cluster "${CLUSTER}" fs new ${CEPHFS_NAME} ${CEPHFS_METADATA_POOL} ${CEPHFS_DATA_POOL} fi fi # NOTE: prefixing this with exec causes it to die (commit suicide) /usr/bin/ceph-mds \ --cluster "${CLUSTER}" \ --setuser "ceph" \ --setgroup "ceph" \ -d \ -i "${MDS_NAME}" ================================================ FILE: ceph-client/templates/bin/pool/_calc.py.tpl ================================================ #!/usr/bin/python # -*- coding: utf-8 -*- {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} #NOTE(portdirect): this is a simple approximation of https://ceph.com/pgcalc/ import math import sys replication = int(sys.argv[1]) number_of_osds = int(sys.argv[2]) percentage_data = float(sys.argv[3]) target_pgs_per_osd = int(sys.argv[4]) raw_pg_num_opt = target_pgs_per_osd * number_of_osds \ * (math.ceil(percentage_data) / 100.0) / replication raw_pg_num_min = number_of_osds / replication if raw_pg_num_min >= raw_pg_num_opt: raw_pg_num = raw_pg_num_min else: raw_pg_num = raw_pg_num_opt max_pg_num = int(math.pow(2, math.ceil(math.log(raw_pg_num, 2)))) min_pg_num = int(math.pow(2, math.floor(math.log(raw_pg_num, 2)))) if min_pg_num >= (raw_pg_num * 0.75): print(min_pg_num) else: print(max_pg_num) ================================================ FILE: ceph-client/templates/bin/pool/_init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C : "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} if [[ ! -e ${CEPH_CONF}.template ]]; then echo "ERROR- ${CEPH_CONF}.template must exist; get it from your existing mon" exit 1 else ENDPOINT=$(mon_host_from_k8s_ep "${NAMESPACE}" ceph-mon-discovery) if [[ "${ENDPOINT}" == "" ]]; then /bin/sh -c -e "cat ${CEPH_CONF}.template | tee ${CEPH_CONF}" || true else /bin/sh -c -e "cat ${CEPH_CONF}.template | sed 's#mon_host.*#mon_host = ${ENDPOINT}#g' | tee ${CEPH_CONF}" || true fi fi if [[ ! -e ${ADMIN_KEYRING} ]]; then echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" exit 1 fi function wait_for_pid() { tail --pid=$1 -f /dev/null } function wait_for_pgs () { echo "#### Start: Checking pgs ####" pgs_ready=0 query='map({state: .state}) | group_by(.state) | map({state: .[0].state, count: length}) | .[] | select(.state | contains("active") or contains("premerge") | not)' if [[ $(ceph mon versions | awk '/version/{print $3}' | sort -n | head -n 1 | cut -d. -f1) -ge 14 ]]; then query=".pg_stats | ${query}" fi # Loop until all pgs are active while [[ $pgs_ready -lt 3 ]]; do pgs_state=$(ceph --cluster ${CLUSTER} pg ls -f json | jq -c "${query}") if [[ $(jq -c '. | select(.state | contains("peer") or contains("activating") or contains("recover") or contains("unknown") or contains("creating") | not)' <<< "${pgs_state}") ]]; then # If inactive PGs aren't in the allowed set of states above, fail echo "Failure, found inactive PGs that aren't in the allowed set of states" exit 1 fi if [[ "${pgs_state}" ]]; then pgs_ready=0 else (( pgs_ready+=1 )) fi sleep 3 done } function check_recovery_flags () { echo "### Start: Checking for flags that will prevent recovery" # Ensure there are no flags set that will prevent recovery of degraded PGs if [[ $(ceph osd stat | grep "norecover\|nobackfill\|norebalance") ]]; then ceph osd stat echo "Flags are set that prevent recovery of degraded PGs" exit 1 fi } function check_osd_count() { echo "#### Start: Checking OSD count ####" noup_flag=$(ceph osd stat | awk '/noup/ {print $2}') osd_stat=$(ceph osd stat -f json-pretty) num_osd=$(awk '/"num_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) num_in_osds=$(awk '/"num_in_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) num_up_osds=$(awk '/"num_up_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) EXPECTED_OSDS={{.Values.conf.pool.target.osd}} EXPECTED_FINAL_OSDS={{.Values.conf.pool.target.final_osd}} REQUIRED_PERCENT_OF_OSDS={{.Values.conf.pool.target.required_percent_of_osds}} if [ ${num_up_osds} -gt ${EXPECTED_FINAL_OSDS} ]; then echo "More running OSDs (${num_up_osds}) than expected (${EXPECTED_FINAL_OSDS}). Please correct the expected value (.Values.conf.pool.target.final_osd)." exit 1 fi MIN_OSDS=$(($EXPECTED_OSDS*$REQUIRED_PERCENT_OF_OSDS/100)) if [ ${MIN_OSDS} -lt 1 ]; then MIN_OSDS=1 fi if [ "${noup_flag}" ]; then osd_status=$(ceph osd dump -f json | jq -c '.osds[] | .state') count=0 for osd in $osd_status; do if [[ "$osd" == *"up"* || "$osd" == *"new"* ]]; then ((count=count+1)) fi done echo "Caution: noup flag is set. ${count} OSDs in up/new state. Required number of OSDs: ${MIN_OSDS}." if [ $MIN_OSDS -gt $count ]; then exit 1 fi else if [ "${num_osd}" -eq 0 ]; then echo "There are no osds in the cluster" exit 1 elif [ "${num_in_osds}" -ge "${MIN_OSDS}" ] && [ "${num_up_osds}" -ge "${MIN_OSDS}" ]; then echo "Required number of OSDs (${MIN_OSDS}) are UP and IN status" else echo "Required number of OSDs (${MIN_OSDS}) are NOT UP and IN status. Cluster shows OSD count=${num_osd}, UP=${num_up_osds}, IN=${num_in_osds}" exit 1 fi fi } function create_crushrule () { CRUSH_NAME=$1 CRUSH_RULE=$2 CRUSH_FAILURE_DOMAIN=$3 CRUSH_DEVICE_CLASS=$4 if ! ceph --cluster "${CLUSTER}" osd crush rule ls | grep -q "^\$CRUSH_NAME$"; then ceph --cluster "${CLUSTER}" osd crush rule $CRUSH_RULE $CRUSH_NAME default $CRUSH_FAILURE_DOMAIN $CRUSH_DEVICE_CLASS || true fi } # Set mons to use the msgr2 protocol on nautilus if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]]; then ceph --cluster "${CLUSTER}" mon enable-msgr2 fi check_osd_count {{- range $crush_rule := .Values.conf.pool.crush_rules -}} {{- with $crush_rule }} create_crushrule {{ .name }} {{ .crush_rule }} {{ .failure_domain }} {{ .device_class }} {{- end }} {{- end }} function reweight_osds () { OSD_DF_OUTPUT=$(ceph --cluster "${CLUSTER}" osd df --format json-pretty) for OSD_ID in $(ceph --cluster "${CLUSTER}" osd ls); do OSD_EXPECTED_WEIGHT=$(echo "${OSD_DF_OUTPUT}" | grep -A7 "\bosd.${OSD_ID}\b" | awk '/"kb"/{ gsub(",",""); d= $2/1073741824 ; r = sprintf("%.2f", d); print r }'); OSD_WEIGHT=$(echo "${OSD_DF_OUTPUT}" | grep -A3 "\bosd.${OSD_ID}\b" | awk '/crush_weight/{print $2}' | cut -d',' -f1) if [[ "${OSD_EXPECTED_WEIGHT}" != "0.00" ]] && [[ "${OSD_WEIGHT}" != "${OSD_EXPECTED_WEIGHT}" ]]; then ceph --cluster "${CLUSTER}" osd crush reweight osd.${OSD_ID} ${OSD_EXPECTED_WEIGHT}; fi done } function enable_autoscaling () { CEPH_MAJOR_VERSION=$(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) if [[ ${CEPH_MAJOR_VERSION} -ge 16 ]]; then # Pacific introduced the noautoscale flag to make this simpler ceph osd pool unset noautoscale else if [[ ${CEPH_MAJOR_VERSION} -eq 14 ]]; then ceph mgr module enable pg_autoscaler # only required for nautilus fi ceph config set global osd_pool_default_pg_autoscale_mode on fi } function disable_autoscaling () { CEPH_MAJOR_VERSION=$(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) if [[ ${CEPH_MAJOR_VERSION} -ge 16 ]]; then # Pacific introduced the noautoscale flag to make this simpler ceph osd pool set noautoscale else if [[ ${CEPH_MAJOR_VERSION} -eq 14 ]]; then ceph mgr module disable pg_autoscaler # only required for nautilus fi ceph config set global osd_pool_default_pg_autoscale_mode off fi } function set_cluster_flags () { if [[ -n "${CLUSTER_SET_FLAGS}" ]]; then for flag in ${CLUSTER_SET_FLAGS}; do ceph osd set ${flag} done fi } function unset_cluster_flags () { if [[ -n "${CLUSTER_UNSET_FLAGS}" ]]; then for flag in ${CLUSTER_UNSET_FLAGS}; do ceph osd unset ${flag} done fi } function run_cluster_commands () { {{- range .Values.conf.features.cluster_commands }} ceph --cluster "${CLUSTER}" {{ . }} {{- end }} } # Helper function to set pool properties only if the target value differs from # the current value to optimize performance function set_pool_property() { POOL_NAME=$1 PROPERTY_NAME=$2 CURRENT_PROPERTY_VALUE=$3 TARGET_PROPERTY_VALUE=$4 REALLY_MEAN_IT="" if [[ "${PROPERTY_NAME}" == "size" ]]; then REALLY_MEAN_IT="--yes-i-really-mean-it" fi if [[ "${CURRENT_PROPERTY_VALUE}" != "${TARGET_PROPERTY_VALUE}" ]]; then ceph --cluster "${CLUSTER}" osd pool set "${POOL_NAME}" "${PROPERTY_NAME}" "${TARGET_PROPERTY_VALUE}" ${REALLY_MEAN_IT} fi echo "${TARGET_PROPERTY_VALUE}" } function create_pool () { POOL_APPLICATION=$1 POOL_NAME=$2 POOL_REPLICATION=$3 POOL_PLACEMENT_GROUPS=$4 POOL_CRUSH_RULE=$5 POOL_PROTECTION=$6 PG_NUM_MIN=$7 if ! ceph --cluster "${CLUSTER}" osd pool stats "${POOL_NAME}" > /dev/null 2>&1; then if [[ ${POOL_PLACEMENT_GROUPS} -gt 0 ]]; then ceph --cluster "${CLUSTER}" osd pool create "${POOL_NAME}" ${POOL_PLACEMENT_GROUPS} else ceph --cluster "${CLUSTER}" osd pool create "${POOL_NAME}" ${PG_NUM_MIN} --pg-num-min ${PG_NUM_MIN} fi while [ $(ceph --cluster "${CLUSTER}" -s | grep creating -c) -gt 0 ]; do echo -n .;sleep 1; done ceph --cluster "${CLUSTER}" osd pool application enable "${POOL_NAME}" "${POOL_APPLICATION}" fi # 'tr' and 'awk' are needed here to strip off text that is echoed before the JSON string. # In some cases, errors/warnings are written to stdout and the JSON doesn't parse correctly. pool_values=$(ceph --cluster "${CLUSTER}" osd pool get "${POOL_NAME}" all -f json | tr -d '\n' | awk -F{ '{print "{" $2}') if [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]]; then if [[ "${ENABLE_AUTOSCALER}" == "true" ]]; then pg_num=$(jq -r '.pg_num' <<< "${pool_values}") pgp_num=$(jq -r '.pgp_num' <<< "${pool_values}") pg_num_min=$(jq -r '.pg_num_min' <<< "${pool_values}") pg_autoscale_mode=$(jq -r '.pg_autoscale_mode' <<< "${pool_values}") # set pg_num_min to PG_NUM_MIN before enabling autoscaler if [[ ${pg_num} -lt ${PG_NUM_MIN} ]]; then pg_autoscale_mode=$(set_pool_property "${POOL_NAME}" pg_autoscale_mode "${pg_autoscale_mode}" "off") pg_num=$(set_pool_property "${POOL_NAME}" pg_num "${pg_num}" "${PG_NUM_MIN}") pgp_num=$(set_pool_property "${POOL_NAME}" pgp_num "${pgp_num}" "${PG_NUM_MIN}") fi pg_num_min=$(set_pool_property "${POOL_NAME}" pg_num_min "${pg_num_min}" "${PG_NUM_MIN}") pg_autoscale_mode=$(set_pool_property "${POOL_NAME}" pg_autoscale_mode "${pg_autoscale_mode}" "on") else pg_autoscale_mode=$(set_pool_property "${POOL_NAME}" pg_autoscale_mode "${pg_autoscale_mode}" "off") fi fi # # Make sure pool is not protected after creation AND expansion so we can manipulate its settings. # Final protection settings are applied once parameters (size, pg) have been adjusted. # nosizechange=$(jq -r '.nosizechange' <<< "${pool_values}") nopschange=$(jq -r '.nopschange' <<< "${pool_values}") nodelete=$(jq -r '.nodelete' <<< "${pool_values}") size=$(jq -r '.size' <<< "${pool_values}") crush_rule=$(jq -r '.crush_rule' <<< "${pool_values}") nosizechange=$(set_pool_property "${POOL_NAME}" nosizechange "${nosizechange}" "false") nopgchange=$(set_pool_property "${POOL_NAME}" nopgchange "${nopgchange}" "false") nodelete=$(set_pool_property "${POOL_NAME}" nodelete "${nodelete}" "false") size=$(set_pool_property "${POOL_NAME}" size "${size}" "${POOL_REPLICATION}") crush_rule=$(set_pool_property "${POOL_NAME}" crush_rule "${crush_rule}" "${POOL_CRUSH_RULE}") # set pg_num to pool if [[ ${POOL_PLACEMENT_GROUPS} -gt 0 ]]; then pg_num=$(jq -r ".pg_num" <<< "${pool_values}") pgp_num=$(jq -r ".pgp_num" <<< "${pool_values}") pg_num=$(set_pool_property "${POOL_NAME}" pg_num "${pg_num}" "${POOL_PLACEMENT_GROUPS}") pgp_num=$(set_pool_property "${POOL_NAME}" pgp_num "${pgp_num}" "${POOL_PLACEMENT_GROUPS}") fi #This is to handle cluster expansion case where replication may change from intilization if [ ${POOL_REPLICATION} -gt 1 ]; then min_size=$(jq -r '.min_size' <<< "${pool_values}") EXPECTED_POOLMINSIZE=$[${POOL_REPLICATION}-1] min_size=$(set_pool_property "${POOL_NAME}" min_size "${min_size}" "${EXPECTED_POOLMINSIZE}") fi # # Handling of .Values.conf.pool.target.protected: # Possible settings # - true | 1 = Protect the pools after they get created # - false | 0 = Do not protect the pools once they get created and let Ceph defaults apply # - Absent = Do not protect the pools once they get created and let Ceph defaults apply # # If protection is not requested through values.yaml, just use the Ceph defaults. With Luminous we do not # apply any protection to the pools when they get created. # # Note: If the /etc/ceph/ceph.conf file modifies the defaults the deployment will fail on pool creation # - nosizechange = Do not allow size and min_size changes on the pool # - nodelete = Do not allow deletion of the pool # if [ "x${POOL_PROTECTION}" == "xtrue" ] || [ "x${POOL_PROTECTION}" == "x1" ]; then nosizechange=$(set_pool_property "${POOL_NAME}" nosizechange "${nosizechange}" "true") nodelete=$(set_pool_property "${POOL_NAME}" nodelete "${nodelete}" "true") fi } function manage_pool () { POOL_APPLICATION=$1 POOL_NAME=$2 POOL_REPLICATION=$3 TOTAL_DATA_PERCENT=$4 TARGET_PG_PER_OSD=$5 POOL_CRUSH_RULE=$6 POOL_QUOTA=$7 POOL_PROTECTION=$8 CLUSTER_CAPACITY=$9 POOL_PG_NUM_MIN=${10} TOTAL_OSDS={{.Values.conf.pool.target.osd}} POOL_PLACEMENT_GROUPS=0 if [[ -n "${TOTAL_DATA_PERCENT}" ]]; then if [[ "${ENABLE_AUTOSCALER}" == "false" ]] || [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -lt 14 ]]; then POOL_PLACEMENT_GROUPS=$(python3 /tmp/pool-calc.py ${POOL_REPLICATION} ${TOTAL_OSDS} ${TOTAL_DATA_PERCENT} ${TARGET_PG_PER_OSD}) fi fi create_pool "${POOL_APPLICATION}" "${POOL_NAME}" "${POOL_REPLICATION}" "${POOL_PLACEMENT_GROUPS}" "${POOL_CRUSH_RULE}" "${POOL_PROTECTION}" "${POOL_PG_NUM_MIN}" ceph --cluster "${CLUSTER}" osd pool set-quota "${POOL_NAME}" max_bytes $POOL_QUOTA } # Helper to convert TiB, TB, GiB, GB, MiB, MB, KiB, KB, or bytes to bytes function convert_to_bytes() { value=${1} value="$(echo "${value}" | sed 's/TiB/ \* 1024GiB/g')" value="$(echo "${value}" | sed 's/TB/ \* 1000GB/g')" value="$(echo "${value}" | sed 's/GiB/ \* 1024MiB/g')" value="$(echo "${value}" | sed 's/GB/ \* 1000MB/g')" value="$(echo "${value}" | sed 's/MiB/ \* 1024KiB/g')" value="$(echo "${value}" | sed 's/MB/ \* 1000KB/g')" value="$(echo "${value}" | sed 's/KiB/ \* 1024/g')" value="$(echo "${value}" | sed 's/KB/ \* 1000/g')" python3 -c "print(int(${value}))" } set_cluster_flags unset_cluster_flags run_cluster_commands reweight_osds {{ $targetOSDCount := .Values.conf.pool.target.osd }} {{ $targetFinalOSDCount := .Values.conf.pool.target.final_osd }} {{ $targetPGperOSD := .Values.conf.pool.target.pg_per_osd }} {{ $crushRuleDefault := .Values.conf.pool.default.crush_rule }} {{ $targetQuota := .Values.conf.pool.target.quota | default 100 }} {{ $targetProtection := .Values.conf.pool.target.protected | default "false" | quote | lower }} {{ $targetPGNumMin := .Values.conf.pool.target.pg_num_min }} cluster_capacity=$(ceph --cluster "${CLUSTER}" df -f json-pretty | grep '"total_bytes":' | head -n1 | awk '{print $2}' | tr -d ',') # Check to make sure pool quotas don't exceed the expected cluster capacity in its final state target_quota=$(python3 -c "print(int(${cluster_capacity} * {{ $targetFinalOSDCount }} / {{ $targetOSDCount }} * {{ $targetQuota }} / 100))") quota_sum=0 {{- range $pool := .Values.conf.pool.spec -}} {{- with $pool }} # Read the pool quota from the pool spec (no quota if absent) # Set pool_quota to 0 if target_quota is 0 [[ ${target_quota} -eq 0 ]] && pool_quota=0 || pool_quota="$(convert_to_bytes {{ .pool_quota | default 0 }})" quota_sum=$(python3 -c "print(int(${quota_sum} + (${pool_quota} * {{ .replication }})))") {{- end }} {{- end }} if [[ ${quota_sum} -gt ${target_quota} ]]; then echo "The sum of all pool quotas exceeds the target quota for the cluster" exit 1 fi if [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]] && [[ "${ENABLE_AUTOSCALER}" != "true" ]]; then disable_autoscaling fi # Track the manage_pool() PIDs in an array so we can wait for them to finish MANAGE_POOL_PIDS=() {{- range $pool := .Values.conf.pool.spec -}} {{- with $pool }} pool_name="{{ .name }}" {{- if .rename }} # If a renamed pool exists, that name should be used for idempotence if [[ -n "$(ceph --cluster ${CLUSTER} osd pool ls | grep ^{{ .rename }}$)" ]]; then pool_name="{{ .rename }}" fi {{- end }} # Read the pool quota from the pool spec (no quota if absent) # Set pool_quota to 0 if target_quota is 0 [[ ${target_quota} -eq 0 ]] && pool_quota=0 || pool_quota="$(convert_to_bytes {{ .pool_quota | default 0 }})" pool_crush_rule="{{ $crushRuleDefault }}" {{- if .crush_rule }} pool_crush_rule="{{ .crush_rule }}" {{- end }} pool_pg_num_min={{ $targetPGNumMin }} {{- if .pg_num_min }} pool_pg_num_min={{ .pg_num_min }} {{- end }} manage_pool {{ .application }} ${pool_name} {{ .replication }} {{ .percent_total_data }} {{ $targetPGperOSD }} $pool_crush_rule $pool_quota {{ $targetProtection }} ${cluster_capacity} ${pool_pg_num_min} & MANAGE_POOL_PID=$! MANAGE_POOL_PIDS+=( $MANAGE_POOL_PID ) {{- if .rename }} # Wait for manage_pool() to finish for this pool before trying to rename the pool wait_for_pid $MANAGE_POOL_PID # If a rename value exists, the pool exists, and a pool with the rename value doesn't exist, rename the pool pool_list=$(ceph --cluster ${CLUSTER} osd pool ls) if [[ -n $(grep ^{{ .name }}$ <<< "${pool_list}") ]] && [[ -z $(grep ^{{ .rename }}$ <<< "${pool_list}") ]]; then ceph --cluster "${CLUSTER}" osd pool rename "{{ .name }}" "{{ .rename }}" pool_name="{{ .rename }}" fi {{- end }} {{- if and .delete .delete_all_pool_data }} # Wait for manage_pool() to finish for this pool before trying to delete the pool wait_for_pid $MANAGE_POOL_PID # If delete is set to true and delete_all_pool_data is also true, delete the pool if [[ "true" == "{{ .delete }}" ]] && [[ "true" == "{{ .delete_all_pool_data }}" ]]; then ceph --cluster "${CLUSTER}" tell mon.* injectargs '--mon-allow-pool-delete=true' ceph --cluster "${CLUSTER}" osd pool set "${pool_name}" nodelete false ceph --cluster "${CLUSTER}" osd pool delete "${pool_name}" "${pool_name}" --yes-i-really-really-mean-it ceph --cluster "${CLUSTER}" tell mon.* injectargs '--mon-allow-pool-delete=false' fi {{- end }} {{- end }} {{- end }} # Wait for all manage_pool() instances to finish before proceeding for pool_pid in ${MANAGE_POOL_PIDS[@]}; do wait_for_pid $pool_pid done if [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]] && [[ "${ENABLE_AUTOSCALER}" == "true" ]]; then enable_autoscaling fi {{- if .Values.conf.pool.crush.tunables }} ceph --cluster "${CLUSTER}" osd crush tunables {{ .Values.conf.pool.crush.tunables }} {{- end }} wait_for_pgs check_recovery_flags ================================================ FILE: ceph-client/templates/bin/utils/_checkDNS.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" ENDPOINT="{$1}" function check_mon_dns () { GREP_CMD=$(grep -rl 'ceph-mon' ${CEPH_CONF}) if [[ "${ENDPOINT}" == "{up}" ]]; then echo "If DNS is working, we are good here" elif [[ "${ENDPOINT}" != "" ]]; then if [[ ${GREP_CMD} != "" ]]; then # No DNS, write CEPH MONs IPs into ${CEPH_CONF} sh -c -e "cat ${CEPH_CONF}.template | sed 's/mon_host.*/mon_host = ${ENDPOINT}/g' | tee ${CEPH_CONF}" > /dev/null 2>&1 else echo "endpoints are already cached in ${CEPH_CONF}" exit fi fi } check_mon_dns exit ================================================ FILE: ceph-client/templates/bin/utils/_checkDNS_start.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -xe {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} {{- $rgwNameSpaces := "" }} {{- $sep := "" }} {{- range $_, $ns := .Values.endpoints.ceph_object_store.endpoint_namespaces }} {{- $rgwNameSpaces = printf "%s%s%s" $rgwNameSpaces $sep $ns }} {{- $sep = " " }} {{- end }} rgwNameSpaces={{- printf "\"%s\"" $rgwNameSpaces }} function check_mon_dns { NS=${1} # RGWs and the rgw namespace could not exist. Let's check this and prevent this script from failing if [[ $(kubectl get ns ${NS} -o json | jq -r '.status.phase') == "Active" ]]; then DNS_CHECK=$(getent hosts ceph-mon | head -n1) PODS=$(kubectl get pods --namespace=${NS} --selector=application=ceph --field-selector=status.phase=Running \ --output=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | grep -E 'ceph-mon|ceph-osd|ceph-mgr|ceph-mds|ceph-rgw') ENDPOINT=$(mon_host_from_k8s_ep "${NAMESPACE}" ceph-mon-discovery) if [[ ${PODS} == "" || "${ENDPOINT}" == "" ]]; then echo "Something went wrong, no PODS or ENDPOINTS are available!" elif [[ ${DNS_CHECK} == "" ]]; then for POD in ${PODS}; do kubectl exec -t ${POD} --namespace=${NS} -- \ sh -c -e "/tmp/utils-checkDNS.sh "${ENDPOINT}"" done else for POD in ${PODS}; do kubectl exec -t ${POD} --namespace=${NS} -- \ sh -c -e "/tmp/utils-checkDNS.sh up" done fi else echo "The namespace ${NS} is not ready, yet" fi } function watch_mon_dns { while [ true ]; do echo "checking DNS health" for myNS in ${NAMESPACE} ${rgwNameSpaces}; do check_mon_dns ${myNS} || true done echo "sleep 300 sec" sleep 300 done } watch_mon_dns exit ================================================ FILE: ceph-client/templates/bin/utils/_checkPGs.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex mgrPod=$(kubectl get pods --namespace=${DEPLOYMENT_NAMESPACE} --selector=application=ceph --selector=component=mgr --output=jsonpath={.items[0].metadata.name} 2>/dev/null) kubectl exec -t ${mgrPod} --namespace=${DEPLOYMENT_NAMESPACE} -- python3 /tmp/utils-checkPGs.py All 2>/dev/null ================================================ FILE: ceph-client/templates/bin/utils/_defragOSDs.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex PODS=$(kubectl get pods --namespace=${NAMESPACE} \ --selector=application=ceph,component=osd --field-selector=status.phase=Running \ '--output=jsonpath={range .items[*]}{.metadata.name}{"\n"}{end}') for POD in ${PODS}; do kubectl exec -t ${POD} -c ceph-osd-default --namespace=${NAMESPACE} -- \ sh -c -e "/tmp/utils-defragOSDs.sh" done exit 0 ================================================ FILE: ceph-client/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.configmap_bin .Values.deployment.ceph }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: ceph-client-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} init-dirs.sh: | {{ tuple "bin/_init-dirs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} pool-init.sh: | {{ tuple "bin/pool/_init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} pool-calc.py: | {{ tuple "bin/pool/_calc.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mds-start.sh: | {{ tuple "bin/mds/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} helm-tests.sh: | {{ tuple "bin/_helm-tests.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-checkDNS.sh: | {{ tuple "bin/utils/_checkDNS.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-checkDNS_start.sh: | {{ tuple "bin/utils/_checkDNS_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-checkPGs.sh: | {{ tuple "bin/utils/_checkPGs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-defragOSDs.sh: | {{ tuple "bin/utils/_defragOSDs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: ceph-client/templates/configmap-etc-client.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ceph.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if .Values.deployment.ceph }} {{- if empty .Values.conf.ceph.global.mon_host -}} {{- $monHost := tuple "ceph_mon" "internal" "mon_msgr2" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} {{- $_ := $monHost | set .Values.conf.ceph.global "mon_host" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.cluster_network -}} {{- $_ := .Values.network.cluster | set .Values.conf.ceph.osd "cluster_network" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.public_network -}} {{- $_ := .Values.network.public | set .Values.conf.ceph.osd "public_network" -}} {{- end -}} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapName }} data: ceph.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.ceph | indent 4 }} {{- end }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "ceph-client-etc" . | include "ceph.configmap.etc" }} {{- end }} ================================================ FILE: ceph-client/templates/cronjob-checkPGs.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cronjob_checkPGs }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-pool-checkpgs" }} {{ tuple $envAll "pool_checkpgs" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - pods - pods/exec verbs: - get - list - watch - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: CronJob metadata: name: {{ $serviceAccountName }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "pool-checkpgs" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: schedule: {{ .Values.jobs.pool_checkPGs.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.pool_checkPGs.history.successJob }} failedJobsHistoryLimit: {{ .Values.jobs.pool_checkPGs.history.failJob }} concurrencyPolicy: {{ .Values.jobs.pool_checkPGs.concurrency.execPolicy }} startingDeadlineSeconds: {{ .Values.jobs.pool_checkPGs.startingDeadlineSecs }} jobTemplate: metadata: labels: {{ tuple $envAll "ceph" "pool-checkpgs" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "pool-checkpgs" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.mgr.node_selector_key }}: {{ .Values.labels.mgr.node_selector_value }} initContainers: {{ tuple $envAll "pool_checkpgs" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: {{ $serviceAccountName }} {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 12 }} env: - name: DEPLOYMENT_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace command: - /tmp/utils-checkPGs.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-client-bin mountPath: /tmp/utils-checkPGs.sh subPath: utils-checkPGs.sh readOnly: true - name: ceph-client-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - mountPath: /etc/ceph/ceph.client.admin.keyring name: ceph-client-admin-keyring readOnly: true subPath: ceph.client.admin.keyring - mountPath: /etc/ceph/ceph.mon.keyring.seed name: ceph-mon-keyring readOnly: true subPath: ceph.mon.keyring - mountPath: /var/lib/ceph/bootstrap-osd/ceph.keyring name: ceph-bootstrap-osd-keyring readOnly: true subPath: ceph.keyring - mountPath: /var/lib/ceph/bootstrap-mds/ceph.keyring name: ceph-bootstrap-mds-keyring readOnly: true subPath: ceph.keyring restartPolicy: Never hostNetwork: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-client-bin configMap: name: ceph-client-bin defaultMode: 0555 - name: ceph-client-etc configMap: name: ceph-client-etc defaultMode: 0444 - name: ceph-client-admin-keyring secret: defaultMode: 420 secretName: ceph-client-admin-keyring - name: ceph-mon-keyring secret: defaultMode: 420 secretName: ceph-mon-keyring - name: ceph-bootstrap-osd-keyring secret: defaultMode: 420 secretName: ceph-bootstrap-osd-keyring - name: ceph-bootstrap-mds-keyring secret: defaultMode: 420 secretName: ceph-bootstrap-mds-keyring {{- end }} ================================================ FILE: ceph-client/templates/cronjob-defragosds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cronjob_defragosds }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-defragosds" }} {{ tuple $envAll "ceph_defragosds" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - pods - pods/exec verbs: - get - list - watch - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: CronJob metadata: name: {{ $serviceAccountName }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "ceph-defragosds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: schedule: {{ .Values.jobs.ceph_defragosds.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.ceph_defragosds.history.successJob }} failedJobsHistoryLimit: {{ .Values.jobs.ceph_defragosds.history.failJob }} concurrencyPolicy: {{ .Values.jobs.ceph_defragosds.concurrency.execPolicy }} startingDeadlineSeconds: {{ .Values.jobs.ceph_defragosds.startingDeadlineSecs }} jobTemplate: metadata: labels: {{ tuple $envAll "ceph" "ceph-defragosds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "ceph-defragosds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.mgr.node_selector_key }}: {{ .Values.labels.mgr.node_selector_value }} containers: - name: {{ $serviceAccountName }} {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 12 }} env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: KUBECTL_PARAM value: {{ tuple $envAll "ceph" "ceph-defragosd" | include "helm-toolkit.snippets.kubernetes_kubectl_params" }} command: - /tmp/utils-defragOSDs.sh - cron volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-client-bin mountPath: /tmp/utils-defragOSDs.sh subPath: utils-defragOSDs.sh readOnly: true restartPolicy: Never hostNetwork: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-client-bin configMap: name: ceph-client-bin defaultMode: 0555 {{- end }} ================================================ FILE: ceph-client/templates/deployment-checkdns.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License: is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.deployment_checkdns .Values.deployment.ceph }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-checkdns" }} {{/* We will give different name to the RoleBinding resource (see $cephRoleBindingName variable below). This is neccessary, because the RoleBinding with the default name "ceph-checkdns" exists in the system, and its reference can not be changed. */}} {{- $cephRoleBindingName := "ceph-checkdns-rolebinding" }} {{ tuple $envAll "checkdns" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ printf "%s-%s" $envAll.Release.Name "clusterrole-checkdns" | quote }} rules: - apiGroups: - "" resources: - pods - endpoints - pods/exec - namespaces verbs: - get - list - watch - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ printf "%s-for-%s" $cephRoleBindingName $envAll.Release.Namespace }} namespace: {{ $envAll.Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: {{ printf "%s-%s" $envAll.Release.Name "clusterrole-checkdns" | quote }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- kind: Deployment apiVersion: apps/v1 metadata: name: ceph-checkdns annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} labels: {{ tuple $envAll "ceph" "checkdns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "ceph" "checkdns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "ceph" "checkdns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-checkdns" "containerNames" (list "ceph-checkdns" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "checkdns" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceph" "checkdns" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ tuple $envAll "checkdns" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} nodeSelector: {{ .Values.labels.checkdns.node_selector_key }}: {{ .Values.labels.checkdns.node_selector_value }} initContainers: {{ tuple $envAll "checkdns" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} hostNetwork: true dnsPolicy: {{ .Values.pod.dns_policy }} containers: - name: ceph-checkdns {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.checkdns | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "checkdns" "container" "checkdns" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: K8S_HOST_NETWORK value: "1" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: KUBECTL_PARAM value: {{ tuple $envAll "ceph" "checkdns" | include "helm-toolkit.snippets.kubernetes_kubectl_params" }} command: - /tmp/_start.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ceph-client-bin mountPath: /tmp/_start.sh subPath: utils-checkDNS_start.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: ceph-client-bin configMap: name: ceph-client-bin defaultMode: 0555 {{- end }} ================================================ FILE: ceph-client/templates/deployment-mds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "livenessProbeTemplate" }} tcpSocket: port: 6800 {{- end }} {{- define "readinessProbeTemplate" }} tcpSocket: port: 6800 {{- end }} {{- if and .Values.manifests.deployment_mds ( and .Values.deployment.ceph .Values.conf.features.mds) }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-mds" }} {{ tuple $envAll "mds" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- kind: Deployment apiVersion: apps/v1 metadata: name: ceph-mds annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.mds }} selector: matchLabels: {{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: name: ceph-mds labels: {{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-client-hash: {{ tuple "configmap-etc-client.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "ceph-mds" "containerNames" (list "ceph-mds" "ceph-init-dirs") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "mds" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ tuple $envAll "mds" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} nodeSelector: {{ .Values.labels.mds.node_selector_key }}: {{ .Values.labels.mds.node_selector_value }} initContainers: {{ tuple $envAll "mds" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-init-dirs {{ tuple $envAll "ceph_mds" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "mds" "container" "init_dirs" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/init-dirs.sh env: - name: CLUSTER value: "ceph" volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-client-bin mountPath: /tmp/init-dirs.sh subPath: init-dirs.sh readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false containers: - name: ceph-mds {{ tuple $envAll "ceph_mds" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.mds | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "mds" "container" "mds" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/mds-start.sh env: - name: CLUSTER value: "ceph" - name: CEPHFS_CREATE value: "1" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} ports: - containerPort: 6800 {{ dict "envAll" . "component" "ceph" "container" "ceph-mds" "type" "liveness" "probeTemplate" (include "livenessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} {{ dict "envAll" . "component" "ceph" "container" "ceph-mds" "type" "readiness" "probeTemplate" (include "readinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-client-bin mountPath: /tmp/mds-start.sh subPath: mds-start.sh readOnly: true - name: ceph-client-bin mountPath: /tmp/utils-checkDNS.sh subPath: utils-checkDNS.sh readOnly: true - name: ceph-client-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true - name: ceph-bootstrap-mds-keyring mountPath: /var/lib/ceph/bootstrap-mds/ceph.keyring subPath: ceph.keyring readOnly: false - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: pod-etc-ceph emptyDir: {} - name: ceph-client-etc configMap: name: ceph-client-etc defaultMode: 0444 - name: ceph-client-bin configMap: name: ceph-client-bin defaultMode: 0555 - name: pod-var-lib-ceph emptyDir: {} - name: pod-var-lib-ceph-crash hostPath: path: /var/lib/openstack-helm/ceph/crash type: DirectoryOrCreate - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} - name: ceph-bootstrap-mds-keyring secret: secretName: {{ .Values.secrets.keyrings.mds }} {{- end }} ================================================ FILE: ceph-client/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ceph-client/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-client-bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-client-bootstrap labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-client-bootstrap" "containerNames" (list "ceph-client-bootstrap" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "bootstrap" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-client-bootstrap {{ tuple $envAll "ceph_bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "bootstrap" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ceph-client-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true - name: ceph-client-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-client-bin configMap: name: ceph-client-bin defaultMode: 0555 - name: ceph-client-etc configMap: name: ceph-client-etc defaultMode: 0444 - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} {{- end }} ================================================ FILE: ceph-client/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ceph-client" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: ceph-client/templates/job-rbd-pool.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_rbd_pool .Values.deployment.ceph }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-rbd-pool" }} {{ tuple $envAll "rbd_pool" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-rbd-pool labels: {{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: name: ceph-rbd-pool labels: {{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "ceph-rbd-pool" "containerNames" (list "ceph-rbd-pool" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "rbd_pool" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: {{ $envAll.Values.jobs.rbd_pool.restartPolicy | quote }} affinity: {{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ $envAll.Values.labels.job.node_selector_key }}: {{ $envAll.Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "rbd_pool" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-rbd-pool {{ tuple $envAll "ceph_rbd_pool" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.rbd_pool | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rbd_pool" "container" "rbd_pool" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: ENABLE_AUTOSCALER value: {{ .Values.conf.features.pg_autoscaler | quote }} - name: CLUSTER_SET_FLAGS value: {{ .Values.conf.features.cluster_flags.set | quote }} - name: CLUSTER_UNSET_FLAGS value: {{ .Values.conf.features.cluster_flags.unset | quote }} command: - /tmp/pool-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ceph-client-bin mountPath: /tmp/pool-init.sh subPath: pool-init.sh readOnly: true - name: ceph-client-bin mountPath: /tmp/pool-calc.py subPath: pool-calc.py readOnly: true - name: pod-etc-ceph mountPath: /etc/ceph readOnly: false - name: ceph-client-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-run mountPath: /run readOnly: false volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-client-etc configMap: name: ceph-client-etc defaultMode: 0444 - name: ceph-client-bin configMap: name: ceph-client-bin defaultMode: 0555 - name: pod-var-lib-ceph emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} {{- end }} ================================================ FILE: ceph-client/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.helm_tests }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" $envAll.Release.Name "test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ $serviceAccountName }} labels: {{ tuple $envAll "ceph-client" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ dict "envAll" $envAll "podName" "ceph-client-test" "containerNames" (list "init" "ceph-cluster-helm-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} restartPolicy: Never serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: ceph-cluster-helm-test {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: - name: CLUSTER value: "ceph" - name: CEPH_DEPLOYMENT_NAMESPACE value: {{ .Release.Namespace }} - name: REQUIRED_PERCENT_OF_OSDS value: {{ .Values.conf.pool.target.required_percent_of_osds | ceil | quote }} - name: EXPECTED_CRUSHRULE value: {{ .Values.conf.pool.default.crush_rule | default "replicated_rule" | quote }} - name: MGR_COUNT value: {{ .Values.pod.replicas.mgr | default "1" | quote }} - name: ENABLE_AUTOSCALER value: {{ .Values.conf.features.pg_autoscaler | quote }} {{- range $pool := .Values.conf.pool.spec -}} {{- with $pool }} - name: {{ .name | upper | replace "." "_" }} value: {{ .replication | quote }} {{- end }} {{- end }} command: - /tmp/helm-tests.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ceph-client-bin mountPath: /tmp/helm-tests.sh subPath: helm-tests.sh readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true - name: ceph-client-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: ceph-client-bin configMap: name: ceph-client-bin defaultMode: 0555 - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} - name: ceph-client-etc configMap: name: ceph-client-etc defaultMode: 0444 {{- end }} ================================================ FILE: ceph-client/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: ceph-client/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for ceph-client. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- deployment: ceph: true release_group: null images: pull_policy: IfNotPresent tags: ceph_bootstrap: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_config_helper: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' ceph_mds: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_rbd_pool: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' image_repo_sync: 'quay.io/airshipit/docker:27.5.0' local_registry: active: false exclude: - dep_check - image_repo_sync labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled mgr: node_selector_key: ceph-mgr node_selector_value: enabled mds: node_selector_key: ceph-mds node_selector_value: enabled checkdns: node_selector_key: ceph-mon node_selector_value: enabled pod: security_context: checkdns: pod: runAsUser: 65534 container: checkdns: allowPrivilegeEscalation: false readOnlyRootFilesystem: true mds: pod: runAsUser: 65534 container: init_dirs: runAsUser: 0 readOnlyRootFilesystem: true mds: runAsUser: 64045 readOnlyRootFilesystem: true allowPrivilegeEscalation: false bootstrap: pod: runAsUser: 65534 container: bootstrap: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rbd_pool: pod: runAsUser: 65534 container: rbd_pool: allowPrivilegeEscalation: false readOnlyRootFilesystem: true test: pod: runAsUser: 65534 container: test: allowPrivilegeEscalation: false readOnlyRootFilesystem: true dns_policy: "ClusterFirstWithHostNet" replicas: mds: 2 lifecycle: upgrades: deployments: pod_replacement_strategy: RollingUpdate revision_history: 3 rolling_update: max_surge: 25% max_unavailable: 25% affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 resources: enabled: false mds: requests: memory: "10Mi" cpu: "250m" limits: memory: "50Mi" cpu: "500m" checkdns: requests: memory: "5Mi" cpu: "250m" limits: memory: "50Mi" cpu: "500m" jobs: bootstrap: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rbd_pool: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "10Mi" cpu: "250m" limits: memory: "50Mi" cpu: "500m" tolerations: checkdns: tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 60 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 60 mds: tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 60 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 60 probes: ceph: ceph-mds: readiness: enabled: true params: timeoutSeconds: 5 liveness: enabled: true params: initialDelaySeconds: 60 timeoutSeconds: 5 secrets: keyrings: mon: ceph-mon-keyring mds: ceph-bootstrap-mds-keyring osd: ceph-bootstrap-osd-keyring rgw: ceph-bootstrap-rgw-keyring mgr: ceph-bootstrap-mgr-keyring admin: ceph-client-admin-keyring oci_image_registry: ceph-client: ceph-client-oci-image-registry network: public: 192.168.0.0/16 cluster: 192.168.0.0/16 jobs: ceph_defragosds: # Execute the 1st of each month cron: "0 0 1 * *" history: # Number of successful job to keep successJob: 1 # Number of failed job to keep failJob: 1 concurrency: # Skip new job if previous job still active execPolicy: Forbid startingDeadlineSecs: 60 pool_checkPGs: # Execute every 15 minutes cron: "*/15 * * * *" history: # Number of successful job to keep successJob: 1 # Number of failed job to keep failJob: 1 concurrency: # Skip new job if previous job still active execPolicy: Forbid startingDeadlineSecs: 60 rbd_pool: restartPolicy: OnFailure conf: features: mds: true pg_autoscaler: true cluster_flags: # List of flags to set or unset separated by spaces set: "" unset: "" cluster_commands: # Add additional commands to run against the Ceph cluster here # NOTE: Beginning with Pacific, mon_allow_pool_size_one must be # configured here to allow gate scripts to use 1x replication. # Adding it to /etc/ceph/ceph.conf doesn't seem to be effective. - config set global mon_allow_pool_size_one true - osd require-osd-release tentacle - status pool: # NOTE(portdirect): this drives a simple approximation of # https://ceph.com/pgcalc/, the `target.osd` key should be set to match the # expected number of osds in a cluster, and the `target.pg_per_osd` should be # set to match the desired number of placement groups on each OSD. crush: # NOTE(portdirect): to use RBD devices with Ubuntu 16.04's 4.4.x series # kernel this should be set to `hammer` tunables: null target: # NOTE(portdirect): arbitrarily we set the default number of expected OSD's to 5 # to match the number of nodes in the OSH gate. osd: 5 # This the number of OSDs expected in the final state. This is to allow the above # target to be smaller initially in the event of a partial deployment. This way # helm tests can still pass at deployment time and pool quotas can be set based on # the expected final state (actual target quota = final_osd / osd * quota). final_osd: 5 # This is just for helm tests to proceed the deployment if we have mentioned % of # osds are up and running. required_percent_of_osds: 75 pg_per_osd: 100 # NOTE(bw6938): When pools are created with the autoscaler enabled, a pg_num_min # value specifies the minimum value of pg_num that the autoscaler will target. # That default was recently changed from 8 to 32 which severely limits the number # of pools in a small cluster per https://github.com/rook/rook/issues/5091. This change # overrides the default pg_num_min value of 32 with a value of 8, matching the default # pg_num value of 8. pg_num_min: 8 protected: true # NOTE(st053q): target quota should be set to the overall cluster full percentage # to be tolerated as a quota (percent full to allow in order to tolerate some # level of failure) # Set target quota to "0" (must be quoted) to remove quotas for all pools quota: 100 default: # NOTE(supamatt): Accepted values are taken from `crush_rules` list. crush_rule: replicated_rule crush_rules: # NOTE(supamatt): Device classes must remain undefined if all OSDs are the # same device type of backing disks (ie, all HDD or all SDD). - name: same_host crush_rule: create-simple failure_domain: osd device_class: - name: replicated_rule crush_rule: create-simple failure_domain: host device_class: - name: rack_replicated_rule crush_rule: create-simple failure_domain: rack device_class: # - name: replicated_rule-ssd # crush_rule: create-replicated # failure_domain: host # device_class: sdd # - name: replicated_rule-hdd # crush_rule: create-replicated # failure_domain: host # device_class: hdd # - name: rack_replicated_rule-ssd # crush_rule: create-replicated # failure_domain: rack # device_class: ssd # - name: rack_replicated_rule-hdd # crush_rule: create-replicated # failure_domain: rack # device_class: hdd # - name: row_replicated_rule # crush_rule: create-simple # failure_domain: row # device_class: # NOTE(portdirect): this section describes the pools that will be managed by # the ceph pool management job, as it tunes the pgs and crush rule, based on # the above. spec: # Health metrics pool - name: .mgr application: mgr_devicehealth replication: 1 percent_total_data: 5 # RBD pool - name: rbd # An optional "rename" value may be used to change the name of an existing pool. # If the pool doesn't exist, it will be created and renamed. If the pool exists with # the original name, it will be renamed. If the pool exists and has already been # renamed, the name will not be changed. If two pools exist with the two names, the # pool matching the renamed value will be configured and the other left alone. # rename: rbd-new # Optional "delete" and "delete_all_pool_data" values may be used to delete an # existing pool. Both must exist and must be set to true in order to delete a pool. # NOTE: Deleting a pool deletes all of its data and is unrecoverable. This is why # both values are required in order to delete a pool. Neither value does # anything by itself. # delete: false # delete_all_pool_data: false application: rbd replication: 3 percent_total_data: 40 # Example of 100 GiB pool_quota for rbd pool (no pool quota if absent) # May be specified in TiB, TB, GiB, GB, MiB, MB, KiB, KB, or bytes # NOTE: This should always be a string value to avoid Helm issues with large integers # pool_quota: "100GiB" # Example of an overridden pg_num_min value for a single pool # pg_num_min: 32 # NOTE(supamatt): By default the crush rules used to create each pool will be # taken from the pool default `crush_rule` unless a pool specific `crush_rule` # is specified. The rule MUST exist for it to be defined here. # crush_rule: replicated_rule # CephFS pools - name: cephfs_metadata application: cephfs replication: 3 percent_total_data: 5 - name: cephfs_data application: cephfs replication: 3 percent_total_data: 10 # RadosGW pools - name: .rgw.root application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.control application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.data.root application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.gc application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.log application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.intent-log application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.meta application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.usage application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.keys application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.email application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.swift application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.uid application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.buckets.extra application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.buckets.index application: rgw replication: 3 percent_total_data: 3 - name: default.rgw.buckets.data application: rgw replication: 3 percent_total_data: 29 ceph: global: # auth cephx: true cephx_require_signatures: false cephx_cluster_require_signatures: true cephx_service_require_signatures: false objecter_inflight_op_bytes: "1073741824" objecter_inflight_ops: 10240 debug_ms: "0/0" log_file: /dev/stdout mon_cluster_log_file: /dev/stdout osd: osd_mkfs_type: xfs osd_mkfs_options_xfs: -f -i size=2048 osd_max_object_name_len: 256 ms_bind_port_min: 6800 ms_bind_port_max: 7100 dependencies: dynamic: common: local_image_registry: jobs: - ceph-client-image-repo-sync services: - endpoint: node service: local_image_registry static: bootstrap: jobs: null services: - endpoint: internal service: ceph_mon cephfs_client_key_generator: jobs: null mds: jobs: - ceph-storage-keys-generator - ceph-mds-keyring-generator - ceph-rbd-pool services: - endpoint: internal service: ceph_mon pool_checkpgs: jobs: - ceph-rbd-pool services: - endpoint: internal service: ceph_mgr checkdns: services: - endpoint: internal service: ceph_mon namespace_client_key_cleaner: jobs: null namespace_client_key_generator: jobs: null rbd_pool: services: - endpoint: internal service: ceph_mon - endpoint: internal service: ceph_mgr image_repo_sync: services: - endpoint: internal service: local_image_registry tests: jobs: - ceph-rbd-pool - ceph-mgr-keyring-generator services: - endpoint: internal service: ceph_mon - endpoint: internal service: ceph_mgr bootstrap: enabled: false script: | ceph -s function ensure_pool () { ceph osd pool stats $1 || ceph osd pool create $1 $2 if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 12 ]]; then ceph osd pool application enable $1 $3 fi } #ensure_pool volumes 8 cinder endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ceph-client: username: ceph-client password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null ceph_mon: namespace: null hosts: default: ceph-mon discovery: ceph-mon-discovery host_fqdn_override: default: null port: mon: default: 6789 mon_msgr2: default: 3300 ceph_mgr: namespace: null hosts: default: ceph-mgr host_fqdn_override: default: null port: mgr: default: 7000 metrics: default: 9283 scheme: default: http ceph_object_store: endpoint_namespaces: - openstack - ceph # hosts: # default: ceph-rgw # host_fqdn_override: # default: null manifests: configmap_bin: true configmap_test_bin: true configmap_etc: true deployment_mds: true deployment_checkdns: true job_bootstrap: false job_cephfs_client_key: true job_image_repo_sync: true job_rbd_pool: true helm_tests: true cronjob_checkPGs: true cronjob_defragosds: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ceph-mon/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Ceph Mon name: ceph-mon version: 2025.2.0 home: https://github.com/ceph/ceph dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ceph-mon/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: ceph-mon/templates/bin/_init-dirs.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C : "${HOSTNAME:=$(uname -n)}" : "${MGR_NAME:=${HOSTNAME}}" : "${MDS_NAME:=mds-${HOSTNAME}}" : "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" : "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" for keyring in ${OSD_BOOTSTRAP_KEYRING} ${MDS_BOOTSTRAP_KEYRING} ; do mkdir -p "$(dirname "$keyring")" done # Let's create the ceph directories for DIRECTORY in mon osd mds radosgw tmp mgr crash; do mkdir -p "/var/lib/ceph/${DIRECTORY}" done # Create socket directory mkdir -p /run/ceph # Create the MDS directory mkdir -p "/var/lib/ceph/mds/${CLUSTER}-${MDS_NAME}" # Create the MGR directory mkdir -p "/var/lib/ceph/mgr/${CLUSTER}-${MGR_NAME}" # Adjust the owner of all those directories chown -R ceph. /run/ceph/ /var/lib/ceph/* ================================================ FILE: ceph-mon/templates/bin/_post-apply.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} export LC_ALL=C : "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" if [[ ! -f /etc/ceph/${CLUSTER}.conf ]]; then echo "ERROR- /etc/ceph/${CLUSTER}.conf must exist; get it from your existing mon" exit 1 fi if [[ ! -f ${ADMIN_KEYRING} ]]; then echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" exit 1 fi ceph --cluster ${CLUSTER} -s function wait_for_pods() { timeout=${2:-1800} end=$(date -ud "${timeout} seconds" +%s) # Selecting containers with "ceph-mon" name and # counting them based on "ready" field. count_pods=".items | map(.status.containerStatuses | .[] | \ select(.name==\"ceph-mon\")) | \ group_by(.ready) | map({(.[0].ready | tostring): length}) | .[]" min_mons="add | if .true >= (.false + .true) \ then \"pass\" else \"fail\" end" while true; do # Leave while loop if all mons are ready. state=$(kubectl get pods --namespace="${1}" -l component=mon -o json | jq "${count_pods}") mon_state=$(jq -s "${min_mons}" <<< "${state}") if [[ "${mon_state}" == \"pass\" ]]; then break fi sleep 5 if [ $(date -u +%s) -gt $end ] ; then echo -e "Containers failed to start after $timeout seconds\n" kubectl get pods --namespace "${1}" -o wide -l component=mon exit 1 fi done } function check_ds() { for ds in `kubectl get ds --namespace=$CEPH_NAMESPACE -l component=mon --no-headers=true|awk '{print $1}'` do ds_query=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status` if echo $ds_query |grep -i "numberAvailable" ;then currentNumberScheduled=`echo $ds_query|jq -r .currentNumberScheduled` desiredNumberScheduled=`echo $ds_query|jq -r .desiredNumberScheduled` numberAvailable=`echo $ds_query|jq -r .numberAvailable` numberReady=`echo $ds_query|jq -r .numberReady` updatedNumberScheduled=`echo $ds_query|jq -r .updatedNumberScheduled` ds_check=`echo "$currentNumberScheduled $desiredNumberScheduled $numberAvailable $numberReady $updatedNumberScheduled"| \ tr ' ' '\n'|sort -u|wc -l` if [ $ds_check != 1 ]; then echo "Some pods in daemonset $ds are not ready" exit else echo "All pods in deamonset $ds are ready" fi else echo "There are no mons under daemonset $ds" fi done } function restart_mons() { mon_pods=`kubectl get po -n $CEPH_NAMESPACE -l component=mon --no-headers | awk '{print $1}'` for pod in ${mon_pods} do if [[ -n "$pod" ]]; then echo "Restarting pod $pod" kubectl delete pod -n $CEPH_NAMESPACE $pod fi echo "Waiting for the pod $pod to restart" # The pod will not be ready in first 60 seconds. Thus we can reduce # amount of queries to kubernetes. sleep 60 wait_for_pods ceph -s done } wait_for_pods $CEPH_NAMESPACE require_upgrade=0 max_release=0 for ds in `kubectl get ds --namespace=$CEPH_NAMESPACE -l component=mon --no-headers=true|awk '{print $1}'` do updatedNumberScheduled=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status.updatedNumberScheduled` desiredNumberScheduled=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status.desiredNumberScheduled` if [[ $updatedNumberScheduled != $desiredNumberScheduled ]]; then if kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status|grep -i "numberAvailable" ;then require_upgrade=$((require_upgrade+1)) _release=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status.observedGeneration` max_release=$(( max_release > _release ? max_release : _release )) fi fi done echo "Latest revision of the helm chart(s) is : $max_release" if [[ "$UNCONDITIONAL_MON_RESTART" == "true" ]] || [[ $max_release -gt 1 ]]; then if [[ "$UNCONDITIONAL_MON_RESTART" == "true" ]] || [[ $require_upgrade -gt 0 ]]; then echo "Restart ceph-mon pods one at a time to prevent disruption" restart_mons fi # Check all the ceph-mon daemonsets echo "checking DS" check_ds else echo "No revisions found for upgrade" fi ================================================ FILE: ceph-mon/templates/bin/keys/_bootstrap-keyring-generator.py.tpl ================================================ #!/bin/python import os import struct import time import base64 key = os.urandom(16) header = struct.pack( ' create_kube_key $(ceph_gen_key) ${CEPH_KEYRING_NAME} ${CEPH_KEYRING_TEMPLATE} ${KUBE_SECRET_NAME} {{ else }} echo "Not touching ${KUBE_SECRET_NAME} as this is not the initial deployment" {{- end -}} ================================================ FILE: ceph-mon/templates/bin/keys/_storage-keyring-manager.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ if .Release.IsInstall }} {{- $envAll := . }} function ceph_gen_key () { python3 ${CEPH_GEN_DIR}/keys-bootstrap-keyring-generator.py } function kube_ceph_keyring_gen () { CEPH_KEY=$1 CEPH_KEY_TEMPLATE=$2 sed "s|{{"{{"}} key {{"}}"}}|${CEPH_KEY}|" ${CEPH_TEMPLATES_DIR}/${CEPH_KEY_TEMPLATE} | base64 -w0 | tr -d '\n' } CEPH_CLIENT_KEY="" ROOK_CEPH_TOOLS_POD=$(kubectl -n ${DEPLOYMENT_NAMESPACE} get pods --no-headers | awk '/rook-ceph-tools/{print $1}') if [[ -n "${ROOK_CEPH_TOOLS_POD}" ]]; then CEPH_AUTH_KEY_NAME=$(echo "${CEPH_KEYRING_NAME}" | awk -F. '{print $2 "." $3}') CEPH_CLIENT_KEY=$(kubectl -n ${DEPLOYMENT_NAMESPACE} exec ${ROOK_CEPH_TOOLS_POD} -- ceph auth ls | grep -A1 "${CEPH_AUTH_KEY_NAME}" | awk '/key:/{print $2}') fi if [[ -z "${CEPH_CLIENT_KEY}" ]]; then CEPH_CLIENT_KEY=$(ceph_gen_key) fi function create_kube_key () { CEPH_KEYRING=$1 CEPH_KEYRING_NAME=$2 CEPH_KEYRING_TEMPLATE=$3 KUBE_SECRET_NAME=$4 if ! kubectl get --namespace ${DEPLOYMENT_NAMESPACE} secrets ${KUBE_SECRET_NAME}; then { cat < create_kube_key ${CEPH_CLIENT_KEY} ${CEPH_KEYRING_NAME} ${CEPH_KEYRING_TEMPLATE} ${CEPH_KEYRING_ADMIN_NAME} function create_kube_storage_key () { CEPH_KEYRING=$1 KUBE_SECRET_NAME=$2 if ! kubectl get --namespace ${DEPLOYMENT_NAMESPACE} secrets ${KUBE_SECRET_NAME}; then { cat < create_kube_storage_key ${CEPH_CLIENT_KEY} ${CEPH_STORAGECLASS_ADMIN_SECRET_NAME} create_kube_storage_key ${CEPH_CLIENT_KEY} ${CEPH_STORAGECLASS_ADMIN_SECRET_NAME_NODE} {{ else }} echo "Not touching ${KUBE_SECRET_NAME} as this is not the initial deployment" {{ end }} ================================================ FILE: ceph-mon/templates/bin/mgr/_check.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C COMMAND="${@:-liveness}" function heath_check () { ASOK=$(ls /var/run/ceph/${CLUSTER}-mgr*) MGR_NAME=$(basename ${ASOK} | sed -e 's/.asok//' | cut -f 1 -d '.' --complement) MGR_STATE=$(ceph --cluster ${CLUSTER} --connect-timeout 1 daemon mgr.${MGR_NAME} status) if [ $? = 0 ]; then exit 0 else echo $MGR_STATE exit 1 fi } function liveness () { heath_check } function readiness () { heath_check } $COMMAND ================================================ FILE: ceph-mon/templates/bin/mgr/_start.sh.tpl ================================================ #!/bin/bash set -ex : "${CEPH_GET_ADMIN_KEY:=0}" : "${MGR_NAME:=$(uname -n)}" : "${MGR_KEYRING:=/var/lib/ceph/mgr/${CLUSTER}-${MGR_NAME}/keyring}" : "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} if [[ ! -e ${CEPH_CONF}.template ]]; then echo "ERROR- ${CEPH_CONF}.template must exist; get it from your existing mon" exit 1 else ENDPOINT=$(mon_host_from_k8s_ep "${NAMESPACE}" ceph-mon-discovery) if [[ "${ENDPOINT}" == "" ]]; then /bin/sh -c -e "cat ${CEPH_CONF}.template | tee ${CEPH_CONF}" || true else /bin/sh -c -e "cat ${CEPH_CONF}.template | sed 's#mon_host.*#mon_host = ${ENDPOINT}#g' | tee ${CEPH_CONF}" || true fi fi if [ ${CEPH_GET_ADMIN_KEY} -eq 1 ]; then if [[ ! -e ${ADMIN_KEYRING} ]]; then echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" exit 1 fi fi # Create a MGR keyring rm -rf $MGR_KEYRING if [ ! -e "$MGR_KEYRING" ]; then # Create ceph-mgr key timeout 10 ceph --cluster "${CLUSTER}" auth get-or-create mgr."${MGR_NAME}" mon 'allow profile mgr' osd 'allow *' mds 'allow *' -o "$MGR_KEYRING" chown --verbose ceph. "$MGR_KEYRING" chmod 600 "$MGR_KEYRING" fi echo "SUCCESS" ceph --cluster "${CLUSTER}" -v # Env. variables matching the pattern "_" will be # found and parsed for config-key settings by # ceph config set mgr mgr// MODULES_TO_DISABLE=`ceph mgr dump | python3 -c "import json, sys; print(' '.join(json.load(sys.stdin)['modules']))"` for module in ${ENABLED_MODULES}; do # This module may have been enabled in the past # remove it from the disable list if present MODULES_TO_DISABLE=${MODULES_TO_DISABLE/$module/} options=`env | grep ^${module}_ || true` for option in ${options}; do #strip module name option=${option/${module}_/} key=`echo $option | cut -d= -f1` value=`echo $option | cut -d= -f2` if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]]; then ceph --cluster "${CLUSTER}" config set mgr mgr/$module/$key $value --force else ceph --cluster "${CLUSTER}" config set mgr mgr/$module/$key $value fi done ceph --cluster "${CLUSTER}" mgr module enable ${module} --force done for module in $MODULES_TO_DISABLE; do ceph --cluster "${CLUSTER}" mgr module disable ${module} done echo "SUCCESS" # start ceph-mgr exec /usr/bin/ceph-mgr \ --cluster "${CLUSTER}" \ --setuser "ceph" \ --setgroup "ceph" \ -d \ -i "${MGR_NAME}" ================================================ FILE: ceph-mon/templates/bin/mon/_check.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-liveness}" : ${K8S_HOST_NETWORK:=0} function heath_check () { SOCKDIR=${CEPH_SOCKET_DIR:-/run/ceph} SBASE=${CEPH_OSD_SOCKET_BASE:-ceph-mon} SSUFFIX=${CEPH_SOCKET_SUFFIX:-asok} MON_ID=$(ps auwwx | grep ceph-mon | grep -v "$1" | grep -v grep | sed 's/.*-i\ //;s/\ .*//'|awk '{print $1}') if [ -z "${MON_ID}" ]; then if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then MON_NAME=${POD_NAME} else MON_NAME=${NODE_NAME} fi fi if [ -S "${SOCKDIR}/${SBASE}.${MON_NAME}.${SSUFFIX}" ]; then MON_STATE=$(ceph -f json-pretty --connect-timeout 1 --admin-daemon "${SOCKDIR}/${SBASE}.${MON_NAME}.${SSUFFIX}" mon_status|grep state|sed 's/.*://;s/[^a-z]//g') echo "MON ${MON_ID} ${MON_STATE}"; # this might be a stricter check than we actually want. what are the # other values for the "state" field? for S in ${MON_LIVE_STATE}; do if [ "x${MON_STATE}x" = "x${S}x" ]; then exit 0 fi done fi # if we made it this far, things are not running exit 1 } function liveness () { MON_LIVE_STATE="probing electing synchronizing leader peon" heath_check } function readiness () { MON_LIVE_STATE="leader peon" heath_check } $COMMAND ================================================ FILE: ceph-mon/templates/bin/mon/_start.sh.tpl ================================================ #!/bin/bash set -ex export LC_ALL=C : "${K8S_HOST_NETWORK:=0}" : "${MON_KEYRING:=/etc/ceph/${CLUSTER}.mon.keyring}" : "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" : "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" : "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} if [[ ! -e ${CEPH_CONF}.template ]]; then echo "ERROR- ${CEPH_CONF}.template must exist; get it from your existing mon" exit 1 else ENDPOINT=$(mon_host_from_k8s_ep "${NAMESPACE}" ceph-mon-discovery) if [[ -z "${ENDPOINT}" ]]; then /bin/sh -c -e "cat ${CEPH_CONF}.template | tee ${CEPH_CONF}" || true else /bin/sh -c -e "cat ${CEPH_CONF}.template | sed 's#mon_host.*#mon_host = ${ENDPOINT}#g' | tee ${CEPH_CONF}" || true fi fi if [[ -z "$CEPH_PUBLIC_NETWORK" ]]; then echo "ERROR- CEPH_PUBLIC_NETWORK must be defined as the name of the network for the OSDs" exit 1 fi if [[ -z "$MON_IP" ]]; then echo "ERROR- MON_IP must be defined as the IP address of the monitor" exit 1 fi if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then MON_NAME=${POD_NAME} else MON_NAME=${NODE_NAME} fi MON_DATA_DIR="/var/lib/ceph/mon/${CLUSTER}-${MON_NAME}" MONMAP="/etc/ceph/monmap-${CLUSTER}" # Make the monitor directory /bin/sh -c "mkdir -p \"${MON_DATA_DIR}\"" function get_mon_config { # Get fsid from ceph.conf local fsid=$(ceph-conf --lookup fsid -c /etc/ceph/${CLUSTER}.conf) timeout=10 MONMAP_ADD="" while [[ -z "${MONMAP_ADD// }" && "${timeout}" -gt 0 ]]; do # Get the ceph mon pods (name and IP) from the Kubernetes API. Formatted as a set of monmap params if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then MONMAP_ADD=$(kubectl get pods --namespace=${NAMESPACE} ${KUBECTL_PARAM} -o template --template="{{`{{range .items}}`}}{{`{{if .status.podIP}}`}}--addv {{`{{.metadata.name}}`}} [v1:{{`{{.status.podIP}}`}}:${MON_PORT},v2:{{`{{.status.podIP}}`}}:${MON_PORT_V2}] {{`{{end}}`}} {{`{{end}}`}}") else MONMAP_ADD=$(kubectl get pods --namespace=${NAMESPACE} ${KUBECTL_PARAM} -o template --template="{{`{{range .items}}`}}{{`{{if .status.podIP}}`}}--addv {{`{{.spec.nodeName}}`}} [v1:{{`{{.status.podIP}}`}}:${MON_PORT},v2:{{`{{.status.podIP}}`}}:${MON_PORT_V2}] {{`{{end}}`}} {{`{{end}}`}}") fi (( timeout-- )) sleep 1 done if [[ -z "${MONMAP_ADD// }" ]]; then exit 1 fi # Create a monmap with the Pod Names and IP monmaptool --create ${MONMAP_ADD} --fsid ${fsid} ${MONMAP} --clobber } get_mon_config # If we don't have a monitor keyring, this is a new monitor if [ ! -e "${MON_DATA_DIR}/keyring" ]; then if [ ! -e ${MON_KEYRING}.seed ]; then echo "ERROR- ${MON_KEYRING}.seed must exist. You can extract it from your current monitor by running 'ceph auth get mon. -o ${MON_KEYRING}' or use a KV Store" exit 1 else cp -vf ${MON_KEYRING}.seed ${MON_KEYRING} fi if [ ! -e ${MONMAP} ]; then echo "ERROR- ${MONMAP} must exist. You can extract it from your current monitor by running 'ceph mon getmap -o ${MONMAP}' or use a KV Store" exit 1 fi # Testing if it's not the first monitor, if one key doesn't exist we assume none of them exist for KEYRING in ${OSD_BOOTSTRAP_KEYRING} ${MDS_BOOTSTRAP_KEYRING} ${ADMIN_KEYRING}; do ceph-authtool ${MON_KEYRING} --import-keyring ${KEYRING} done # Prepare the monitor daemon's directory with the map and keyring ceph-mon --setuser ceph --setgroup ceph --cluster "${CLUSTER}" --mkfs -i ${MON_NAME} --inject-monmap ${MONMAP} --keyring ${MON_KEYRING} --mon-data "${MON_DATA_DIR}" else echo "Trying to get the most recent monmap..." # Ignore when we timeout, in most cases that means the cluster has no quorum or # no mons are up and running yet timeout 5 ceph --cluster "${CLUSTER}" mon getmap -o ${MONMAP} || true ceph-mon --setuser ceph --setgroup ceph --cluster "${CLUSTER}" -i ${MON_NAME} --inject-monmap ${MONMAP} --keyring ${MON_KEYRING} --mon-data "${MON_DATA_DIR}" timeout 7 ceph --cluster "${CLUSTER}" mon add "${MON_NAME}" "${MON_IP}:${MON_PORT_V2}" || true fi # start MON exec /usr/bin/ceph-mon \ --cluster "${CLUSTER}" \ --setuser "ceph" \ --setgroup "ceph" \ -d \ -i ${MON_NAME} \ --mon-data "${MON_DATA_DIR}" \ --public-addr "${MON_IP}:${MON_PORT_V2}" ================================================ FILE: ceph-mon/templates/bin/mon/_stop.sh.tpl ================================================ #!/bin/bash set -ex NUMBER_OF_MONS=$(ceph mon stat | awk '$3 == "mons" {print $2}') if [[ "${NUMBER_OF_MONS}" -gt "3" ]]; then if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then ceph mon remove "${POD_NAME}" else ceph mon remove "${NODE_NAME}" fi else echo "doing nothing since we are running less than or equal to 3 mons" fi ================================================ FILE: ceph-mon/templates/bin/moncheck/_reap-zombies.py.tpl ================================================ #!/usr/bin/python import re import os import subprocess # nosec import json MON_REGEX = r"^\d: \[((v\d+:([0-9\.]*):\d+\/\d+,*)+)] mon.([^ ]*)$" # kubctl_command = 'kubectl get pods --namespace=${NAMESPACE} -l component=mon,application=ceph -o template --template="{ {{"}}"}}range .items{{"}}"}} \\"{{"}}"}}.metadata.name{{"}}"}}\\": \\"{{"}}"}}.status.podIP{{"}}"}}\\" , {{"}}"}}end{{"}}"}} }"' if int(os.getenv('K8S_HOST_NETWORK', 0)) > 0: kubectl_command = 'kubectl get pods --namespace=${NAMESPACE} -l component=mon,application=ceph -o template --template="{ {{"{{"}}range \$i, \$v := .items{{"}}"}} {{"{{"}} if \$i{{"}}"}} , {{"{{"}} end {{"}}"}} \\"{{"{{"}}\$v.spec.nodeName{{"}}"}}\\": \\"{{"{{"}}\$v.status.podIP{{"}}"}}\\" {{"{{"}}end{{"}}"}} }"' else: kubectl_command = 'kubectl get pods --namespace=${NAMESPACE} -l component=mon,application=ceph -o template --template="{ {{"{{"}}range \$i, \$v := .items{{"}}"}} {{"{{"}} if \$i{{"}}"}} , {{"{{"}} end {{"}}"}} \\"{{"{{"}}\$v.metadata.name{{"}}"}}\\": \\"{{"{{"}}\$v.status.podIP{{"}}"}}\\" {{"{{"}}end{{"}}"}} }"' monmap_command = "ceph --cluster=${CLUSTER} mon getmap > /tmp/monmap && monmaptool -f /tmp/monmap --print" def extract_mons_from_monmap(): monmap = subprocess.check_output(monmap_command, shell=True).decode('utf-8') # nosec mons = {} for line in monmap.split("\n"): m = re.match(MON_REGEX, line) if m is not None: mons[m.group(4)] = m.group(3) return mons def extract_mons_from_kubeapi(): kubemap = subprocess.check_output(kubectl_command, shell=True).decode('utf-8') # nosec return json.loads(kubemap) current_mons = extract_mons_from_monmap() expected_mons = extract_mons_from_kubeapi() print("current mons: %s" % current_mons) print("expected mons: %s" % expected_mons) removed_mon = False for mon in current_mons: if not mon in expected_mons: print("removing zombie mon %s" % mon) subprocess.call(["ceph", "--cluster", os.environ["NAMESPACE"], "mon", "remove", mon]) # nosec removed_mon = True elif current_mons[mon] != expected_mons[mon]: # check if for some reason the ip of the mon changed print("ip change detected for pod %s" % mon) subprocess.call(["kubectl", "--namespace", os.environ["NAMESPACE"], "delete", "pod", mon]) # nosec removed_mon = True print("deleted mon %s via the kubernetes api" % mon) if not removed_mon: print("no zombie mons found ...") ================================================ FILE: ceph-mon/templates/bin/moncheck/_start.sh.tpl ================================================ #!/bin/bash set -ex export LC_ALL=C : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} if [[ ! -e ${CEPH_CONF}.template ]]; then echo "ERROR- ${CEPH_CONF}.template must exist; get it from your existing mon" exit 1 else ENDPOINT=$(mon_host_from_k8s_ep ${NAMESPACE} ceph-mon-discovery) if [[ "${ENDPOINT}" == "" ]]; then /bin/sh -c -e "cat ${CEPH_CONF}.template | tee ${CEPH_CONF}" || true else /bin/sh -c -e "cat ${CEPH_CONF}.template | sed 's#mon_host.*#mon_host = ${ENDPOINT}#g' | tee ${CEPH_CONF}" || true fi fi function check_mon_msgr2 { if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]]; then if ceph health detail|grep -i "MON_MSGR2_NOT_ENABLED"; then echo "ceph-mon msgr v2 not enabled on all ceph mons so enabling" ceph mon enable-msgr2 fi fi } function get_mon_count { ceph mon count-metadata hostname | jq '. | length' } function check_mon_addrs { local mon_dump=$(ceph mon dump) local mon_hostnames=$(echo "${mon_dump}" | awk '/mon\./{print $3}' | sed 's/mon\.//g') local mon_endpoints=$(kubectl get endpoints ceph-mon-discovery -n ${NAMESPACE} -o json) local v1_port=$(jq '.subsets[0].ports[] | select(.name == "mon") | .port' <<< ${mon_endpoints}) local v2_port=$(jq '.subsets[0].ports[] | select(.name == "mon-msgr2") | .port' <<< ${mon_endpoints}) for mon in ${mon_hostnames}; do local mon_endpoint=$(echo "${mon_dump}" | awk "/${mon}/{print \$2}") local mon_ip=$(jq -r ".subsets[0].addresses[] | select(.nodeName == \"${mon}\") | .ip" <<< ${mon_endpoints}) # Skip this mon if it doesn't appear in the list of kubernetes endpoints if [[ -n "${mon_ip}" ]]; then local desired_endpoint=$(printf '[v1:%s:%s/0,v2:%s:%s/0]' ${mon_ip} ${v1_port} ${mon_ip} ${v2_port}) if [[ "${mon_endpoint}" != "${desired_endpoint}" ]]; then echo "endpoint for ${mon} is ${mon_endpoint}, setting it to ${desired_endpoint}" ceph mon set-addrs ${mon} ${desired_endpoint} fi fi done } function watch_mon_health { previous_mon_count=$(get_mon_count) while [ true ]; do mon_count=$(get_mon_count) if [[ ${mon_count} -ne ${previous_mon_count} ]]; then echo "checking for zombie mons" python3 /tmp/moncheck-reap-zombies.py || true fi previous_mon_count=${mon_count} echo "checking for ceph-mon msgr v2" check_mon_msgr2 echo "checking mon endpoints in monmap" check_mon_addrs echo "sleep 30 sec" sleep 30 done } watch_mon_health ================================================ FILE: ceph-mon/templates/bin/utils/_checkDNS.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" ENDPOINT="{$1}" function check_mon_dns () { GREP_CMD=$(grep -rl 'ceph-mon' ${CEPH_CONF}) if [[ "${ENDPOINT}" == "{up}" ]]; then echo "If DNS is working, we are good here" elif [[ "${ENDPOINT}" != "" ]]; then if [[ ${GREP_CMD} != "" ]]; then # No DNS, write CEPH MONs IPs into ${CEPH_CONF} sh -c -e "cat ${CEPH_CONF}.template | sed 's/mon_host.*/mon_host = ${ENDPOINT}/g' | tee ${CEPH_CONF}" > /dev/null 2>&1 else echo "endpoints are already cached in ${CEPH_CONF}" exit fi fi } check_mon_dns exit ================================================ FILE: ceph-mon/templates/bin/utils/_checkObjectReplication.py.tpl ================================================ #!/usr/bin/python3 import subprocess # nosec import json import sys import collections if (int(len(sys.argv)) == 1): print("Please provide pool name to test , example: checkObjectReplication.py ") sys.exit(1) else: poolName = sys.argv[1] cmdRep = 'ceph osd map' + ' ' + str(poolName) + ' ' + 'testreplication -f json-pretty' objectRep = subprocess.check_output(cmdRep, shell=True) # nosec repOut = json.loads(objectRep) osdNumbers = repOut['up'] print("Test object got replicated on these osds: %s" % str(osdNumbers)) osdHosts= [] for osd in osdNumbers: cmdFind = 'ceph osd find' + ' ' + str(osd) osdFind = subprocess.check_output(cmdFind , shell=True) # nosec osdHost = json.loads(osdFind) osdHostLocation = osdHost['crush_location'] osdHosts.append(osdHostLocation['host']) print("Test object got replicated on these hosts: %s" % str(osdHosts)) print("Hosts hosting multiple copies of a placement groups are: %s" % str([item for item, count in collections.Counter(osdHosts).items() if count > 1])) sys.exit(0) ================================================ FILE: ceph-mon/templates/bin/utils/_checkPGs.py.tpl ================================================ #!/usr/bin/python import subprocess # nosec import json import sys from argparse import * class cephCRUSH(): """ Currently, this script is coded to work with the ceph clusters that have these type-ids -- osd, host, rack, root. To add other type_ids to the CRUSH map, this script needs enhancements to include the new type_ids. type_id name ------- ---- 0 osd 1 host 2 chassis 3 rack 4 row 5 pdu 6 pod 7 room 8 datacenter 9 region 10 root Ceph organizes the CRUSH map in hierarchical topology. At the top, it is the root. The next levels are racks, hosts, and OSDs, respectively. The OSDs are at the leaf level. This script looks at OSDs in each placement group of a ceph pool. For each OSD, starting from the OSD leaf level, this script traverses up to the root. Along the way, the host and rack are recorded and then verified to make sure the paths to the root are in separate failure domains. This script reports the offending PGs to stdout. """ """ This list stores the ceph crush hierarchy retrieved from the ceph osd crush tree -f json-pretty """ crushHierarchy = [] """ Failure Domains - currently our crush map uses these type IDs - osd, host, rack, root If we need to add chassis type (or other types) later on, add the type to the if statement in the crushFD construction section. crushFD[0] = {'id': -2, 'name': 'host1', 'type': 'host'} crushFD[23] = {'id': -5, 'name': 'host2', 'type': 'host'} crushFD[68] = {'id': -7, 'name': 'host3', 'type': 'host'} rack_FD[-2] = {'id': -9, 'name': 'rack1', 'type': 'rack' } rack_FD[-15] = {'id': -17, 'name': 'rack2', 'type': 'rack' } root_FD[-17] = {'id': -1, 'name': 'default', 'type': 'root' }} root_FD[-9] = {'id': -1, 'name': 'default', 'type': 'root' }} """ crushFD = {} def __init__(self, poolName): if 'all' in poolName or 'All' in poolName: try: poolLs = 'ceph osd pool ls -f json-pretty' poolstr = subprocess.check_output(poolLs, shell=True) # nosec self.listPoolName = json.loads(poolstr) except subprocess.CalledProcessError as e: print('{}'.format(e)) """Unable to get all pools - cannot proceed""" sys.exit(2) else: self.listPoolName = poolName try: """Retrieve the crush hierarchies""" crushTree = "ceph osd crush tree -f json-pretty | jq .nodes" chstr = subprocess.check_output(crushTree, shell=True) # nosec self.crushHierarchy = json.loads(chstr) except subprocess.CalledProcessError as e: print('{}'.format(e)) """Unable to get crush hierarchy - cannot proceed""" sys.exit(2) """ Number of racks configured in the ceph cluster. The racks that are present in the crush hierarchy may not be used. The un-used rack would not show up in the crushFD. """ self.count_racks = 0 """depth level - 3 is OSD, 2 is host, 1 is rack, 0 is root""" self.osd_depth = 0 """Construct the Failure Domains - OSD -> Host -> Rack -> Root""" for chitem in self.crushHierarchy: if chitem['type'] == 'host' or \ chitem['type'] == 'rack' or \ chitem['type'] == 'root': for child in chitem['children']: self.crushFD[child] = {'id': chitem['id'], 'name': chitem['name'], 'type': chitem['type']} if chitem['type'] == 'rack' and len(chitem['children']) > 0: self.count_racks += 1 elif chitem['type'] == 'osd': if self.osd_depth == 0: self.osd_depth = chitem['depth'] """[ { 'pg-name' : [osd.1, osd.2, osd.3] } ... ]""" self.poolPGs = [] """Replica of the pool. Initialize to 0.""" self.poolSize = 0 def isSupportedRelease(self): cephMajorVer = int(subprocess.check_output("ceph mon versions | awk '/version/{print $3}' | cut -d. -f1", shell=True)) # nosec return cephMajorVer >= 14 def getPoolSize(self, poolName): """ size (number of replica) is an attribute of a pool { "pool": "rbd", "pool_id": 1, "size": 3 } """ pSize = {} """Get the size attribute of the poolName""" try: poolGet = 'ceph osd pool get ' + poolName + ' size -f json-pretty' szstr = subprocess.check_output(poolGet, shell=True) # nosec pSize = json.loads(szstr) self.poolSize = pSize['size'] except subprocess.CalledProcessError as e: print('{}'.format(e)) self.poolSize = 0 """Continue on""" return def checkPGs(self, poolName): poolPGs = self.poolPGs['pg_stats'] if self.isSupportedRelease() else self.poolPGs if not poolPGs: return print('Checking PGs in pool {} ...'.format(poolName)), badPGs = False for pg in poolPGs: osdUp = pg['up'] """ Construct the OSD path from the leaf to the root. If the replica is set to 3 and there are 3 racks. Each OSD has its own rack (failure domain). If more than one OSD has the same rack, this is a violation. If the number of rack is one, then we need to make sure the hosts for the three OSDs are different. """ check_FD = {} checkFailed = False for osd in osdUp: traverseID = osd """Start the level with 1 to include the OSD leaf""" traverseLevel = 1 while (self.crushFD[traverseID]['type'] != 'root'): crushType = self.crushFD[traverseID]['type'] crushName = self.crushFD[traverseID]['name'] if crushType in check_FD: check_FD[crushType].append(crushName) else: check_FD[crushType] = [crushName] """traverse up (to the root) one level""" traverseID = self.crushFD[traverseID]['id'] traverseLevel += 1 if not (traverseLevel == self.osd_depth): raise Exception("OSD depth mismatch") """ check_FD should have { 'host': ['host1', 'host2', 'host3', 'host4'], 'rack': ['rack1', 'rack2', 'rack3'] } Not checking for the 'root' as there is only one root. """ for ktype in check_FD: kvalue = check_FD[ktype] if ktype == 'host': """ At the host level, every OSD should come from different host. It is a violation if duplicate hosts are found. """ if len(kvalue) != len(set(kvalue)): if not badPGs: print('Failed') badPGs = True print('OSDs {} in PG {} failed check in host {}'.format(pg['up'], pg['pgid'], kvalue)) elif ktype == 'rack': if len(kvalue) == len(set(kvalue)): continue else: """ There are duplicate racks. This could be due to situation like pool's size is 3 and there are only two racks (or one rack). OSDs should come from different hosts as verified in the 'host' section. """ if self.count_racks == len(set(kvalue)): continue elif self.count_racks > len(set(kvalue)): """Not all the racks were used to allocate OSDs""" if not badPGs: print('Failed') badPGs = True print('OSDs {} in PG {} failed check in rack {}'.format(pg['up'], pg['pgid'], kvalue)) check_FD.clear() if not badPGs: print('Passed') return def checkPoolPGs(self): for pool in self.listPoolName: self.getPoolSize(pool) if self.poolSize == 1: """No need to check pool with the size set to 1 copy""" print('Checking PGs in pool {} ... {}'.format(pool, 'Skipped')) continue elif self.poolSize == 0: print('Pool {} was not found.'.format(pool)) continue if not self.poolSize > 1: raise Exception("Pool size was incorrectly set") try: """Get the list of PGs in the pool""" lsByPool = 'ceph pg ls-by-pool ' + pool + ' -f json-pretty' pgstr = subprocess.check_output(lsByPool, shell=True) # nosec self.poolPGs = json.loads(pgstr) """Check that OSDs in the PG are in separate failure domains""" self.checkPGs(pool) except subprocess.CalledProcessError as e: print('{}'.format(e)) """Continue to the next pool (if any)""" return def Main(): parser = ArgumentParser(description=''' Cross-check the OSDs assigned to the Placement Groups (PGs) of a ceph pool with the CRUSH topology. The cross-check compares the OSDs in a PG and verifies the OSDs reside in separate failure domains. PGs with OSDs in the same failure domain are flagged as violation. The offending PGs are printed to stdout. This CLI is executed on-demand on a ceph-mon pod. To invoke the CLI, you can specify one pool or list of pools to check. The special pool name All (or all) checks all the pools in the ceph cluster. ''', formatter_class=RawTextHelpFormatter) parser.add_argument('PoolName', type=str, nargs='+', help='List of pools (or All) to validate the PGs and OSDs mapping') args = parser.parse_args() if ('all' in args.PoolName or 'All' in args.PoolName) and len(args.PoolName) > 1: print('You only need to give one pool with special pool All') sys.exit(1) """ Retrieve the crush hierarchies and store it. Cross-check the OSDs in each PG searching for failure domain violation. """ ccm = cephCRUSH(args.PoolName) ccm.checkPoolPGs() if __name__ == '__main__': Main() ================================================ FILE: ceph-mon/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.configmap_bin .Values.deployment.ceph }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} post-apply.sh: | {{ tuple "bin/_post-apply.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} init-dirs.sh: | {{ tuple "bin/_init-dirs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} keys-bootstrap-keyring-generator.py: | {{ tuple "bin/keys/_bootstrap-keyring-generator.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} keys-bootstrap-keyring-manager.sh: | {{ tuple "bin/keys/_bootstrap-keyring-manager.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} keys-storage-keyring-manager.sh: | {{ tuple "bin/keys/_storage-keyring-manager.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mon-start.sh: | {{ tuple "bin/mon/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mon-stop.sh: | {{ tuple "bin/mon/_stop.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mon-check.sh: | {{ tuple "bin/mon/_check.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mgr-start.sh: | {{ tuple "bin/mgr/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mgr-check.sh: | {{ tuple "bin/mgr/_check.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} moncheck-start.sh: | {{ tuple "bin/moncheck/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} moncheck-reap-zombies.py: | {{ tuple "bin/moncheck/_reap-zombies.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-checkObjectReplication.py: | {{ tuple "bin/utils/_checkObjectReplication.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-checkDNS.sh: | {{ tuple "bin/utils/_checkDNS.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} utils-checkPGs.py: | {{ tuple "bin/utils/_checkPGs.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ================================================ FILE: ceph-mon/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ceph.mon.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if .Values.deployment.ceph }} {{- if empty .Values.conf.ceph.global.mon_host -}} {{- $monHost := tuple "ceph_mon" "discovery" "mon_msgr2" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} {{- $_ := $monHost | set .Values.conf.ceph.global "mon_host" -}} {{- end -}} {{- if empty .Values.conf.ceph.global.fsid -}} {{- $_ := uuidv4 | set .Values.conf.ceph.global "fsid" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.cluster_network -}} {{- $_ := .Values.network.cluster | set .Values.conf.ceph.osd "cluster_network" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.public_network -}} {{- $_ := .Values.network.public | set .Values.conf.ceph.osd "public_network" -}} {{- end -}} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapName }} data: ceph.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.ceph | indent 4 }} {{- end }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list (printf "%s-%s" .Release.Name "etc") . | include "ceph.mon.configmap.etc" }} {{- end }} ================================================ FILE: ceph-mon/templates/configmap-templates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.configmap_templates .Values.deployment.storage_secrets }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.Release.Name "templates" | quote }} data: admin.keyring: | {{ .Values.conf.templates.keyring.admin | indent 4 }} mon.keyring: | {{ .Values.conf.templates.keyring.mon | indent 4 }} bootstrap.keyring.mds: | {{ .Values.conf.templates.keyring.bootstrap.mds | indent 4 }} bootstrap.keyring.mgr: | {{ .Values.conf.templates.keyring.bootstrap.mgr | indent 4 }} bootstrap.keyring.osd: | {{ .Values.conf.templates.keyring.bootstrap.osd | indent 4 }} {{- end }} ================================================ FILE: ceph-mon/templates/daemonset-mon.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "monLivenessProbeTemplate" -}} exec: command: - /tmp/mon-check.sh {{- end -}} {{- define "monReadinessProbeTemplate" -}} exec: command: - /tmp/mon-check.sh {{- end -}} {{- if and .Values.manifests.daemonset_mon .Values.deployment.ceph }} {{- $envAll := . }} {{- $serviceAccountName := (printf "%s" .Release.Name) }} {{ tuple $envAll "mon" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - pods - endpoints verbs: - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} {{- end }} {{- define "ceph.mon.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} --- kind: DaemonSet apiVersion: apps/v1 metadata: name: ceph-mon annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "mon" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "ceph-mon" "containerNames" (list "ceph-mon" "ceph-init-dirs" "ceph-log-ownership") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "mon" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.mon.node_selector_key }}: {{ .Values.labels.mon.node_selector_value }} hostNetwork: true shareProcessNamespace: true dnsPolicy: {{ .Values.pod.dns_policy }} initContainers: {{ tuple $envAll "mon" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-init-dirs {{ tuple $envAll "ceph_mon" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "mon" "container" "ceph_init_dirs" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/init-dirs.sh env: - name: CLUSTER value: "ceph" volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/init-dirs.sh subPath: init-dirs.sh readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false - name: ceph-log-ownership {{ tuple $envAll "ceph_mon" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "mon" "container" "ceph_log_ownership" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - ceph:root - /var/log/ceph volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: pod-var-log mountPath: /var/log/ceph readOnly: false containers: - name: ceph-mon {{ tuple $envAll "ceph_mon" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.mon | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "mon" "container" "ceph_mon" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: K8S_HOST_NETWORK value: "1" - name: MONMAP value: /var/lib/ceph/mon/monmap - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: CEPH_PUBLIC_NETWORK value: {{ .Values.network.public | quote }} - name: KUBECTL_PARAM value: {{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_kubectl_params" }} - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName command: - /tmp/mon-start.sh lifecycle: preStop: exec: command: - /tmp/mon-stop.sh ports: - containerPort: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - containerPort: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" . "component" "ceph" "container" "ceph-mon" "type" "liveness" "probeTemplate" (include "monLivenessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} {{ dict "envAll" . "component" "ceph" "container" "ceph-mon" "type" "readiness" "probeTemplate" (include "monReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/mon-start.sh subPath: mon-start.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/mon-stop.sh subPath: mon-stop.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/mon-check.sh subPath: mon-check.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/checkObjectReplication.py subPath: utils-checkObjectReplication.py readOnly: true - name: ceph-mon-bin mountPath: /tmp/utils-checkDNS.sh subPath: utils-checkDNS.sh readOnly: true - name: ceph-mon-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true - name: ceph-mon-keyring mountPath: /etc/ceph/ceph.mon.keyring.seed subPath: ceph.mon.keyring readOnly: true - name: ceph-bootstrap-osd-keyring mountPath: /var/lib/ceph/bootstrap-osd/ceph.keyring subPath: ceph.keyring readOnly: true - name: ceph-bootstrap-mds-keyring mountPath: /var/lib/ceph/bootstrap-mds/ceph.keyring subPath: ceph.keyring readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false - name: pod-var-log mountPath: /var/log/ceph readOnly: false volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: pod-etc-ceph emptyDir: {} - name: pod-var-log emptyDir: {} - name: ceph-mon-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-mon-etc configMap: name: {{ $configMapName }} defaultMode: 0444 - name: pod-var-lib-ceph hostPath: path: {{ .Values.conf.storage.mon.directory }} - name: pod-var-lib-ceph-crash hostPath: path: /var/lib/openstack-helm/ceph/crash type: DirectoryOrCreate - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} - name: ceph-mon-keyring secret: secretName: {{ .Values.secrets.keyrings.mon }} - name: ceph-bootstrap-osd-keyring secret: secretName: {{ .Values.secrets.keyrings.osd }} - name: ceph-bootstrap-mds-keyring secret: secretName: {{ .Values.secrets.keyrings.mds }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_mon }} {{- $daemonset := .Values.daemonset.prefix_name }} {{- $configMapName := (printf "%s-%s" .Release.Name "etc") }} {{- $serviceAccountName := (printf "%s" .Release.Name) }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "ceph.mon.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "ceph.mon.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "ceph.utils.mon_daemonset_overrides" }} {{- end }} ================================================ FILE: ceph-mon/templates/deployment-mgr.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "mgrLivenessProbeTemplate" -}} exec: command: - /tmp/mgr-check.sh {{- end }} {{- define "mgrReadinessProbeTemplate" -}} exec: command: - /tmp/mgr-check.sh {{- end }} {{- if and .Values.manifests.deployment_mgr (and .Values.deployment.ceph .Values.conf.features.mgr ) }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-mgr" }} # This protective IF prevents an attempt of repeated creation # of ceph-mgr service account. # To be considered: the separation of SA and Deployment manifests. {{- if .Values.manifests.deployment_mgr_sa }} {{ tuple $envAll "mgr" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- end }} --- kind: Deployment apiVersion: apps/v1 metadata: name: ceph-mgr annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.mgr }} selector: matchLabels: {{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} strategy: type: {{ .Values.pod.updateStrategy.mgr.type }} template: metadata: labels: {{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "ceph-mgr" "containerNames" (list "ceph-mgr" "ceph-init-dirs") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "mgr" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ tuple $envAll "mgr" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} nodeSelector: {{ .Values.labels.mgr.node_selector_key }}: {{ .Values.labels.mgr.node_selector_value }} hostNetwork: true hostPID: true dnsPolicy: {{ .Values.pod.dns_policy }} initContainers: {{ tuple $envAll "mgr" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-init-dirs {{ tuple $envAll "ceph_mgr" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "mgr" "container" "init_dirs" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/init-dirs.sh env: - name: CLUSTER value: "ceph" volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/init-dirs.sh subPath: init-dirs.sh readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false containers: - name: ceph-mgr {{ tuple $envAll "ceph_mgr" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.mgr | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "mgr" "container" "mgr" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} {{- if .Values.ceph_mgr_enabled_modules }} - name: ENABLED_MODULES value: |- {{- range $value := .Values.ceph_mgr_enabled_modules }} {{ $value }} {{- end }} {{- end }} {{- if .Values.ceph_mgr_modules_config }} {{- range $module,$params := .Values.ceph_mgr_modules_config }} {{- range $key, $value := $params }} - name: {{ $module }}_{{ $key }} value: {{ $value | quote }} {{- end }} {{- end }} {{- end }} command: - /mgr-start.sh ports: - name: mgr containerPort: {{ tuple "ceph_mgr" "internal" "mgr" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if (has "prometheus" .Values.ceph_mgr_enabled_modules) }} - name: metrics containerPort: {{ tuple "ceph_mgr" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ end -}} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /mgr-start.sh subPath: mgr-start.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/mgr-check.sh subPath: mgr-check.sh readOnly: true - name: ceph-mon-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-mon-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true - name: ceph-bootstrap-mgr-keyring mountPath: /var/lib/ceph/bootstrap-mgr/ceph.keyring subPath: ceph.keyring readOnly: false - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false - name: ceph-mon-bin mountPath: /tmp/utils-checkPGs.py subPath: utils-checkPGs.py readOnly: true {{ dict "envAll" . "component" "ceph" "container" "ceph-mgr" "type" "liveness" "probeTemplate" (include "mgrLivenessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} {{ dict "envAll" . "component" "ceph" "container" "ceph-mgr" "type" "readiness" "probeTemplate" (include "mgrReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: pod-etc-ceph emptyDir: {} - name: ceph-mon-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-mon-etc configMap: name: {{ printf "%s-%s" $envAll.Release.Name "etc" | quote }} defaultMode: 0444 - name: pod-var-lib-ceph emptyDir: {} - name: pod-var-lib-ceph-crash hostPath: path: /var/lib/openstack-helm/ceph/crash type: DirectoryOrCreate - name: ceph-mon-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} - name: ceph-bootstrap-mgr-keyring secret: secretName: {{ .Values.secrets.keyrings.mgr }} {{- end }} ================================================ FILE: ceph-mon/templates/deployment-moncheck.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.deployment_moncheck .Values.deployment.ceph }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-mon-check" }} {{ tuple $envAll "moncheck" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- kind: Deployment apiVersion: apps/v1 metadata: name: ceph-mon-check annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.mon_check }} selector: matchLabels: {{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-mon-check" "containerNames" (list "ceph-mon" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "moncheck" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ tuple $envAll "mon_check" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} nodeSelector: {{ .Values.labels.mon.node_selector_key }}: {{ .Values.labels.mon.node_selector_value }} initContainers: {{ tuple $envAll "moncheck" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-mon {{ tuple $envAll "ceph_mon_check" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.moncheck | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "moncheck" "container" "ceph_mon" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: K8S_HOST_NETWORK value: "1" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} command: - /tmp/moncheck-start.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/moncheck-start.sh subPath: moncheck-start.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/moncheck-reap-zombies.py subPath: moncheck-reap-zombies.py readOnly: true - name: ceph-mon-bin mountPath: /tmp/utils-checkDNS.sh subPath: utils-checkDNS.sh readOnly: true - name: ceph-mon-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true - name: ceph-mon-keyring mountPath: /etc/ceph/ceph.mon.keyring subPath: ceph.mon.keyring readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: pod-etc-ceph emptyDir: {} - name: ceph-mon-etc configMap: name: {{ printf "%s-%s" $envAll.Release.Name "etc" | quote }} defaultMode: 0444 - name: ceph-mon-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: pod-var-lib-ceph emptyDir: {} - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} - name: ceph-mon-keyring secret: secretName: {{ .Values.secrets.keyrings.mon }} {{- end }} ================================================ FILE: ceph-mon/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ceph-mon/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-bootstrap labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-bootstrap" "containerNames" (list "ceph-bootstrap" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "bootstrap" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-bootstrap {{ tuple $envAll "ceph_bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "ceph_bootstrap" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true - name: ceph-mon-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-mon-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-mon-etc configMap: name: {{ printf "%s-%s" $envAll.Release.Name "etc" | quote }} defaultMode: 0444 - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} {{- end }} ================================================ FILE: ceph-mon/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ceph-mon" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: ceph-mon/templates/job-keyring.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_keyring .Values.deployment.storage_secrets }} {{- $envAll := . }} {{- range $key1, $cephBootstrapKey := tuple "mds" "osd" "mon" "mgr" }} {{- $component := print $cephBootstrapKey "-keyring-generator" }} {{- $jobName := print "ceph-" $component }} {{- $serviceAccountName := $jobName }} {{ tuple $envAll "job_keyring_generator" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - create - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ $jobName }} labels: {{ tuple $envAll "ceph" $jobName | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" $jobName | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" $jobName "containerNames" (list $jobName "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "ceph" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ $envAll.Values.labels.job.node_selector_key }}: {{ $envAll.Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "job_keyring_generator" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: {{ $jobName }} {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.secret_provisioning | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ceph" "container" $jobName | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: DEPLOYMENT_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: CEPH_GEN_DIR value: /tmp - name: CEPH_TEMPLATES_DIR value: /tmp/templates {{- if eq $cephBootstrapKey "mon" }} - name: CEPH_KEYRING_NAME value: ceph.mon.keyring - name: CEPH_KEYRING_TEMPLATE value: mon.keyring {{- else }} - name: CEPH_KEYRING_NAME value: ceph.keyring - name: CEPH_KEYRING_TEMPLATE value: bootstrap.keyring.{{ $cephBootstrapKey }} {{- end }} - name: KUBE_SECRET_NAME value: {{ index $envAll.Values.secrets.keyrings $cephBootstrapKey }} command: - /tmp/keys-bootstrap-keyring-manager.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/keys-bootstrap-keyring-manager.sh subPath: keys-bootstrap-keyring-manager.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/keys-bootstrap-keyring-generator.py subPath: keys-bootstrap-keyring-generator.py readOnly: true - name: ceph-templates mountPath: /tmp/templates readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-mon-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-templates configMap: name: {{ printf "%s-%s" $envAll.Release.Name "templates" | quote }} defaultMode: 0444 {{- end }} {{- end }} ================================================ FILE: ceph-mon/templates/job-post-apply.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if eq .Values.pod.lifecycle.upgrades.daemonsets.pod_replacement_strategy "OnDelete" }} {{- if and .Values.manifests.job_post_apply }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "post-apply" }} {{ tuple $envAll "post-apply" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - '' resources: - pods - events - jobs - pods/exec verbs: - create - get - delete - list - apiGroups: - 'apps' resources: - daemonsets verbs: - get - list - apiGroups: - 'batch' resources: - jobs verbs: - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- apiVersion: batch/v1 kind: Job metadata: name: {{ $serviceAccountName }} labels: {{ tuple $envAll "ceph-upgrade" "post-apply" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph-upgrade" "post-apply" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "ceph-mon-post-apply" "containerNames" (list "ceph-mon-post-apply" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "post_apply" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "post-apply" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-mon-post-apply {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "post_apply" "container" "ceph_mon_post_apply" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: CEPH_NAMESPACE value: {{ .Release.Namespace }} - name: RELEASE_GROUP_NAME value: {{ .Release.Name }} - name: UNCONDITIONAL_MON_RESTART value: {{ .Values.conf.storage.unconditional_mon_restart | quote }} command: - /tmp/post-apply.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/post-apply.sh subPath: post-apply.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/wait-for-pods.sh subPath: wait-for-pods.sh readOnly: true - name: ceph-mon-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-mon-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-mon-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-mon-etc configMap: name: {{ printf "%s-%s" $envAll.Release.Name "etc" | quote }} defaultMode: 0444 - name: ceph-mon-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} {{- end }} {{- end }} ================================================ FILE: ceph-mon/templates/job-storage-admin-keys.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_storage_admin_keys .Values.deployment.storage_secrets }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-storage-keys-generator" }} {{ tuple $envAll "storage_keys_generator" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - pods - pods/exec - secrets verbs: - get - create - patch - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-storage-keys-generator labels: {{ tuple $envAll "ceph" "storage-keys-generator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "storage-keys-generator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "ceph-storage-keys-generator" "containerNames" (list "ceph-storage-keys-generator" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "storage_keys_generator" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ $envAll.Values.labels.job.node_selector_key }}: {{ $envAll.Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "storage_keys_generator" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-storage-keys-generator {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.secret_provisioning | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "storage_keys_generator" "container" "ceph_storage_keys_generator" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: DEPLOYMENT_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: CEPH_GEN_DIR value: /tmp - name: CEPH_TEMPLATES_DIR value: /tmp/templates - name: CEPH_KEYRING_NAME value: ceph.client.admin.keyring - name: CEPH_KEYRING_TEMPLATE value: admin.keyring - name: CEPH_KEYRING_ADMIN_NAME value: {{ .Values.secrets.keyrings.admin }} - name: CEPH_STORAGECLASS_ADMIN_SECRET_NAME value: {{ .Values.storageclass.rbd.parameters.adminSecretName }} - name: CEPH_STORAGECLASS_ADMIN_SECRET_NAME_NODE value: {{ .Values.storageclass.rbd.parameters.adminSecretNameNode }} command: - /tmp/keys-storage-keyring-manager.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-mon-bin mountPath: /tmp/keys-storage-keyring-manager.sh subPath: keys-storage-keyring-manager.sh readOnly: true - name: ceph-mon-bin mountPath: /tmp/keys-bootstrap-keyring-generator.py subPath: keys-bootstrap-keyring-generator.py readOnly: true - name: ceph-templates mountPath: /tmp/templates readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-mon-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-templates configMap: name: {{ printf "%s-%s" $envAll.Release.Name "templates" | quote }} defaultMode: 0444 {{- end }} ================================================ FILE: ceph-mon/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: ceph-mon/templates/service-mgr.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_mgr ( and .Values.deployment.ceph .Values.conf.features.mgr ) }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.ceph_mgr }} --- apiVersion: v1 kind: Service metadata: name: ceph-mgr labels: {{ tuple $envAll "ceph" "manager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: ports: - name: ceph-mgr port: {{ tuple "ceph_mgr" "internal" "mgr" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: {{ tuple "ceph_mgr" "internal" "mgr" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if (has "prometheus" .Values.ceph_mgr_enabled_modules) }} - name: metrics protocol: TCP port: {{ tuple "ceph_mgr" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ end }} selector: {{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: ceph-mon/templates/service-mon-discovery.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_mon_discovery .Values.deployment.ceph }} {{- $envAll := . }} --- kind: Service apiVersion: v1 metadata: name: {{ tuple "ceph_mon" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: mon port: {{ tuple "ceph_mon" "discovery" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: {{ tuple "ceph_mon" "discovery" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: mon-msgr2 port: {{ tuple "ceph_mon" "discovery" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: {{ tuple "ceph_mon" "discovery" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{- if .Values.manifests.daemonset_mon }} {{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- else }} app: rook-ceph-mon ceph_daemon_type: mon {{- end }} clusterIP: None publishNotReadyAddresses: true {{- end }} ================================================ FILE: ceph-mon/templates/service-mon.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_mon .Values.deployment.ceph }} {{- $envAll := . }} --- kind: Service apiVersion: v1 metadata: name: {{ tuple "ceph_mon" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: mon port: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: mon-msgr2 port: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} clusterIP: None {{- end }} ================================================ FILE: ceph-mon/templates/snippets/_mon_host_from_k8s_ep.sh.tpl ================================================ {{- define "ceph-mon.snippets.mon_host_from_k8s_ep" -}} {{/* Inserts a bash function definition mon_host_from_k8s_ep() which can be used to construct a mon_hosts value from the given namespaced endpoint. Usage (e.g. in _script.sh.tpl): #!/bin/bash : "${NS:=ceph}" : "${EP:=ceph-mon-discovery}" {{ include "ceph-mon.snippets.mon_host_from_k8s_ep" . }} MON_HOST=$(mon_host_from_k8s_ep "$NS" "$EP") if [ -z "$MON_HOST" ]; then # deal with failure else sed -i -e "s/^mon_host = /mon_host = $MON_HOST/" /etc/ceph/ceph.conf fi */}} {{` # Construct a mon_hosts value from the given namespaced endpoint # IP x.x.x.x with port p named "mon-msgr2" will appear as [v2:x.x.x.x/p/0] # IP x.x.x.x with port q named "mon" will appear as [v1:x.x.x.x/q/0] # IP x.x.x.x with ports p and q will appear as [v2:x.x.x.x/p/0,v1:x.x.x.x/q/0] # The entries for all IPs will be joined with commas mon_host_from_k8s_ep() { local ns=$1 local ep=$2 if [ -z "$ns" ] || [ -z "$ep" ]; then return 1 fi # We don't want shell expansion for the go-template expression # shellcheck disable=SC2016 kubectl get endpoints -n "$ns" "$ep" -o go-template=' {{- $sep := "" }} {{- range $_,$s := .subsets }} {{- $v2port := 0 }} {{- $v1port := 0 }} {{- range $_,$port := index $s "ports" }} {{- if (eq $port.name "mon-msgr2") }} {{- $v2port = $port.port }} {{- else if (eq $port.name "mon") }} {{- $v1port = $port.port }} {{- end }} {{- end }} {{- range $_,$address := index $s "addresses" }} {{- $v2endpoint := printf "v2:%s:%d/0" $address.ip $v2port }} {{- $v1endpoint := printf "v1:%s:%d/0" $address.ip $v1port }} {{- if (and $v2port $v1port) }} {{- printf "%s[%s,%s]" $sep $v2endpoint $v1endpoint }} {{- $sep = "," }} {{- else if $v2port }} {{- printf "%s[%s]" $sep $v2endpoint }} {{- $sep = "," }} {{- else if $v1port }} {{- printf "%s[%s]" $sep $v1endpoint }} {{- $sep = "," }} {{- end }} {{- end }} {{- end }}' } `}} {{- end -}} ================================================ FILE: ceph-mon/templates/utils/_mon_daemonset_overrides.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ceph.utils.match_exprs_hash" }} {{- $match_exprs := index . 0 }} {{- $context := index . 1 }} {{- $_ := set $context.Values "__match_exprs_hash_content" "" }} {{- range $match_expr := $match_exprs }} {{- $_ := set $context.Values "__match_exprs_hash_content" (print $context.Values.__match_exprs_hash_content $match_expr.key $match_expr.operator ($match_expr.values | quote)) }} {{- end }} {{- $context.Values.__match_exprs_hash_content | sha256sum | trunc 8 }} {{- $_ := unset $context.Values "__match_exprs_hash_content" }} {{- end }} {{- define "ceph.utils.mon_daemonset_overrides" }} {{- $daemonset := index . 0 }} {{- $daemonset_yaml := index . 1 }} {{- $configmap_include := index . 2 }} {{- $configmap_name := index . 3 }} {{- $context := index . 4 }} {{- $_ := unset $context ".Files" }} {{- $_ := set $context.Values "__daemonset_yaml" $daemonset_yaml }} {{- $daemonset_root_name := printf "ceph_%s" $daemonset }} {{- $_ := set $context.Values "__daemonset_list" list }} {{- $_ := set $context.Values "__default" dict }} {{- if hasKey $context.Values.conf "overrides" }} {{- range $key, $val := $context.Values.conf.overrides }} {{- if eq $key $daemonset_root_name }} {{- range $type, $type_data := . }} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{/* dictionary that will contain all info needed to generate this iteration of the daemonset */}} {{- $current_dict := dict }} {{/* set daemonset name */}} {{- $_ := set $current_dict "name" $host_data.name }} {{/* apply overrides */}} {{- $override_conf_copy := $host_data.conf }} {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}} {{- $root_conf_copy := omit ($context.Values.conf | toYaml | fromYaml) "overrides" }} {{- $merged_dict := mergeOverwrite $root_conf_copy $override_conf_copy }} {{- $root_conf_copy2 := dict "conf" $merged_dict }} {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "conf") "__daemonset_list" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $current_dict "nodeData" $root_conf_copy4 }} {{/* Schedule to this host explicitly. */}} {{- $nodeSelector_dict := dict }} {{- $_ := set $nodeSelector_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $nodeSelector_dict "operator" "In" }} {{- $values_list := list $host_data.name }} {{- $_ := set $nodeSelector_dict "values" $values_list }} {{- $list_aggregate := list $nodeSelector_dict }} {{- $_ := set $current_dict "matchExpressions" $list_aggregate }} {{/* store completed daemonset entry/info into global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $current_dict }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- end }} {{- end }} {{- if eq $type "labels" }} {{- $_ := set $context.Values "__label_list" . }} {{- range $label_data := . }} {{/* dictionary that will contain all info needed to generate this iteration of the daemonset. */}} {{- $_ := set $context.Values "__current_label" dict }} {{/* set daemonset name */}} {{- $_ := set $context.Values.__current_label "name" $label_data.label.key }} {{/* apply overrides */}} {{- $override_conf_copy := $label_data.conf }} {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}} {{- $root_conf_copy := omit ($context.Values.conf | toYaml | fromYaml) "overrides" }} {{- $merged_dict := mergeOverwrite $root_conf_copy $override_conf_copy }} {{- $root_conf_copy2 := dict "conf" $merged_dict }} {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "conf") "__daemonset_list" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__current_label "nodeData" $root_conf_copy4 }} {{/* Schedule to the provided label value(s) */}} {{- $label_dict := omit $label_data.label "NULL" }} {{- $_ := set $label_dict "operator" "In" }} {{- $list_aggregate := list $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{/* Do not schedule to other specified labels, with higher precedence as the list position increases. Last defined label is highest priority. */}} {{- $other_labels := without $context.Values.__label_list $label_data }} {{- range $label_data2 := $other_labels }} {{- $label_dict := omit $label_data2.label "NULL" }} {{- $_ := set $label_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{- end }} {{- $_ := set $context.Values "__label_list" $other_labels }} {{/* Do not schedule to any other specified hosts */}} {{- range $type, $type_data := $val }} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{- $label_dict := dict }} {{- $_ := set $label_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $label_dict "operator" "NotIn" }} {{- $values_list := list $host_data.name }} {{- $_ := set $label_dict "values" $values_list }} {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{- end }} {{/* store completed daemonset entry/info into global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__current_label }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- $_ := unset $context.Values "__current_label" }} {{- end }} {{- end }} {{- end }} {{/* scheduler exceptions for the default daemonset */}} {{- $_ := set $context.Values.__default "matchExpressions" list }} {{- range $type, $type_data := . }} {{/* Do not schedule to other specified labels */}} {{- if eq $type "labels" }} {{- range $label_data := . }} {{- $default_dict := omit $label_data.label "NULL" }} {{- $_ := set $default_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }} {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{/* Do not schedule to other specified hosts */}} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{- $default_dict := dict }} {{- $_ := set $default_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $default_dict "operator" "NotIn" }} {{- $values_list := list $host_data.name }} {{- $_ := set $default_dict "values" $values_list }} {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }} {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{/* generate the default daemonset */}} {{/* set name */}} {{- $_ := set $context.Values.__default "name" "default" }} {{/* no overrides apply, so copy as-is */}} {{- $root_conf_copy1 := omit $context.Values.conf "overrides" }} {{- $root_conf_copy2 := dict "conf" $root_conf_copy1 }} {{- $context_values := omit $context.Values "conf" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__default "nodeData" $root_conf_copy4 }} {{/* add to global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__default }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- $_ := set $context.Values "__last_configmap_name" $configmap_name }} {{- range $current_dict := $context.Values.__daemonset_list }} {{- $context_novalues := omit $context "Values" }} {{- $merged_dict := mergeOverwrite $context_novalues $current_dict.nodeData }} {{- $_ := set $current_dict "nodeData" $merged_dict }} {{/* name needs to be a DNS-1123 compliant name. Ensure lower case */}} {{- $name_format1 := printf (print $daemonset_root_name "-" $current_dict.name) | lower }} {{/* labels may contain underscores which would be invalid here, so we replace them with dashes there may be other valid label names which would make for an invalid DNS-1123 name but these will be easier to handle in future with sprig regex* functions (not availabile in helm 2.5.1) */}} {{- $name_format2 := $name_format1 | replace "_" "-" | replace "." "-" }} {{/* To account for the case where the same label is defined multiple times in overrides (but with different label values), we add a sha of the scheduling data to ensure name uniqueness */}} {{- $_ := set $current_dict "dns_1123_name" dict }} {{- if hasKey $current_dict "matchExpressions" }} {{- $_ := set $current_dict "dns_1123_name" (printf (print $name_format2 "-" (list $current_dict.matchExpressions $context | include "ceph.utils.match_exprs_hash"))) }} {{- else }} {{- $_ := set $current_dict "dns_1123_name" $name_format2 }} {{- end }} {{/* set daemonset metadata name */}} {{- if not $context.Values.__daemonset_yaml.metadata }}{{- $_ := set $context.Values.__daemonset_yaml "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.metadata.name }}{{- $_ := set $context.Values.__daemonset_yaml.metadata "name" dict }}{{- end }} {{- $_ := set $context.Values.__daemonset_yaml.metadata "name" $current_dict.dns_1123_name }} {{/* cross-reference configmap name to container volume definitions */}} {{- $_ := set $context.Values "__volume_list" list }} {{- range $current_volume := $context.Values.__daemonset_yaml.spec.template.spec.volumes }} {{- $_ := set $context.Values "__volume" $current_volume }} {{- if hasKey $context.Values.__volume "configMap" }} {{- if eq $context.Values.__volume.configMap.name $context.Values.__last_configmap_name }} {{- $_ := set $context.Values.__volume.configMap "name" $current_dict.dns_1123_name }} {{- end }} {{- end }} {{- $updated_list := append $context.Values.__volume_list $context.Values.__volume }} {{- $_ := set $context.Values "__volume_list" $updated_list }} {{- end }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "volumes" $context.Values.__volume_list }} {{/* populate scheduling restrictions */}} {{- if hasKey $current_dict "matchExpressions" }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "affinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity "nodeAffinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity "requiredDuringSchedulingIgnoredDuringExecution" dict }}{{- end }} {{- $match_exprs := dict }} {{- $_ := set $match_exprs "matchExpressions" $current_dict.matchExpressions }} {{- $appended_match_expr := list $match_exprs }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution "nodeSelectorTerms" $appended_match_expr }} {{- end }} {{/* input value hash for current set of values overrides */}} {{- if not $context.Values.__daemonset_yaml.spec }}{{- $_ := set $context.Values.__daemonset_yaml "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template }}{{- $_ := set $context.Values.__daemonset_yaml.spec "template" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata.annotations }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata "annotations" dict }}{{- end }} {{- $cmap := list $current_dict.dns_1123_name $current_dict.nodeData | include $configmap_include }} {{- $values_hash := $cmap | quote | sha256sum }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata.annotations "configmap-etc-hash" $values_hash }} {{/* generate configmap */}} --- {{ $cmap }} {{/* generate daemonset yaml */}} {{ range $k, $v := index $current_dict.nodeData.Values.conf.storage "mon" }} --- {{- $_ := set $context.Values "__tmpYAML" dict }} {{ $dsNodeName := index $context.Values.__daemonset_yaml.metadata "name" }} {{ $localDsNodeName := print (trunc 54 $current_dict.dns_1123_name) "-" (print $dsNodeName $k | quote | sha256sum | trunc 8) }} {{- if not $context.Values.__tmpYAML.metadata }}{{- $_ := set $context.Values.__tmpYAML "metadata" dict }}{{- end }} {{- $_ := set $context.Values.__tmpYAML.metadata "name" $localDsNodeName }} {{ merge $context.Values.__tmpYAML $context.Values.__daemonset_yaml | toYaml }} {{ end }} --- {{- $_ := set $context.Values "__last_configmap_name" $current_dict.dns_1123_name }} {{- end }} {{- end }} ================================================ FILE: ceph-mon/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for ceph-mon. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- deployment: ceph: true storage_secrets: true images: pull_policy: IfNotPresent tags: ceph_bootstrap: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_config_helper: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' ceph_mon: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_mgr: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_mon_check: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' image_repo_sync: 'quay.io/airshipit/docker:27.5.0' local_registry: active: false exclude: - dep_check - image_repo_sync labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled mon: node_selector_key: ceph-mon node_selector_value: enabled mgr: node_selector_key: ceph-mgr node_selector_value: enabled pod: security_context: mon: pod: runAsUser: 65534 container: ceph_init_dirs: runAsUser: 0 readOnlyRootFilesystem: true ceph_log_ownership: runAsUser: 0 readOnlyRootFilesystem: true ceph_mon: runAsUser: 64045 readOnlyRootFilesystem: true allowPrivilegeEscalation: false mgr: pod: runAsUser: 65534 container: init_dirs: runAsUser: 0 readOnlyRootFilesystem: true mgr: runAsUser: 64045 readOnlyRootFilesystem: true allowPrivilegeEscalation: false moncheck: pod: runAsUser: 65534 container: ceph_mon: allowPrivilegeEscalation: false readOnlyRootFilesystem: true bootstrap: pod: runAsUser: 65534 container: ceph_bootstrap: allowPrivilegeEscalation: false readOnlyRootFilesystem: true storage_keys_generator: pod: runAsUser: 65534 container: ceph_storage_keys_generator: allowPrivilegeEscalation: false readOnlyRootFilesystem: true ceph: pod: runAsUser: 65534 container: ceph-mds-keyring-generator: allowPrivilegeEscalation: false readOnlyRootFilesystem: true ceph-mgr-keyring-generator: allowPrivilegeEscalation: false readOnlyRootFilesystem: true ceph-mon-keyring-generator: allowPrivilegeEscalation: false readOnlyRootFilesystem: true ceph-osd-keyring-generator: allowPrivilegeEscalation: false readOnlyRootFilesystem: true post_apply: pod: runAsUser: 65534 container: ceph_mon_post_apply: allowPrivilegeEscalation: false readOnlyRootFilesystem: true dns_policy: "ClusterFirstWithHostNet" replicas: mgr: 2 mon_check: 1 lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate mon: enabled: true min_ready_seconds: 0 max_unavailable: 1 updateStrategy: mgr: type: Recreate affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 resources: enabled: false mon: requests: memory: "50Mi" cpu: "250m" limits: memory: "100Mi" cpu: "500m" mgr: requests: memory: "5Mi" cpu: "250m" limits: memory: "50Mi" cpu: "500m" mon_check: requests: memory: "5Mi" cpu: "250m" limits: memory: "50Mi" cpu: "500m" jobs: bootstrap: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" secret_provisioning: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tolerations: mgr: tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 60 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 60 mon_check: tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 60 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 60 probes: ceph: ceph-mon: readiness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 60 timeoutSeconds: 5 liveness: enabled: true params: initialDelaySeconds: 360 periodSeconds: 180 timeoutSeconds: 5 ceph-mgr: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 5 liveness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 5 secrets: keyrings: mon: ceph-mon-keyring mds: ceph-bootstrap-mds-keyring osd: ceph-bootstrap-osd-keyring mgr: ceph-bootstrap-mgr-keyring admin: ceph-client-admin-keyring oci_image_registry: ceph-mon: ceph-mon-oci-image-registry-key network: public: 192.168.0.0/16 cluster: 192.168.0.0/16 conf: features: mgr: true templates: keyring: admin: | [client.admin] key = {{ key }} auid = 0 caps mds = "allow" caps mon = "allow *" caps osd = "allow *" caps mgr = "allow *" mon: | [mon.] key = {{ key }} caps mon = "allow *" bootstrap: mds: | [client.bootstrap-mds] key = {{ key }} caps mon = "allow profile bootstrap-mds" mgr: | [client.bootstrap-mgr] key = {{ key }} caps mgr = "allow profile bootstrap-mgr" osd: | [client.bootstrap-osd] key = {{ key }} caps mon = "allow rw" ceph: global: # auth cephx: true cephx_require_signatures: false cephx_cluster_require_signatures: true cephx_service_require_signatures: false objecter_inflight_op_bytes: "1073741824" objecter_inflight_ops: 10240 debug_ms: "0/0" mon_osd_down_out_interval: 1800 mon_osd_down_out_subtree_limit: root mon_osd_min_in_ratio: 0 mon_osd_min_up_ratio: 0 mon_data_avail_warn: 15 log_file: /dev/stdout mon_cluster_log_file: /dev/stdout # Beginning with the Pacific release, this config setting is necessary # to allow pools to use 1x replication, which is disabled by default. The # openstack-helm gate scripts use 1x replication for automated testing, # so this is required. It doesn't seem to be sufficient to add this to # /etc/ceph/ceph.conf, however. It must also be set explicitly via the # 'ceph config' command, so this must also be added to the # cluster_commands value in the ceph-client chart so it will be set # before pools are created and configured there. mon_allow_pool_size_one: true osd: osd_mkfs_type: xfs osd_mkfs_options_xfs: -f -i size=2048 osd_max_object_name_len: 256 ms_bind_port_min: 6800 ms_bind_port_max: 7100 osd_snap_trim_priority: 1 osd_snap_trim_sleep: 0.1 osd_pg_max_concurrent_snap_trims: 1 filestore_merge_threshold: -10 filestore_split_multiple: 12 filestore_max_sync_interval: 10 osd_scrub_begin_hour: 22 osd_scrub_end_hour: 4 osd_scrub_during_recovery: false osd_scrub_sleep: 0.1 osd_scrub_chunk_min: 1 osd_scrub_chunk_max: 4 osd_scrub_load_threshold: 10.0 osd_deep_scrub_stride: "1048576" osd_scrub_priority: 1 osd_recovery_op_priority: 1 osd_recovery_max_active: 1 osd_mount_options_xfs: "rw,noatime,largeio,inode64,swalloc,logbufs=8,logbsize=256k,allocsize=4M" osd_journal_size: 10240 storage: mon: directory: /var/lib/openstack-helm/ceph/mon # The post-apply job will try to determine if mons need to be restarted # and only restart them if necessary. Set this value to "true" to restart # mons unconditionally. unconditional_mon_restart: "false" daemonset: prefix_name: "mon" dependencies: dynamic: common: local_image_registry: jobs: - ceph-mon-image-repo-sync services: - endpoint: node service: local_image_registry static: bootstrap: jobs: null services: - endpoint: internal service: ceph_mon job_keyring_generator: jobs: null mon: jobs: - ceph-storage-keys-generator - ceph-mon-keyring-generator mgr: jobs: - ceph-storage-keys-generator - ceph-mgr-keyring-generator services: - endpoint: internal service: ceph_mon moncheck: jobs: - ceph-storage-keys-generator - ceph-mon-keyring-generator services: - endpoint: discovery service: ceph_mon storage_keys_generator: jobs: null image_repo_sync: services: - endpoint: internal service: local_image_registry bootstrap: enabled: false script: | ceph -s function ensure_pool () { ceph osd pool stats $1 || ceph osd pool create $1 $2 if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 12 ]]; then ceph osd pool application enable $1 $3 fi } #ensure_pool volumes 8 cinder # Uncomment below to enable mgr modules # For a list of available modules: # http://docs.ceph.com/docs/master/mgr/ # This overrides mgr_initial_modules (default: restful, status) # Any module not listed here will be disabled ceph_mgr_enabled_modules: - restful - status - prometheus - balancer - iostat - pg_autoscaler # You can configure your mgr modules # below. Each module has its own set # of key/value. Refer to the doc # above for more info. For example: ceph_mgr_modules_config: # balancer: # active: 1 # prometheus: # server_port: 9283 # server_addr: 0.0.0.0 # dashboard: # port: 7000 # localpool: # failure_domain: host # subtree: rack # pg_num: "128" # num_rep: "3" # min_size: "2" # if you change provision_storage_class to false # it is presumed you manage your own storage # class definition externally # We iterate over each storageclass parameters # and derive the manifest. storageclass: rbd: parameters: adminSecretName: pvc-ceph-conf-combined-storageclass adminSecretNameNode: pvc-ceph-conf-combined-storageclass cephfs: provision_storage_class: true provisioner: ceph.com/cephfs metadata: name: cephfs parameters: adminId: admin userSecretName: pvc-ceph-cephfs-client-key adminSecretName: pvc-ceph-conf-combined-storageclass adminSecretNamespace: ceph endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ceph-mon: username: ceph-mon password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null ceph_mon: namespace: null hosts: default: ceph-mon discovery: ceph-mon-discovery host_fqdn_override: default: null port: mon: default: 6789 mon_msgr2: default: 3300 ceph_mgr: namespace: null hosts: default: ceph-mgr host_fqdn_override: default: null port: mgr: default: 7000 metrics: default: 9283 scheme: default: http monitoring: prometheus: enabled: true ceph_mgr: scrape: true port: 9283 manifests: configmap_bin: true configmap_etc: true configmap_templates: true daemonset_mon: true deployment_mgr: true deployment_mgr_sa: true deployment_moncheck: true job_image_repo_sync: true job_bootstrap: true job_keyring: true job_post_apply: true service_mon: true service_mgr: true service_mon_discovery: true job_storage_admin_keys: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ceph-osd/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Ceph OSD name: ceph-osd version: 2025.2.0 home: https://github.com/ceph/ceph dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ceph-osd/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: ceph-osd/templates/bin/_helm-tests.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex function check_osd_count() { echo "#### Start: Checking OSD count ####" noup_flag=$(ceph osd stat | awk '/noup/ {print $2}') osd_stat=$(ceph osd stat -f json-pretty) num_osd=$(awk '/"num_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) num_in_osds=$(awk '/"num_in_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) num_up_osds=$(awk '/"num_up_osds"/{print $2}' <<< "$osd_stat" | cut -d, -f1) MIN_OSDS=$((${num_osd}*$REQUIRED_PERCENT_OF_OSDS/100)) if [ ${MIN_OSDS} -lt 1 ]; then MIN_OSDS=1 fi if [ "${noup_flag}" ]; then osd_status=$(ceph osd dump -f json | jq -c '.osds[] | .state') count=0 for osd in $osd_status; do if [[ "$osd" == *"up"* || "$osd" == *"new"* ]]; then ((count=count+1)) fi done echo "Caution: noup flag is set. ${count} OSDs in up/new state. Required number of OSDs: ${MIN_OSDS}." ceph -s exit 0 else if [ "${num_osd}" -eq 0 ]; then echo "There are no osds in the cluster" elif [ "${num_in_osds}" -ge "${MIN_OSDS}" ] && [ "${num_up_osds}" -ge "${MIN_OSDS}" ]; then echo "Required number of OSDs (${MIN_OSDS}) are UP and IN status" ceph -s exit 0 else echo "Required number of OSDs (${MIN_OSDS}) are NOT UP and IN status. Cluster shows OSD count=${num_osd}, UP=${num_up_osds}, IN=${num_in_osds}" fi fi } # in case the chart has been re-installed in order to make changes to daemonset # we do not need rack_by_rack restarts # but we need to wait until all re-installed ceph-osd pods are healthy # and there is degraded objects while true; do check_osd_count sleep 60 done ================================================ FILE: ceph-osd/templates/bin/_init-dirs.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C : "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" mkdir -p "$(dirname "${OSD_BOOTSTRAP_KEYRING}")" # Let's create the ceph directories for DIRECTORY in osd tmp crash; do mkdir -p "/var/lib/ceph/${DIRECTORY}" done # Create socket directory mkdir -p /run/ceph # Adjust the owner of all those directories chown -R ceph. /run/ceph/ /var/lib/ceph/* ================================================ FILE: ceph-osd/templates/bin/_post-apply.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} export LC_ALL=C : "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" if [[ ! -f /etc/ceph/${CLUSTER}.conf ]]; then echo "ERROR- /etc/ceph/${CLUSTER}.conf must exist; get it from your existing mon" exit 1 fi if [[ ! -f ${ADMIN_KEYRING} ]]; then echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" exit 1 fi ceph --cluster ${CLUSTER} -s function wait_for_pods() { timeout=${2:-1800} end=$(date -ud "${timeout} seconds" +%s) # Selecting containers with "ceph-osd-default" name and # counting them based on "ready" field. count_pods=".items | map(.status.containerStatuses | .[] | \ select(.name==\"ceph-osd-default\")) | \ group_by(.ready) | map({(.[0].ready | tostring): length}) | .[]" min_osds="add | if .true >= (.false + .true)*${REQUIRED_PERCENT_OF_OSDS}/100 \ then \"pass\" else \"fail\" end" while true; do # Leaving while loop if minimum amount of OSDs are ready. # It allows to proceed even if some OSDs are not ready # or in "CrashLoopBackOff" state state=$(kubectl get pods --namespace="${1}" -l component=osd -o json | jq "${count_pods}") osd_state=$(jq -s "${min_osds}" <<< "${state}") if [[ "${osd_state}" == \"pass\" ]]; then break fi sleep 5 if [ $(date -u +%s) -gt $end ] ; then echo -e "Containers failed to start after $timeout seconds\n" kubectl get pods --namespace "${1}" -o wide -l component=osd exit 1 fi done } function check_ds() { for ds in `kubectl get ds --namespace=$CEPH_NAMESPACE -l component=osd --no-headers=true|awk '{print $1}'` do ds_query=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status` if echo $ds_query |grep -i "numberAvailable" ;then currentNumberScheduled=`echo $ds_query|jq -r .currentNumberScheduled` desiredNumberScheduled=`echo $ds_query|jq -r .desiredNumberScheduled` numberAvailable=`echo $ds_query|jq -r .numberAvailable` numberReady=`echo $ds_query|jq -r .numberReady` updatedNumberScheduled=`echo $ds_query|jq -r .updatedNumberScheduled` ds_check=`echo "$currentNumberScheduled $desiredNumberScheduled $numberAvailable $numberReady $updatedNumberScheduled"| \ tr ' ' '\n'|sort -u|wc -l` if [ $ds_check != 1 ]; then echo "few pods under daemonset $ds are not yet ready" exit else echo "all pods ubder deamonset $ds are ready" fi else echo "this are no osds under daemonset $ds" fi done } function wait_for_pgs () { echo "#### Start: Checking pgs ####" pgs_ready=0 pgs_inactive=0 query='map({state: .state}) | group_by(.state) | map({state: .[0].state, count: length}) | .[] | select(.state | contains("active") | not)' if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 14 ]]; then query=".pg_stats | ${query}" fi # Loop until all pgs are active while [[ $pgs_ready -lt 3 ]]; do pgs_state=$(ceph --cluster ${CLUSTER} pg ls -f json | jq -c "${query}") if [[ $(jq -c '. | select(.state | contains("peering") | not)' <<< "${pgs_state}") ]]; then if [[ $pgs_inactive -gt 200 ]]; then # If inactive PGs aren't peering after ~10 minutes, fail echo "Failure, found inactive PGs that aren't peering" exit 1 fi (( pgs_inactive+=1 )) else pgs_inactive=0 fi if [[ "${pgs_state}" ]]; then pgs_ready=0 else (( pgs_ready+=1 )) fi sleep 30 done } function wait_for_degraded_objects () { echo "#### Start: Checking for degraded objects ####" # Loop until no degraded objects while [[ ! -z "`ceph --cluster ${CLUSTER} -s | grep 'degraded'`" ]] do sleep 30 ceph -s done } function wait_for_degraded_and_misplaced_objects () { echo "#### Start: Checking for degraded and misplaced objects ####" # Loop until no degraded or misplaced objects while [[ ! -z "`ceph --cluster ${CLUSTER} -s | grep 'degraded\|misplaced'`" ]] do sleep 30 ceph -s done } function restart_by_rack() { racks=`ceph osd tree | awk '/rack/{print $4}'` echo "Racks under ceph cluster are: $racks" for rack in $racks do hosts_in_rack=(`ceph osd tree | sed -n "/rack $rack/,/rack/p" | awk '/host/{print $4}' | tr '\n' ' '|sed 's/ *$//g'`) echo "hosts under rack "$rack" are: ${hosts_in_rack[@]}" echo "hosts count under $rack are: ${#hosts_in_rack[@]}" for host in ${hosts_in_rack[@]} do echo "host is : $host" if [[ ! -z "$host" ]]; then pods_on_host=$(kubectl get po -n "$CEPH_NAMESPACE" -l component=osd -o wide |grep "$host"|awk '{print $1}' | tr '\n' ' '|sed 's/ *$//g') echo "Restarting the pods under host $host" for pod in ${pods_on_host} do kubectl delete pod -n "$CEPH_NAMESPACE" "${pod}" || true done fi done echo "waiting for the pods under host $host from restart" # The pods will not be ready in first 60 seconds. Thus we can reduce # amount of queries to kubernetes. sleep 60 # Degraded objects won't recover with noout set unless pods come back and # PGs become healthy, so simply wait for 0 degraded objects wait_for_degraded_objects ceph -s done } if [[ "$DISRUPTIVE_OSD_RESTART" != "true" ]]; then wait_for_pods $CEPH_NAMESPACE fi require_upgrade=0 max_release=0 for ds in `kubectl get ds --namespace=$CEPH_NAMESPACE -l component=osd --no-headers=true|awk '{print $1}'` do updatedNumberScheduled=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status.updatedNumberScheduled` desiredNumberScheduled=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status.desiredNumberScheduled` if [[ $updatedNumberScheduled != $desiredNumberScheduled ]]; then if kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status|grep -i "numberAvailable" ;then require_upgrade=$((require_upgrade+1)) _release=`kubectl get ds -n $CEPH_NAMESPACE $ds -o json|jq -r .status.observedGeneration` max_release=$(( max_release > _release ? max_release : _release )) fi fi done echo "Latest revision of the helm chart(s) is : $max_release" # If flags are set that will prevent recovery, don't restart OSDs ceph -s | grep "noup\|noin\|nobackfill\|norebalance\|norecover" > /dev/null if [[ $? -ne 0 ]]; then if [[ "$UNCONDITIONAL_OSD_RESTART" == "true" ]] || [[ $max_release -gt 1 ]]; then if [[ "$UNCONDITIONAL_OSD_RESTART" == "true" ]] || [[ $require_upgrade -gt 0 ]]; then if [[ "$DISRUPTIVE_OSD_RESTART" == "true" ]]; then echo "restarting all osds simultaneously" kubectl -n $CEPH_NAMESPACE delete pod -l component=osd sleep 60 echo "waiting for pgs to become active and for degraded objects to recover" wait_for_pgs wait_for_degraded_objects ceph -s else echo "waiting for inactive pgs and degraded objects before upgrade" wait_for_pgs wait_for_degraded_and_misplaced_objects ceph -s ceph osd "set" noout echo "lets restart the osds rack by rack" restart_by_rack ceph osd "unset" noout fi fi #lets check all the ceph-osd daemonsets echo "checking DS" check_ds else echo "No revisions found for upgrade" fi else echo "Skipping OSD restarts because flags are set that would prevent recovery" fi ================================================ FILE: ceph-osd/templates/bin/osd/_check.sh.tpl ================================================ #!/bin/sh # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # A liveness check for ceph OSDs: exit 0 if # all OSDs on this host are in the "active" state # per their admin sockets. SOCKDIR=${CEPH_SOCKET_DIR:-/run/ceph} SBASE=${CEPH_OSD_SOCKET_BASE:-ceph-osd} SSUFFIX=${CEPH_SOCKET_SUFFIX:-asok} # default: no sockets, not live cond=1 for sock in $SOCKDIR/$SBASE.*.$SSUFFIX; do if [ -S $sock ]; then OSD_ID=$(echo $sock | awk -F. '{print $2}') OSD_STATE=$(ceph -f json --connect-timeout 1 --admin-daemon "${sock}" status|jq -r '.state') echo "OSD ${OSD_ID} ${OSD_STATE}"; # Succeed if the OSD state is active (running) or preboot (starting) if [ "${OSD_STATE}" = "active" ] || [ "${OSD_STATE}" = "preboot" ]; then cond=0 else # Any other state is unexpected and the probe fails exit 1 fi else echo "No daemon sockets found in $SOCKDIR" fi done exit $cond ================================================ FILE: ceph-osd/templates/bin/osd/_config.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex source /tmp/osd-common-ceph-volume.sh # This script will execute a series of: # ceph config set
# for values defined in .Values.conf.ceph # # .Values.conf.ceph is expected to be a map where each key is the section name: # Example values structure (Helm values.yaml): # conf: # ceph: # osd: # debug_osd: 10 # mon: # debug_mon: 20 # helper: run a ceph config set and log the command run_ceph_set() { echo "+ ceph config set $1 $2 $3" timeout 10 ceph --name client.bootstrap-osd --keyring ${OSD_BOOTSTRAP_KEYRING} config set "$1" "$2" "$3" } # Disable exit on error to ignore config set failures set +e # The following block is generated by Helm templating and will expand into # concrete ceph config set commands. Do not edit at runtime. {{- /* Iterate sections (keys are section names). Sections must not contain nested maps. */ -}} {{- if .Values.conf.ceph }} {{- range $secName, $secValues := .Values.conf.ceph }} echo "Applying Ceph config for section: {{ $secName }}" {{- if eq (kindOf $secValues) "map" }} {{- range $k, $v := $secValues }} {{- if eq (kindOf $v) "map" }} echo "ERROR: nested maps are not allowed in section '{{ $secName }}' for key '{{ $k }}'. Aborting." exit 1 {{- else }} run_ceph_set {{ $secName }} {{ $k }} {{ $v | quote }} {{- end }} {{- end }} {{- else }} echo "ERROR: section '{{ $secName }}' is not a valid map. Aborting. exit 1 {{- end }} {{- end }} {{- else }} echo "No .Values.conf.ceph defined, nothing to configure." {{- end -}} exit 0 ================================================ FILE: ceph-osd/templates/bin/osd/_directory.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C source /tmp/osd-common-ceph-volume.sh : "${JOURNAL_DIR:=/var/lib/ceph/journal}" if [[ ! -d /var/lib/ceph/osd ]]; then echo "ERROR- could not find the osd directory, did you bind mount the OSD data directory?" echo "ERROR- use -v :/var/lib/ceph/osd" exit 1 fi # check if anything is present, if not, create an osd and its directory if [[ -n "$(find /var/lib/ceph/osd -type d -empty ! -name "lost+found")" ]]; then echo "Creating osd" UUID=$(uuidgen) OSD_SECRET=$(ceph-authtool --gen-print-key) OSD_ID=$(echo "{\"cephx_secret\": \"${OSD_SECRET}\"}" | ceph osd new ${UUID} -i - -n client.bootstrap-osd -k "$OSD_BOOTSTRAP_KEYRING") # test that the OSD_ID is an integer if [[ "$OSD_ID" =~ ^-?[0-9]+$ ]]; then echo "OSD created with ID: ${OSD_ID}" else echo "OSD creation failed: ${OSD_ID}" exit 1 fi OSD_PATH="$OSD_PATH_BASE-$OSD_ID/" if [ -n "${JOURNAL_DIR}" ]; then OSD_JOURNAL="${JOURNAL_DIR}/journal.${OSD_ID}" chown -R ceph. ${JOURNAL_DIR} else if [ -n "${JOURNAL}" ]; then OSD_JOURNAL=${JOURNAL} chown -R ceph. $(dirname ${JOURNAL_DIR}) else OSD_JOURNAL=${OSD_PATH%/}/journal fi fi # create the folder and own it mkdir -p "${OSD_PATH}" echo "created folder ${OSD_PATH}" # write the secret to the osd keyring file ceph-authtool --create-keyring ${OSD_PATH%/}/keyring --name osd.${OSD_ID} --add-key ${OSD_SECRET} chown -R "${CHOWN_OPT[@]}" ceph. "${OSD_PATH}" OSD_KEYRING="${OSD_PATH%/}/keyring" # init data directory ceph-osd -i ${OSD_ID} --mkfs --osd-uuid ${UUID} --mkjournal --osd-journal ${OSD_JOURNAL} --setuser ceph --setgroup ceph # add the osd to the crush map crush_location fi for OSD_ID in $(ls /var/lib/ceph/osd | sed 's/.*-//'); do # NOTE(gagehugo): Writing the OSD_ID to tmp for logging echo "${OSD_ID}" > /tmp/osd-id OSD_PATH="$OSD_PATH_BASE-$OSD_ID/" OSD_KEYRING="${OSD_PATH%/}/keyring" if [ -n "${JOURNAL_DIR}" ]; then OSD_JOURNAL="${JOURNAL_DIR}/journal.${OSD_ID}" chown -R ceph. ${JOURNAL_DIR} else if [ -n "${JOURNAL}" ]; then OSD_JOURNAL=${JOURNAL} chown -R ceph. $(dirname ${JOURNAL_DIR}) else OSD_JOURNAL=${OSD_PATH%/}/journal chown ceph. ${OSD_JOURNAL} fi fi # log osd filesystem type FS_TYPE=`stat --file-system -c "%T" ${OSD_PATH}` echo "OSD $OSD_PATH filesystem type: $FS_TYPE" # NOTE(supamatt): Just in case permissions do not align up, we recursively set them correctly. if [ $(stat -c%U ${OSD_PATH}) != ceph ]; then chown -R ceph. ${OSD_PATH}; fi crush_location done exec /usr/bin/ceph-osd \ --cluster ${CLUSTER} \ -f \ -i ${OSD_ID} \ --osd-journal ${OSD_JOURNAL} \ -k ${OSD_KEYRING} --setuser ceph \ --setgroup disk $! > /run/ceph-osd.pid ================================================ FILE: ceph-osd/templates/bin/osd/_init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x echo "Configuring Ceph from Helm values" /tmp/osd-config.sh set -e echo "Initializing the osd with ${DEPLOY_TOOL}" exec "/tmp/init-${DEPLOY_TOOL}.sh" ================================================ FILE: ceph-osd/templates/bin/osd/_log-runner-stop.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex source /tmp/utils-resolveLocations.sh touch /tmp/ceph-log-runner.stop TAIL_PID="$(cat /tmp/ceph-log-runner.pid)" while kill -0 ${TAIL_PID} >/dev/null 2>&1; do kill -9 ${TAIL_PID}; sleep 1; done SLEEP_PID="$(cat /tmp/ceph-log-runner-sleep.pid)" while kill -0 ${SLEEP_PID} >/dev/null 2>&1; do kill -9 ${SLEEP_PID}; sleep 1; done ================================================ FILE: ceph-osd/templates/bin/osd/_log-tail.sh.tpl ================================================ #!/bin/bash set -ex osd_id_file="/tmp/osd-id" function wait_for_file() { local file="$1"; shift local wait_seconds="${1:-30}"; shift until test $((wait_seconds--)) -eq 0 -o -f "$file" ; do sleep 1 done ((++wait_seconds)) } wait_for_file "${osd_id_file}" "${WAIT_FOR_OSD_ID_TIMEOUT}" log_file="/var/log/ceph/${DAEMON_NAME}.$(cat "${osd_id_file}").log" wait_for_file "${log_file}" "${WAIT_FOR_OSD_ID_TIMEOUT}" trap "exit" SIGTERM SIGINT keep_running=true function tail_file () { while $keep_running; do tail --retry -f "${log_file}" & tail_pid=$! echo $tail_pid > /tmp/ceph-log-runner-tail.pid wait $tail_pid if [ -f /tmp/ceph-log-runner.stop ]; then keep_running=false fi sleep 30 done } function truncate_log () { while $keep_running; do sleep ${TRUNCATE_PERIOD} sleep_pid=$! echo $sleep_pid > /tmp/ceph-log-runner-sleep.pid if [[ -f ${log_file} ]] ; then truncate -s "${TRUNCATE_SIZE}" "${log_file}" fi done } tail_file & truncate_log & wait -n keep_running=false wait ================================================ FILE: ceph-osd/templates/bin/osd/_start.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex echo "LAUNCHING OSD: in ${STORAGE_TYPE%-*}:${STORAGE_TYPE#*-} mode" exec "/tmp/osd-${STORAGE_TYPE%-*}-${DEPLOY_TOOL}.sh" ================================================ FILE: ceph-osd/templates/bin/osd/_stop.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex source /tmp/utils-resolveLocations.sh CEPH_OSD_PID="$(cat /run/ceph-osd.pid)" while kill -0 ${CEPH_OSD_PID} >/dev/null 2>&1; do kill -SIGTERM ${CEPH_OSD_PID} sleep 1 done if [ "x${STORAGE_TYPE%-*}" == "xblock" ]; then OSD_DEVICE=$(readlink -f ${STORAGE_LOCATION}) OSD_JOURNAL=$(readlink -f ${JOURNAL_LOCATION}) if [ "x${STORAGE_TYPE#*-}" == "xlogical" ]; then umount "$(findmnt -S "${OSD_DEVICE}1" | tail -n +2 | awk '{ print $1 }')" fi fi fi ================================================ FILE: ceph-osd/templates/bin/osd/ceph-volume/_block.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} source /tmp/osd-common-ceph-volume.sh set -ex : "${OSD_SOFT_FORCE_ZAP:=1}" : "${OSD_JOURNAL_DISK:=}" if [ "x${STORAGE_TYPE%-*}" == "xdirectory" ]; then export OSD_DEVICE="/var/lib/ceph/osd" else export OSD_DEVICE=$(readlink -f ${STORAGE_LOCATION}) fi if [ "x$JOURNAL_TYPE" == "xdirectory" ]; then export OSD_JOURNAL="/var/lib/ceph/journal" else export OSD_JOURNAL=$(readlink -f ${JOURNAL_LOCATION}) fi if [[ -z "${OSD_DEVICE}" ]];then echo "ERROR- You must provide a device to build your OSD ie: /dev/sdb" exit 1 fi if [[ ! -b "${OSD_DEVICE}" ]]; then echo "ERROR- The device pointed by OSD_DEVICE ${OSD_DEVICE} doesn't exist !" exit 1 fi ACTIVATE_OPTIONS="" CEPH_OSD_OPTIONS="" udev_settle OSD_ID=$(ceph-volume inventory ${OSD_DEVICE} | grep "osd id" | awk '{print $3}') if [[ -z ${OSD_ID} ]]; then echo "OSD_ID not found from device ${OSD_DEVICE}" exit 1 fi OSD_FSID=$(ceph-volume inventory ${OSD_DEVICE} | grep "osd fsid" | awk '{print $3}') if [[ -z ${OSD_FSID} ]]; then echo "OSD_FSID not found from device ${OSD_DEVICE}" exit 1 fi OSD_PATH="${OSD_PATH_BASE}-${OSD_ID}" OSD_KEYRING="${OSD_PATH}/keyring" mkdir -p ${OSD_PATH} ceph-volume lvm -v \ --setuser ceph \ --setgroup disk \ activate ${ACTIVATE_OPTIONS} \ --auto-detect-objectstore \ --no-systemd ${OSD_ID} ${OSD_FSID} # NOTE(stevetaylor): Set the OSD's crush weight (use noin flag to prevent rebalancing if necessary) OSD_WEIGHT=$(get_osd_crush_weight_from_device ${OSD_DEVICE}) # NOTE(supamatt): add or move the OSD's CRUSH location crush_location if [ "${OSD_BLUESTORE:-0}" -ne 1 ]; then if [ -n "${OSD_JOURNAL}" ]; then if [ -b "${OSD_JOURNAL}" ]; then OSD_JOURNAL_DISK="$(readlink -f ${OSD_PATH}/journal)" if [ -z "${OSD_JOURNAL_DISK}" ]; then echo "ERROR: Unable to find journal device ${OSD_JOURNAL_DISK}" exit 1 else OSD_JOURNAL="${OSD_JOURNAL_DISK}" if [ -e "${OSD_PATH}/run_mkjournal" ]; then ceph-osd -i ${OSD_ID} --mkjournal rm -rf ${OSD_PATH}/run_mkjournal fi fi fi if [ "x${JOURNAL_TYPE}" == "xdirectory" ]; then OSD_JOURNAL="${OSD_JOURNAL}/journal.${OSD_ID}" touch ${OSD_JOURNAL} wait_for_file "${OSD_JOURNAL}" else if [ ! -b "${OSD_JOURNAL}" ]; then echo "ERROR: Unable to find journal device ${OSD_JOURNAL}" exit 1 else chown ceph. "${OSD_JOURNAL}" fi fi else wait_for_file "${OSD_JOURNAL}" chown ceph. "${OSD_JOURNAL}" fi fi # NOTE(supamatt): Just in case permissions do not align up, we recursively set them correctly. if [ $(stat -c%U ${OSD_PATH}) != ceph ]; then chown -R ceph. ${OSD_PATH}; fi # NOTE(gagehugo): Writing the OSD_ID to tmp for logging echo "${OSD_ID}" > /tmp/osd-id if [ "x${JOURNAL_TYPE}" == "xdirectory" ]; then chown -R ceph. /var/lib/ceph/journal ceph-osd \ --cluster ceph \ --osd-data ${OSD_PATH} \ --osd-journal ${OSD_JOURNAL} \ -f \ -i ${OSD_ID} \ --setuser ceph \ --setgroup disk \ --mkjournal fi exec /usr/bin/ceph-osd \ --cluster ${CLUSTER} \ ${CEPH_OSD_OPTIONS} \ -f \ -i ${OSD_ID} \ --setuser ceph \ --setgroup disk & echo $! > /run/ceph-osd.pid wait # Clean up resources held by the common script common_cleanup ================================================ FILE: ceph-osd/templates/bin/osd/ceph-volume/_bluestore.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} source /tmp/osd-common-ceph-volume.sh set -ex : "${OSD_SOFT_FORCE_ZAP:=1}" export OSD_DEVICE=$(readlink -f ${STORAGE_LOCATION}) if [[ -z "${OSD_DEVICE}" ]];then echo "ERROR- You must provide a device to build your OSD ie: /dev/sdb" exit 1 fi if [[ ! -b "${OSD_DEVICE}" ]]; then echo "ERROR- The device pointed by OSD_DEVICE ${OSD_DEVICE} doesn't exist !" exit 1 fi ACTIVATE_OPTIONS="" CEPH_OSD_OPTIONS="" udev_settle OSD_ID=$(get_osd_id_from_device ${OSD_DEVICE}) if [[ -z ${OSD_ID} ]]; then echo "OSD_ID not found from device ${OSD_DEVICE}" exit 1 fi OSD_FSID=$(get_osd_fsid_from_device ${OSD_DEVICE}) if [[ -z ${OSD_FSID} ]]; then echo "OSD_FSID not found from device ${OSD_DEVICE}" exit 1 fi OSD_PATH="${OSD_PATH_BASE}-${OSD_ID}" OSD_KEYRING="${OSD_PATH}/keyring" mkdir -p ${OSD_PATH} ceph-volume lvm -v \ --setuser ceph \ --setgroup disk \ activate ${ACTIVATE_OPTIONS} \ --auto-detect-objectstore \ --no-systemd ${OSD_ID} ${OSD_FSID} # Cross check the db and wal symlinks if missed DB_DEV=$(get_osd_db_device_from_device ${OSD_DEVICE}) if [[ ! -z ${DB_DEV} ]]; then if [[ ! -h /var/lib/ceph/osd/ceph-${OSD_ID}/block.db ]]; then ln -snf ${DB_DEV} /var/lib/ceph/osd/ceph-${OSD_ID}/block.db chown -h ceph:ceph ${DB_DEV} chown -h ceph:ceph /var/lib/ceph/osd/ceph-${OSD_ID}/block.db fi fi WAL_DEV=$(get_osd_wal_device_from_device ${OSD_DEVICE}) if [[ ! -z ${WAL_DEV} ]]; then if [[ ! -h /var/lib/ceph/osd/ceph-${OSD_ID}/block.wal ]]; then ln -snf ${WAL_DEV} /var/lib/ceph/osd/ceph-${OSD_ID}/block.wal chown -h ceph:ceph ${WAL_DEV} chown -h ceph:ceph /var/lib/ceph/osd/ceph-${OSD_ID}/block.wal fi fi # NOTE(stevetaylor): Set the OSD's crush weight (use noin flag to prevent rebalancing if necessary) OSD_WEIGHT=$(get_osd_crush_weight_from_device ${OSD_DEVICE}) # NOTE(supamatt): add or move the OSD's CRUSH location crush_location # NOTE(supamatt): Just in case permissions do not align up, we recursively set them correctly. if [ $(stat -c%U ${OSD_PATH}) != ceph ]; then chown -R ceph. ${OSD_PATH}; fi # NOTE(gagehugo): Writing the OSD_ID to tmp for logging echo "${OSD_ID}" > /tmp/osd-id exec /usr/bin/ceph-osd \ --cluster ${CLUSTER} \ ${CEPH_OSD_OPTIONS} \ -f \ -i ${OSD_ID} \ --setuser ceph \ --setgroup disk & echo $! > /run/ceph-osd.pid wait # Clean up resources held by the common script common_cleanup ================================================ FILE: ceph-osd/templates/bin/osd/ceph-volume/_common.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex shopt -s expand_aliases export lock_fd='' export ALREADY_LOCKED=0 export PS4='+${BASH_SOURCE:+$(basename ${BASH_SOURCE}):${LINENO}:}${FUNCNAME:+${FUNCNAME}():} ' source /tmp/utils-resolveLocations.sh : "${CRUSH_LOCATION:=root=default host=${HOSTNAME}}" : "${OSD_PATH_BASE:=/var/lib/ceph/osd/${CLUSTER}}" : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" : "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" : "${OSD_JOURNAL_UUID:=$(uuidgen)}" : "${OSD_JOURNAL_SIZE:=$(awk '/^osd_journal_size/{print $3}' ${CEPH_CONF}.template)}" : "${OSD_WEIGHT:=1.0}" {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} # Obtain a global lock on /var/lib/ceph/tmp/init-osd.lock function lock() { # Open a file descriptor for the lock file if there isn't one already if [[ -z "${lock_fd}" ]]; then exec {lock_fd}>/var/lib/ceph/tmp/init-osd.lock || exit 1 fi flock -w 600 "${lock_fd}" &> /dev/null ALREADY_LOCKED=1 } # Release the global lock on /var/lib/ceph/tmp/init-osd.lock function unlock() { flock -u "${lock_fd}" &> /dev/null ALREADY_LOCKED=0 } # "Destructor" for common.sh, must be called by scripts that source this one function common_cleanup() { # Close the file descriptor for the lock file if [[ ! -z "${lock_fd}" ]]; then if [[ ${ALREADY_LOCKED} -ne 0 ]]; then unlock fi eval "exec ${lock_fd}>&-" fi } # Run a command within the global synchronization lock function locked() { # Don't log every command inside locked() to keep logs cleaner { set +x; } 2>/dev/null local LOCK_SCOPE=0 # Allow locks to be re-entrant to avoid deadlocks if [[ ${ALREADY_LOCKED} -eq 0 ]]; then lock LOCK_SCOPE=1 fi # Execute the synchronized command set -x "$@" { set +x; } 2>/dev/null # Only unlock if the lock was obtained in this scope if [[ ${LOCK_SCOPE} -ne 0 ]]; then unlock fi # Re-enable command logging set -x } # Alias commands that interact with disks so they are always synchronized alias dmsetup='locked dmsetup' alias pvs='locked pvs' alias vgs='locked vgs' alias lvs='locked lvs' alias pvdisplay='locked pvdisplay' alias vgdisplay='locked vgdisplay' alias lvdisplay='locked lvdisplay' alias pvcreate='locked pvcreate' alias vgcreate='locked vgcreate' alias lvcreate='locked lvcreate' alias pvremove='locked pvremove' alias vgremove='locked vgremove' alias lvremove='locked lvremove' alias pvrename='locked pvrename' alias vgrename='locked vgrename' alias lvrename='locked lvrename' alias pvchange='locked pvchange' alias vgchange='locked vgchange' alias lvchange='locked lvchange' alias pvscan='locked pvscan' alias vgscan='locked vgscan' alias lvscan='locked lvscan' alias lvm_scan='locked lvm_scan' alias partprobe='locked partprobe' alias ceph-volume='locked ceph-volume' alias disk_zap='locked disk_zap' alias zap_extra_partitions='locked zap_extra_partitions' alias udev_settle='locked udev_settle' alias wipefs='locked wipefs' alias sgdisk='locked sgdisk' alias dd='locked dd' eval CRUSH_FAILURE_DOMAIN_TYPE=$(cat /etc/ceph/storage.json | python3 -c 'import sys, json; data = json.load(sys.stdin); print(json.dumps(data["failure_domain"]))') eval CRUSH_FAILURE_DOMAIN_NAME=$(cat /etc/ceph/storage.json | python3 -c 'import sys, json; data = json.load(sys.stdin); print(json.dumps(data["failure_domain_name"]))') eval CRUSH_FAILURE_DOMAIN_NAME=$(cat /etc/ceph/storage.json | python3 -c 'import sys, json; data = json.load(sys.stdin); print(json.dumps(data["failure_domain_name"]))') eval CRUSH_FAILURE_DOMAIN_BY_HOSTNAME=$(cat /etc/ceph/storage.json | python3 -c 'import sys, json; data = json.load(sys.stdin); print(json.dumps(data["failure_domain_by_hostname"]))') eval CRUSH_FAILURE_DOMAIN_FROM_HOSTNAME_MAP=$(cat /etc/ceph/storage.json | jq '.failure_domain_by_hostname_map."'$HOSTNAME'"') eval DEVICE_CLASS=$(cat /etc/ceph/storage.json | python3 -c 'import sys, json; data = json.load(sys.stdin); print(json.dumps(data["device_class"]))') if [[ $(ceph -v | awk '/version/{print $3}' | cut -d. -f1) -lt 12 ]]; then echo "ERROR - The minimum Ceph version supported is Luminous 12.x.x" exit 1 fi if [ -z "${HOSTNAME}" ]; then echo "HOSTNAME not set; This will prevent to add an OSD into the CRUSH map" exit 1 fi if [[ ! -e ${CEPH_CONF}.template ]]; then echo "ERROR- ${CEPH_CONF}.template must exist; get it from your existing mon" exit 1 else ENDPOINT=$(mon_host_from_k8s_ep "${NAMESPACE}" ceph-mon-discovery) if [[ -z "${ENDPOINT}" ]]; then /bin/sh -c -e "cat ${CEPH_CONF}.template | tee ${CEPH_CONF}" || true else /bin/sh -c -e "cat ${CEPH_CONF}.template | sed 's#mon_host.*#mon_host = ${ENDPOINT}#g' | tee ${CEPH_CONF}" || true fi fi # Wait for a file to exist, regardless of the type function wait_for_file { timeout 10 bash -c "while [ ! -e ${1} ]; do echo 'Waiting for ${1} to show up' && sleep 1 ; done" } function is_available { command -v $@ &>/dev/null } function ceph_cmd_retry() { cnt=0 until "ceph" "$@" || [ $cnt -ge 6 ]; do sleep 10 ((cnt++)) done } function crush_create_or_move { local crush_location=${1} ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" \ osd crush create-or-move -- "${OSD_ID}" "${OSD_WEIGHT}" ${crush_location} } function crush_add_and_move { local crush_failure_domain_type=${1} local crush_failure_domain_name=${2} local crush_location=$(echo "root=default ${crush_failure_domain_type}=${crush_failure_domain_name} host=${HOSTNAME}") crush_create_or_move "${crush_location}" local crush_failure_domain_location_check=$(ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" osd find ${OSD_ID} | grep "${crush_failure_domain_type}" | awk -F '"' '{print $4}') if [ "x${crush_failure_domain_location_check}" != "x${crush_failure_domain_name}" ]; then # NOTE(supamatt): Manually move the buckets for previously configured CRUSH configurations # as create-or-move may not appropiately move them. ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" \ osd crush add-bucket "${crush_failure_domain_name}" "${crush_failure_domain_type}" || true ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" \ osd crush move "${crush_failure_domain_name}" root=default || true ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" \ osd crush move "${HOSTNAME}" "${crush_failure_domain_type}=${crush_failure_domain_name}" || true fi } function crush_location { set_device_class if [ "x${CRUSH_FAILURE_DOMAIN_TYPE}" != "xhost" ]; then echo "Lets check this host is registered in k8s" if kubectl get node ${HOSTNAME}; then CRUSH_FAILURE_DOMAIN_NAME_FROM_NODE_LABEL=$(kubectl get node ${HOSTNAME} -o json| jq -r '.metadata.labels.rack') else echo "It seems there is some issue with setting the hostname on this node hence we didnt found this node in k8s" kubectl get nodes echo ${HOSTNAME} exit 1 fi if [ ${CRUSH_FAILURE_DOMAIN_NAME_FROM_NODE_LABEL} != "null" ]; then CRUSH_FAILURE_DOMAIN_NAME=${CRUSH_FAILURE_DOMAIN_NAME_FROM_NODE_LABEL} fi if [ "x${CRUSH_FAILURE_DOMAIN_NAME}" != "xfalse" ]; then crush_add_and_move "${CRUSH_FAILURE_DOMAIN_TYPE}" "${CRUSH_FAILURE_DOMAIN_NAME}" elif [ "x${CRUSH_FAILURE_DOMAIN_BY_HOSTNAME}" != "xfalse" ]; then crush_add_and_move "${CRUSH_FAILURE_DOMAIN_TYPE}" "$(echo ${CRUSH_FAILURE_DOMAIN_TYPE}_$(echo ${HOSTNAME} | cut -c ${CRUSH_FAILURE_DOMAIN_BY_HOSTNAME}))" elif [ "x${CRUSH_FAILURE_DOMAIN_FROM_HOSTNAME_MAP}" != "xnull" ]; then crush_add_and_move "${CRUSH_FAILURE_DOMAIN_TYPE}" "${CRUSH_FAILURE_DOMAIN_FROM_HOSTNAME_MAP}" else # NOTE(supamatt): neither variables are defined then we fall back to default behavior crush_create_or_move "${CRUSH_LOCATION}" fi else crush_create_or_move "${CRUSH_LOCATION}" fi } # Calculate proper device names, given a device and partition number function dev_part { local osd_device=${1} local osd_partition=${2} if [[ -L ${osd_device} ]]; then # This device is a symlink. Work out it's actual device local actual_device=$(readlink -f "${osd_device}") local bn=$(basename "${osd_device}") if [[ "${actual_device:0-1:1}" == [0-9] ]]; then local desired_partition="${actual_device}p${osd_partition}" else local desired_partition="${actual_device}${osd_partition}" fi # Now search for a symlink in the directory of $osd_device # that has the correct desired partition, and the longest # shared prefix with the original symlink local symdir=$(dirname "${osd_device}") local link="" local pfxlen=0 for option in ${symdir}/*; do [[ -e $option ]] || break if [[ $(readlink -f "${option}") == "${desired_partition}" ]]; then local optprefixlen=$(prefix_length "${option}" "${bn}") if [[ ${optprefixlen} > ${pfxlen} ]]; then link=${symdir}/${option} pfxlen=${optprefixlen} fi fi done if [[ $pfxlen -eq 0 ]]; then >&2 echo "Could not locate appropriate symlink for partition ${osd_partition} of ${osd_device}" exit 1 fi echo "$link" elif [[ "${osd_device:0-1:1}" == [0-9] ]]; then echo "${osd_device}p${osd_partition}" else echo "${osd_device}${osd_partition}" fi } function zap_extra_partitions { # Examine temp mount and delete any block.db and block.wal partitions mountpoint=${1} journal_disk="" journal_part="" block_db_disk="" block_db_part="" block_wal_disk="" block_wal_part="" # Discover journal, block.db, and block.wal partitions first before deleting anything # If the partitions are on the same disk, deleting one can affect discovery of the other(s) if [ -L "${mountpoint}/journal" ]; then journal_disk=$(readlink -m ${mountpoint}/journal | sed 's/[0-9]*//g') journal_part=$(readlink -m ${mountpoint}/journal | sed 's/[^0-9]*//g') fi if [ -L "${mountpoint}/block.db" ]; then block_db_disk=$(readlink -m ${mountpoint}/block.db | sed 's/[0-9]*//g') block_db_part=$(readlink -m ${mountpoint}/block.db | sed 's/[^0-9]*//g') fi if [ -L "${mountpoint}/block.wal" ]; then block_wal_disk=$(readlink -m ${mountpoint}/block.wal | sed 's/[0-9]*//g') block_wal_part=$(readlink -m ${mountpoint}/block.wal | sed 's/[^0-9]*//g') fi # Delete any discovered journal, block.db, and block.wal partitions if [ ! -z "${journal_disk}" ]; then sgdisk -d ${journal_part} ${journal_disk} /usr/bin/flock -s ${journal_disk} /sbin/partprobe ${journal_disk} fi if [ ! -z "${block_db_disk}" ]; then sgdisk -d ${block_db_part} ${block_db_disk} /usr/bin/flock -s ${block_db_disk} /sbin/partprobe ${block_db_disk} fi if [ ! -z "${block_wal_disk}" ]; then sgdisk -d ${block_wal_part} ${block_wal_disk} /usr/bin/flock -s ${block_wal_disk} /sbin/partprobe ${block_wal_disk} fi } function disk_zap { # Run all the commands to clear a disk local device=${1} local dm_devices=$(get_dm_devices_from_osd_device "${device}" | xargs) for dm_device in ${dm_devices}; do if [[ "$(dmsetup ls | grep ${dm_device})" ]]; then dmsetup remove ${dm_device} fi done local logical_volumes=$(get_lv_paths_from_osd_device "${device}" | xargs) if [[ "${logical_volumes}" ]]; then lvremove -y ${logical_volumes} fi local volume_group=$(pvdisplay -ddd -v ${device} | grep "VG Name" | awk '/ceph/{print $3}' | grep "ceph") if [[ ${volume_group} ]]; then vgremove -y ${volume_group} pvremove -y ${device} ceph-volume lvm zap ${device} --destroy fi wipefs --all ${device} sgdisk --zap-all -- ${device} # Wipe the first 200MB boundary, as Bluestore redeployments will not work otherwise dd if=/dev/zero of=${device} bs=1M count=200 } # This should be run atomically to prevent unexpected cache states function lvm_scan { pvscan --cache vgscan --cache lvscan --cache pvscan vgscan lvscan } function wait_for_device { local device="$1" echo "Waiting for block device ${device} to appear" for countdown in {1..600}; do test -b "${device}" && break sleep 1 done test -b "${device}" || exit 1 } function udev_settle { osd_devices="${OSD_DEVICE}" partprobe "${OSD_DEVICE}" lvm_scan if [ "${OSD_BLUESTORE:-0}" -eq 1 ]; then if [ ! -z "$BLOCK_DB" ]; then osd_devices="${osd_devices}\|${BLOCK_DB}" # BLOCK_DB could be a physical or logical device here local block_db="$BLOCK_DB" local db_vg="$(echo $block_db | cut -d'/' -f1)" if [ ! -z "$db_vg" ]; then block_db=$(pvdisplay -ddd -v | grep -B1 "$db_vg" | awk '/PV Name/{print $3}') fi partprobe "${block_db}" fi if [ ! -z "$BLOCK_WAL" ] && [ "$BLOCK_WAL" != "$BLOCK_DB" ]; then osd_devices="${osd_devices}\|${BLOCK_WAL}" # BLOCK_WAL could be a physical or logical device here local block_wal="$BLOCK_WAL" local wal_vg="$(echo $block_wal | cut -d'/' -f1)" if [ ! -z "$wal_vg" ]; then block_wal=$(pvdisplay -ddd -v | grep -B1 "$wal_vg" | awk '/PV Name/{print $3}') fi partprobe "${block_wal}" fi else if [ "x$JOURNAL_TYPE" == "xblock-logical" ] && [ ! -z "$OSD_JOURNAL" ]; then OSD_JOURNAL=$(readlink -f ${OSD_JOURNAL}) if [ ! -z "$OSD_JOURNAL" ]; then local JDEV=$(echo ${OSD_JOURNAL} | sed 's/[0-9]//g') osd_devices="${osd_devices}\|${JDEV}" partprobe "${JDEV}" wait_for_device "${JDEV}" fi fi fi # On occassion udev may not make the correct device symlinks for Ceph, just in case we make them manually mkdir -p /dev/disk/by-partuuid for dev in $(awk '!/rbd/{print $4}' /proc/partitions | grep "${osd_devices}" | grep "[0-9]"); do diskdev=$(echo "${dev//[!a-z]/}") partnum=$(echo "${dev//[!0-9]/}") symlink="/dev/disk/by-partuuid/$(sgdisk -i ${partnum} /dev/${diskdev} | awk '/Partition unique GUID/{print tolower($4)}')" if [ ! -e "${symlink}" ]; then ln -s "../../${dev}" "${symlink}" fi done } # Helper function to get a logical volume from a physical volume function get_lv_from_device { device="$1" pvdisplay -ddd -v -m ${device} | awk '/Logical volume/{print $3}' } # Helper function to get an lvm tag from a logical volume function get_lvm_tag_from_volume { logical_volume="$1" tag="$2" if [[ "$#" -lt 2 ]] || [[ -z "${logical_volume}" ]]; then # Return an empty string if the logical volume doesn't exist echo else # Get and return the specified tag from the logical volume lvs -o lv_tags ${logical_volume} | tr ',' '\n' | grep ${tag} | cut -d'=' -f2 fi } # Helper function to get an lvm tag from a physical device function get_lvm_tag_from_device { device="$1" tag="$2" # Attempt to get a logical volume for the physical device logical_volume="$(get_lv_from_device ${device})" # Use get_lvm_tag_from_volume to get the specified tag from the logical volume get_lvm_tag_from_volume ${logical_volume} ${tag} } # Helper function to get the size of a logical volume function get_lv_size_from_device { device="$1" logical_volume="$(get_lv_from_device ${device})" lvs ${logical_volume} -o LV_SIZE --noheadings --units k --nosuffix | xargs | cut -d'.' -f1 } # Helper function to get the crush weight for an osd device function get_osd_crush_weight_from_device { device="$1" lv_size="$(get_lv_size_from_device ${device})" # KiB if [[ ! -z "${BLOCK_DB_SIZE}" ]]; then db_size=$(echo "${BLOCK_DB_SIZE}" | cut -d'B' -f1 | numfmt --from=iec | awk '{print $1/1024}') # KiB lv_size=$((lv_size+db_size)) # KiB fi echo ${lv_size} | awk '{printf("%.2f\n", $1/1073741824)}' # KiB to TiB } # Helper function to get a cluster FSID from a physical device function get_cluster_fsid_from_device { device="$1" # Use get_lvm_tag_from_device to get the cluster FSID from the device get_lvm_tag_from_device ${device} ceph.cluster_fsid } # Helper function to get an OSD ID from a logical volume function get_osd_id_from_volume { logical_volume="$1" # Use get_lvm_tag_from_volume to get the OSD ID from the logical volume get_lvm_tag_from_volume ${logical_volume} ceph.osd_id } # Helper function get an OSD ID from a physical device function get_osd_id_from_device { device="$1" # Use get_lvm_tag_from_device to get the OSD ID from the device get_lvm_tag_from_device ${device} ceph.osd_id } # Helper function get an OSD FSID from a physical device function get_osd_fsid_from_device { device="$1" # Use get_lvm_tag_from_device to get the OSD FSID from the device get_lvm_tag_from_device ${device} ceph.osd_fsid } # Helper function get an OSD DB device from a physical device function get_osd_db_device_from_device { device="$1" # Use get_lvm_tag_from_device to get the OSD DB device from the device get_lvm_tag_from_device ${device} ceph.db_device } # Helper function get an OSD WAL device from a physical device function get_osd_wal_device_from_device { device="$1" # Use get_lvm_tag_from_device to get the OSD WAL device from the device get_lvm_tag_from_device ${device} ceph.wal_device } function get_block_uuid_from_device { device="$1" get_lvm_tag_from_device ${device} ceph.block_uuid } function get_dm_devices_from_osd_device { device="$1" pv_uuid=$(pvdisplay -ddd -v ${device} | awk '/PV UUID/{print $3}') # Return the list of dm devices that belong to the osd if [[ "${pv_uuid}" ]]; then dmsetup ls | grep "$(echo "${pv_uuid}" | sed 's/-/--/g')" | awk '{print $1}' fi } function get_lv_paths_from_osd_device { device="$1" pv_uuid=$(pvdisplay -ddd -v ${device} | awk '/PV UUID/{print $3}') # Return the list of lvs that belong to the osd if [[ "${pv_uuid}" ]]; then lvdisplay | grep "LV Path" | grep "${pv_uuid}" | awk '{print $3}' fi } function get_vg_name_from_device { device="$1" pv_uuid=$(pvdisplay -ddd -v ${device} | awk '/PV UUID/{print $3}') if [[ "${pv_uuid}" ]]; then echo "ceph-vg-${pv_uuid}" fi } function get_lv_name_from_device { device="$1" device_type="$2" pv_uuid=$(pvdisplay -ddd -v ${device} | awk '/PV UUID/{print $3}') if [[ "${pv_uuid}" ]]; then echo "ceph-${device_type}-${pv_uuid}" fi } function set_device_class { if [ ! -z "$DEVICE_CLASS" ]; then if [ "x$DEVICE_CLASS" != "x$(get_device_class)" ]; then ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" \ osd crush rm-device-class "osd.${OSD_ID}" ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" \ osd crush set-device-class "${DEVICE_CLASS}" "osd.${OSD_ID}" fi fi } function get_device_class { echo $(ceph_cmd_retry --cluster "${CLUSTER}" --name="osd.${OSD_ID}" --keyring="${OSD_KEYRING}" \ osd crush get-device-class "osd.${OSD_ID}") } ================================================ FILE: ceph-osd/templates/bin/osd/ceph-volume/_init-ceph-volume-helper-block-logical.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # We do not want to zap journal disk. Tracking this option seperatly. : "${JOURNAL_FORCE_ZAP:=0}" export OSD_DEVICE=$(readlink -f ${STORAGE_LOCATION}) export OSD_BLUESTORE=0 if [ "x$JOURNAL_TYPE" == "xdirectory" ]; then export OSD_JOURNAL="/var/lib/ceph/journal" else export OSD_JOURNAL=$(readlink -f ${JOURNAL_LOCATION}) fi # Check OSD FSID and journalling metadata # Returns 1 if the disk should be zapped; 0 otherwise. function check_osd_metadata { local ceph_fsid=$1 retcode=0 local tmpmnt=$(mktemp -d) mount ${DM_DEV} ${tmpmnt} if [ "x${JOURNAL_TYPE}" != "xdirectory" ]; then if [ -f "${tmpmnt}/whoami" ]; then OSD_JOURNAL_DISK=$(readlink -f "${tmpmnt}/journal") local osd_id=$(cat "${tmpmnt}/whoami") if [ ! -b "${OSD_JOURNAL_DISK}" ]; then OSD_JOURNAL=$(readlink -f ${OSD_JOURNAL}) local jdev=$(echo ${OSD_JOURNAL} | sed 's/[0-9]//g') if [ ${jdev} == ${OSD_JOURNAL} ]; then echo "OSD Init: It appears that ${OSD_DEVICE} is missing the journal at ${OSD_JOURNAL}." echo "OSD Init: Because OSD_FORCE_REPAIR is set, we will wipe the metadata of the OSD and zap it." rm -rf ${tmpmnt}/ceph_fsid else echo "OSD Init: It appears that ${OSD_DEVICE} is missing the journal at ${OSD_JOURNAL_DISK}." echo "OSD Init: Because OSD_FORCE_REPAIR is set and paritions are manually defined, we will" echo "OSD Init: attempt to recreate the missing journal device partitions." osd_journal_create ${OSD_JOURNAL} ln -sf /dev/disk/by-partuuid/${OSD_JOURNAL_UUID} ${tmpmnt}/journal echo ${OSD_JOURNAL_UUID} | tee ${tmpmnt}/journal_uuid chown ceph. ${OSD_JOURNAL} # During OSD start we will format the journal and set the fsid touch ${tmpmnt}/run_mkjournal fi fi else echo "OSD Init: It looks like ${OSD_DEVICE} has a ceph data partition but is missing it's metadata." echo "OSD Init: The device may contain inconsistent metadata or be corrupted." echo "OSD Init: Because OSD_FORCE_REPAIR is set, we will wipe the metadata of the OSD and zap it." rm -rf ${tmpmnt}/ceph_fsid fi fi if [ -f "${tmpmnt}/ceph_fsid" ]; then local osd_fsid=$(cat "${tmpmnt}/ceph_fsid") if [ ${osd_fsid} != ${ceph_fsid} ]; then echo "OSD Init: ${OSD_DEVICE} is an OSD belonging to a different (or old) ceph cluster." echo "OSD Init: The OSD FSID is ${osd_fsid} while this cluster is ${ceph_fsid}" echo "OSD Init: Because OSD_FORCE_REPAIR was set, we will zap this device." ZAP_EXTRA_PARTITIONS=${tmpmnt} retcode=1 else echo "It looks like ${OSD_DEVICE} is an OSD belonging to a this ceph cluster." echo "OSD_FORCE_REPAIR is set, but will be ignored and the device will not be zapped." echo "Moving on, trying to activate the OSD now." fi else echo "OSD Init: ${OSD_DEVICE} has a ceph data partition but no FSID." echo "OSD Init: Because OSD_FORCE_REPAIR was set, we will zap this device." ZAP_EXTRA_PARTITIONS=${tmpmnt} retcode=1 fi umount ${tmpmnt} return ${retcode} } function determine_what_needs_zapping { if [[ ! -z ${OSD_ID} ]]; then local dm_num=$(dmsetup ls | grep $(lsblk -J ${OSD_DEVICE} | jq -r '.blockdevices[].children[].name') | awk '{print $2}' | cut -d':' -f2 | cut -d')' -f1) DM_DEV="/dev/dm-"${dm_num} elif [[ $(sgdisk --print ${OSD_DEVICE} | grep "F800") ]]; then # Ceph-disk was used to initialize the disk, but this is not supported echo "OSD Init: ceph-disk was used to initialize the disk, but this is no longer supported" exit 1 else if [[ ${OSD_FORCE_REPAIR} -eq 1 ]]; then echo "OSD Init: It looks like ${OSD_DEVICE} isn't consistent, however OSD_FORCE_REPAIR is enabled so we are zapping the device anyway" ZAP_DEVICE=1 else echo "OSD Init: Regarding parted, device ${OSD_DEVICE} is inconsistent/broken/weird." echo "OSD Init: It would be too dangerous to destroy it without any notification." echo "OSD Init: Please set OSD_FORCE_REPAIR to '1' if you really want to zap this disk." exit 1 fi fi if [ ${OSD_FORCE_REPAIR} -eq 1 ] && [ ! -z ${DM_DEV} ]; then if [ -b ${DM_DEV} ]; then local ceph_fsid=$(ceph-conf --lookup fsid) if [ ! -z "${ceph_fsid}" ]; then # Check the OSD metadata and zap the disk if necessary if [[ $(check_osd_metadata ${ceph_fsid}) -eq 1 ]]; then echo "OSD Init: ${OSD_DEVICE} needs to be zapped..." ZAP_DEVICE=1 fi else echo "Unable to determine the FSID of the current cluster." echo "OSD_FORCE_REPAIR is set, but this OSD will not be zapped." echo "Moving on, trying to activate the OSD now." fi else echo "parted says ${DM_DEV} should exist, but we do not see it." echo "We will ignore OSD_FORCE_REPAIR and try to use the device as-is" echo "Moving on, trying to activate the OSD now." fi else echo "INFO- It looks like ${OSD_DEVICE} is an OSD LVM" echo "Moving on, trying to prepare and activate the OSD LVM now." fi } function osd_journal_create { local osd_journal=${1} local osd_journal_partition=$(echo ${osd_journal} | sed 's/[^0-9]//g') local jdev=$(echo ${osd_journal} | sed 's/[0-9]//g') if [ -b "${jdev}" ]; then sgdisk --new=${osd_journal_partition}:0:+${OSD_JOURNAL_SIZE}M \ --change-name='${osd_journal_partition}:ceph journal' \ --partition-guid=${osd_journal_partition}:${OSD_JOURNAL_UUID} \ --typecode=${osd_journal_partition}:45b0969e-9b03-4f30-b4c6-b4b80ceff106 --mbrtogpt -- ${jdev} OSD_JOURNAL=$(dev_part ${jdev} ${osd_journal_partition}) udev_settle else echo "OSD Init: The backing device ${jdev} for ${OSD_JOURNAL} does not exist on this system." exit 1 fi } function osd_journal_prepare { if [ -n "${OSD_JOURNAL}" ]; then if [ -b ${OSD_JOURNAL} ]; then OSD_JOURNAL=$(readlink -f ${OSD_JOURNAL}) OSD_JOURNAL_PARTITION=$(echo ${OSD_JOURNAL} | sed 's/[^0-9]//g') local jdev=$(echo ${OSD_JOURNAL} | sed 's/[0-9]//g') if [ -z "${OSD_JOURNAL_PARTITION}" ]; then OSD_JOURNAL=$(dev_part ${jdev} ${OSD_JOURNAL_PARTITION}) else OSD_JOURNAL=${OSD_JOURNAL} fi elif [ "x${JOURNAL_TYPE}" != "xdirectory" ]; then # The block device exists but doesn't appear to be paritioned, we will proceed with parititioning the device. OSD_JOURNAL=$(readlink -f ${OSD_JOURNAL}) until [ -b ${OSD_JOURNAL} ]; do osd_journal_create ${OSD_JOURNAL} done fi chown ceph. ${OSD_JOURNAL}; elif [ "x${JOURNAL_TYPE}" != "xdirectory" ]; then echo "No journal device specified. OSD and journal will share ${OSD_DEVICE}" echo "For better performance on HDD, consider moving your journal to a separate device" fi CLI_OPTS="${CLI_OPTS} --filestore" } function osd_disk_prepare { if [[ ${CEPH_LVM_PREPARE} -eq 1 ]] || [[ ${DISK_ZAPPED} -eq 1 ]]; then udev_settle RESULTING_VG=""; RESULTING_LV=""; create_vg_if_needed "${OSD_DEVICE}" create_lv_if_needed "${OSD_DEVICE}" "${RESULTING_VG}" "--yes -l 100%FREE" CLI_OPTS="${CLI_OPTS} --data ${RESULTING_LV}" CEPH_LVM_PREPARE=1 udev_settle fi if pvdisplay -ddd -v ${OSD_DEVICE} | awk '/VG Name/{print $3}' | grep "ceph"; then echo "OSD Init: Device is already set up. LVM prepare does not need to be called." CEPH_LVM_PREPARE=0 fi osd_journal_prepare CLI_OPTS="${CLI_OPTS} --data ${OSD_DEVICE} --journal ${OSD_JOURNAL}" udev_settle if [ ! -z "$DEVICE_CLASS" ]; then CLI_OPTS="${CLI_OPTS} --crush-device-class ${DEVICE_CLASS}" fi if [[ ${CEPH_LVM_PREPARE} -eq 1 ]]; then echo "OSD Init: Calling ceph-volume lvm-v prepare ${CLI_OPTS}" ceph-volume lvm -v prepare ${CLI_OPTS} udev_settle fi } ================================================ FILE: ceph-osd/templates/bin/osd/ceph-volume/_init-ceph-volume-helper-bluestore.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export OSD_DEVICE=$(readlink -f ${STORAGE_LOCATION}) export OSD_BLUESTORE=1 alias prep_device='locked prep_device' function check_block_device_for_zap { local block_device=$1 local device_type=$2 if [[ ${block_device} ]]; then local vg_name=$(get_vg_name_from_device ${block_device}) local lv_name=$(get_lv_name_from_device ${OSD_DEVICE} ${device_type}) local vg=$(vgs --noheadings -o vg_name -S "vg_name=${vg_name}" | tr -d '[:space:]') if [[ "${vg}" ]]; then local device_osd_id=$(get_osd_id_from_volume "/dev/${vg_name}/${lv_name}") CEPH_LVM_PREPARE=1 if [[ -n "${device_osd_id}" ]] && [[ -n "${OSD_ID}" ]]; then if [[ "${device_osd_id}" == "${OSD_ID}" ]]; then echo "OSD Init: OSD ID matches the OSD ID already on the data volume. LVM prepare does not need to be called." CEPH_LVM_PREPARE=0 else echo "OSD Init: OSD ID does match the OSD ID on the data volume. Device needs to be zapped." ZAP_DEVICE=1 fi fi # Check if this device (db or wal) has no associated data volume local logical_volumes="$(lvs --noheadings -o lv_name ${vg} | xargs)" for volume in ${logical_volumes}; do local data_volume=$(echo ${volume} | sed -E -e 's/-db-|-wal-/-lv-/g') if [[ -z $(lvs --noheadings -o lv_name -S "lv_name=${data_volume}") ]]; then # DB or WAL volume without a corresponding data volume, remove it lvremove -y /dev/${vg}/${volume} echo "OSD Init: LV /dev/${vg}/${volume} was removed as it did not have a data volume." fi done else if [[ "${vg_name}" ]]; then local logical_devices=$(get_dm_devices_from_osd_device "${OSD_DEVICE}") local device_filter=$(echo "${vg_name}" | sed 's/-/--/g') local logical_devices=$(echo "${logical_devices}" | grep "${device_filter}" | xargs) if [[ "$logical_devices" ]]; then echo "OSD Init: No VG resources found with name ${vg_name}. Device needs to be zapped." ZAP_DEVICE=1 fi fi fi fi } function determine_what_needs_zapping { local osd_fsid=$(get_cluster_fsid_from_device ${OSD_DEVICE}) local cluster_fsid=$(ceph-conf --lookup fsid) # If the OSD FSID is defined within the device, check if we're already bootstrapped. if [[ ! -z "${osd_fsid}" ]]; then # Check if the OSD FSID is the same as the cluster FSID. If so, then we're # already bootstrapped; otherwise, this is an old disk and needs to # be zapped. if [[ "${osd_fsid}" == "${cluster_fsid}" ]]; then if [[ ! -z "${OSD_ID}" ]]; then # Check to see what needs to be done to prepare the disk. If the OSD # ID is in the Ceph OSD list, then LVM prepare does not need to be done. if ceph --name client.bootstrap-osd --keyring $OSD_BOOTSTRAP_KEYRING osd ls |grep -w ${OSD_ID}; then echo "OSD Init: Running bluestore mode and ${OSD_DEVICE} already bootstrapped. LVM prepare does not need to be called." CEPH_LVM_PREPARE=0 elif [[ ${OSD_FORCE_REPAIR} -eq 1 ]]; then echo "OSD initialized for this cluster, but OSD ID not found in the cluster, reinitializing" ZAP_DEVICE=1 else echo "OSD initialized for this cluster, but OSD ID not found in the cluster, repair manually" fi fi else echo "OSD Init: OSD FSID ${osd_fsid} initialized for a different cluster. It needs to be zapped." ZAP_DEVICE=1 fi elif [[ $(sgdisk --print ${OSD_DEVICE} | grep "F800") ]]; then # Ceph-disk was used to initialize the disk, but this is not supported echo "ceph-disk was used to initialize the disk, but this is no longer supported" exit 1 fi check_block_device_for_zap "${BLOCK_DB}" db check_block_device_for_zap "${BLOCK_WAL}" wal # Zapping extra partitions isn't done for bluestore ZAP_EXTRA_PARTITIONS=0 } function prep_device { local block_device=$1 local block_device_size=$2 local device_type=$3 local vg_name lv_name vg device_osd_id logical_devices logical_volume RESULTING_VG=""; RESULTING_LV=""; udev_settle vg_name=$(get_vg_name_from_device ${block_device}) lv_name=$(get_lv_name_from_device ${OSD_DEVICE} ${device_type}) vg=$(vgs --noheadings -o vg_name -S "vg_name=${vg_name}" | tr -d '[:space:]') if [[ -z "${vg}" ]]; then create_vg_if_needed "${block_device}" vg=${RESULTING_VG} fi udev_settle create_lv_if_needed "${block_device}" "${vg}" "--yes -L ${block_device_size}" "${lv_name}" if [[ "${device_type}" == "db" ]]; then BLOCK_DB=${RESULTING_LV} elif [[ "${device_type}" == "wal" ]]; then BLOCK_WAL=${RESULTING_LV} fi udev_settle } function osd_disk_prepare { if [[ ${CEPH_LVM_PREPARE} -eq 1 ]] || [[ ${DISK_ZAPPED} -eq 1 ]]; then udev_settle RESULTING_VG=""; RESULTING_LV=""; create_vg_if_needed "${OSD_DEVICE}" create_lv_if_needed "${OSD_DEVICE}" "${RESULTING_VG}" "--yes -l 100%FREE" CLI_OPTS="${CLI_OPTS} --data ${RESULTING_LV}" CEPH_LVM_PREPARE=1 udev_settle fi if [[ ${BLOCK_DB} && ${BLOCK_WAL} ]]; then prep_device "${BLOCK_DB}" "${BLOCK_DB_SIZE}" "db" "${OSD_DEVICE}" prep_device "${BLOCK_WAL}" "${BLOCK_WAL_SIZE}" "wal" "${OSD_DEVICE}" elif [[ -z ${BLOCK_DB} && ${BLOCK_WAL} ]]; then prep_device "${BLOCK_WAL}" "${BLOCK_WAL_SIZE}" "wal" "${OSD_DEVICE}" elif [[ ${BLOCK_DB} && -z ${BLOCK_WAL} ]]; then prep_device "${BLOCK_DB}" "${BLOCK_DB_SIZE}" "db" "${OSD_DEVICE}" fi CLI_OPTS="${CLI_OPTS} --bluestore" if [ ! -z "$BLOCK_DB" ]; then CLI_OPTS="${CLI_OPTS} --block.db ${BLOCK_DB}" fi if [ ! -z "$BLOCK_WAL" ]; then CLI_OPTS="${CLI_OPTS} --block.wal ${BLOCK_WAL}" fi if [ ! -z "$DEVICE_CLASS" ]; then CLI_OPTS="${CLI_OPTS} --crush-device-class ${DEVICE_CLASS}" fi if [[ ${CEPH_LVM_PREPARE} -eq 1 ]]; then echo "OSD Init: Calling ceph-volume lvm-v prepare ${CLI_OPTS}" ceph-volume lvm -v prepare ${CLI_OPTS} udev_settle fi } ================================================ FILE: ceph-osd/templates/bin/osd/ceph-volume/_init-ceph-volume-helper-directory.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # We do not want to zap journal disk. Tracking this option seperatly. : "${JOURNAL_FORCE_ZAP:=0}" export OSD_DEVICE="/var/lib/ceph/osd" export OSD_JOURNAL="/var/lib/ceph/journal" ================================================ FILE: ceph-osd/templates/bin/osd/ceph-volume/_init-with-ceph-volume.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex : "${OSD_FORCE_REPAIR:=0}" source /tmp/osd-common-ceph-volume.sh source /tmp/init-ceph-volume-helper-${STORAGE_TYPE}.sh # Set up aliases for functions that require disk synchronization alias rename_vg='locked rename_vg' alias rename_lvs='locked rename_lvs' alias update_lv_tags='locked update_lv_tags' # Renames a single VG if necessary function rename_vg { local physical_disk=$1 local old_vg_name=$(pvdisplay -ddd -v ${physical_disk} | awk '/VG Name/{print $3}') local vg_name=$(get_vg_name_from_device ${physical_disk}) if [[ "${old_vg_name}" ]] && [[ "${vg_name}" != "${old_vg_name}" ]]; then vgrename ${old_vg_name} ${vg_name} echo "OSD Init: Renamed volume group ${old_vg_name} to ${vg_name}." fi } # Renames all LVs associated with an OSD as necesasry function rename_lvs { local data_disk=$1 local vg_name=$(pvdisplay -ddd -v ${data_disk} | awk '/VG Name/{print $3}') if [[ "${vg_name}" ]]; then # Rename the OSD volume if necessary local old_lv_name=$(lvdisplay ${vg_name} | awk '/LV Name/{print $3}') local lv_name=$(get_lv_name_from_device ${data_disk} lv) if [[ "${old_lv_name}" ]] && [[ "${lv_name}" != "${old_lv_name}" ]]; then lvrename ${vg_name} ${old_lv_name} ${lv_name} echo "OSD Init: Renamed logical volume ${old_lv_name} (from group ${vg_name}) to ${lv_name}." fi # Rename the OSD's block.db volume if necessary, referenced by UUID local lv_tag=$(get_lvm_tag_from_device ${data_disk} ceph.db_uuid) if [[ "${lv_tag}" ]]; then local lv_device=$(lvdisplay | grep -B4 "${lv_tag}" | awk '/LV Path/{print $3}') if [[ "${lv_device}" ]]; then local db_vg=$(echo ${lv_device} | awk -F "/" '{print $3}') old_lv_name=$(echo ${lv_device} | awk -F "/" '{print $4}') local db_name=$(get_lv_name_from_device ${data_disk} db) if [[ "${old_lv_name}" ]] && [[ "${db_name}" != "${old_lv_name}" ]]; then lvrename ${db_vg} ${old_lv_name} ${db_name} echo "OSD Init: Renamed DB logical volume ${old_lv_name} (from group ${db_vg}) to ${db_name}." fi fi fi # Rename the OSD's WAL volume if necessary, referenced by UUID lv_tag=$(get_lvm_tag_from_device ${data_disk} ceph.wal_uuid) if [[ "${lv_tag}" ]]; then local lv_device=$(lvdisplay | grep -B4 "${lv_tag}" | awk '/LV Path/{print $3}') if [[ "${lv_device}" ]]; then local wal_vg=$(echo ${lv_device} | awk -F "/" '{print $3}') old_lv_name=$(echo ${lv_device} | awk -F "/" '{print $4}') local wal_name=$(get_lv_name_from_device ${data_disk} wal) if [[ "${old_lv_name}" ]] && [[ "${wal_name}" != "${old_lv_name}" ]]; then lvrename ${wal_vg} ${old_lv_name} ${wal_name} echo "OSD Init: Renamed WAL logical volume ${old_lv_name} (from group ${wal_vg}) to ${wal_name}." fi fi fi fi } # Fixes up the tags that reference block, db, and wal logical_volumes # NOTE: This updates tags based on current VG and LV names, so any necessary # renaming should be completed prior to calling this function update_lv_tags { local data_disk=$1 local pv_uuid=$(pvdisplay -ddd -v ${data_disk} | awk '/PV UUID/{print $3}') if [[ "${pv_uuid}" ]]; then local volumes="$(lvs --no-headings | grep -e "${pv_uuid}")" local block_device db_device wal_device vg_name local old_block_device old_db_device old_wal_device # Build OSD device paths from current VG and LV names while read lv vg other_stuff; do if [[ "${lv}" == "$(get_lv_name_from_device ${data_disk} lv)" ]]; then block_device="/dev/${vg}/${lv}" old_block_device=$(get_lvm_tag_from_volume ${block_device} ceph.block_device) fi if [[ "${lv}" == "$(get_lv_name_from_device ${data_disk} db)" ]]; then db_device="/dev/${vg}/${lv}" old_db_device=$(get_lvm_tag_from_volume ${block_device} ceph.db_device) fi if [[ "${lv}" == "$(get_lv_name_from_device ${data_disk} wal)" ]]; then wal_device="/dev/${vg}/${lv}" old_wal_device=$(get_lvm_tag_from_volume ${block_device} ceph.wal_device) fi done <<< ${volumes} # Set new tags on all of the volumes using paths built above while read lv vg other_stuff; do if [[ "${block_device}" ]]; then if [[ "${old_block_device}" ]]; then lvchange --deltag "ceph.block_device=${old_block_device}" /dev/${vg}/${lv} fi lvchange --addtag "ceph.block_device=${block_device}" /dev/${vg}/${lv} echo "OSD Init: Updated lv tags for data volume ${block_device}." fi if [[ "${db_device}" ]]; then if [[ "${old_db_device}" ]]; then lvchange --deltag "ceph.db_device=${old_db_device}" /dev/${vg}/${lv} fi lvchange --addtag "ceph.db_device=${db_device}" /dev/${vg}/${lv} echo "OSD Init: Updated lv tags for DB volume ${db_device}." fi if [[ "${wal_device}" ]]; then if [[ "${old_wal_device}" ]]; then lvchange --deltag "ceph.wal_device=${old_wal_device}" /dev/${vg}/${lv} fi lvchange --addtag "ceph.wal_device=${wal_device}" /dev/${vg}/${lv} echo "OSD Init: Updated lv tags for WAL volume ${wal_device}." fi done <<< ${volumes} fi } function create_vg_if_needed { local bl_device=$1 local vg_name=$(get_vg_name_from_device ${bl_device}) if [[ -z "${vg_name}" ]]; then local random_uuid=$(uuidgen) vgcreate ceph-vg-${random_uuid} ${bl_device} vg_name=$(get_vg_name_from_device ${bl_device}) vgrename ceph-vg-${random_uuid} ${vg_name} echo "OSD Init: Created volume group ${vg_name} for device ${bl_device}." fi RESULTING_VG=${vg_name} } function create_lv_if_needed { local bl_device=$1 local vg_name=$2 local options=$3 local lv_name=${4:-$(get_lv_name_from_device ${bl_device} lv)} if [[ ! "$(lvdisplay | awk '/LV Name/{print $3}' | grep ${lv_name})" ]]; then lvcreate ${options} -n ${lv_name} ${vg_name} echo "OSD Init: Created logical volume ${lv_name} in group ${vg_name} for device ${bl_device}." fi RESULTING_LV=${vg_name}/${lv_name} } function osd_disk_prechecks { if [[ -z "${OSD_DEVICE}" ]]; then echo "ERROR- You must provide a device to build your OSD ie: /dev/sdb" exit 1 fi if [[ ! -b "${OSD_DEVICE}" ]]; then echo "ERROR- The device pointed by OSD_DEVICE (${OSD_DEVICE}) doesn't exist !" exit 1 fi if [ ! -e ${OSD_BOOTSTRAP_KEYRING} ]; then echo "ERROR- ${OSD_BOOTSTRAP_KEYRING} must exist. You can extract it from your current monitor by running 'ceph auth get client.bootstrap-osd -o ${OSD_BOOTSTRAP_KEYRING}'" exit 1 fi timeout 10 ceph --name client.bootstrap-osd --keyring ${OSD_BOOTSTRAP_KEYRING} health || exit 1 } function perform_zap { if [[ ${ZAP_EXTRA_PARTITIONS} != "" ]]; then # This used for filestore/blockstore only echo "OSD Init: Zapping extra partitions ${ZAP_EXTRA_PARTITIONS}" zap_extra_partitions "${ZAP_EXTRA_PARTITIONS}" fi echo "OSD Init: Zapping device ${OSD_DEVICE}..." disk_zap ${OSD_DEVICE} DISK_ZAPPED=1 udev_settle } ####################################################################### # Main program ####################################################################### if [[ "${STORAGE_TYPE}" != "directory" ]]; then # Check to make sure we have what we need to continue osd_disk_prechecks # Settle LVM changes before inspecting volumes udev_settle # Rename VGs first if [[ "${OSD_DEVICE}" ]]; then OSD_DEVICE=$(readlink -f ${OSD_DEVICE}) rename_vg ${OSD_DEVICE} fi # Rename block DB device VG next if [[ "${BLOCK_DB}" ]]; then BLOCK_DB=$(readlink -f ${BLOCK_DB}) rename_vg ${BLOCK_DB} fi # Rename block WAL device VG next if [[ "${BLOCK_WAL}" ]]; then BLOCK_WAL=$(readlink -f ${BLOCK_WAL}) rename_vg ${BLOCK_WAL} fi # Rename LVs after VGs are correct rename_lvs ${OSD_DEVICE} # Update tags (all VG and LV names should be correct before calling this) update_lv_tags ${OSD_DEVICE} # Settle LVM changes again after any changes have been made udev_settle # Initialize some important global variables CEPH_LVM_PREPARE=1 OSD_ID=$(get_osd_id_from_device ${OSD_DEVICE}) DISK_ZAPPED=0 ZAP_DEVICE=0 ZAP_EXTRA_PARTITIONS="" # The disk may need to be zapped or some LVs may need to be deleted before # moving on with the disk preparation. determine_what_needs_zapping if [[ ${ZAP_DEVICE} -eq 1 ]]; then perform_zap fi # Prepare the disk for use osd_disk_prepare # Clean up resources held by the common script common_cleanup fi ================================================ FILE: ceph-osd/templates/bin/utils/_checkDNS.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" ENDPOINT="{$1}" function check_mon_dns () { GREP_CMD=$(grep -rl 'ceph-mon' ${CEPH_CONF}) if [[ "${ENDPOINT}" == "{up}" ]]; then echo "If DNS is working, we are good here" elif [[ "${ENDPOINT}" != "" ]]; then if [[ ${GREP_CMD} != "" ]]; then # No DNS, write CEPH MONs IPs into ${CEPH_CONF} sh -c -e "cat ${CEPH_CONF}.template | sed 's/mon_host.*/mon_host = ${ENDPOINT}/g' | tee ${CEPH_CONF}" > /dev/null 2>&1 else echo "endpoints are already cached in ${CEPH_CONF}" exit fi fi } check_mon_dns exit ================================================ FILE: ceph-osd/templates/bin/utils/_defragOSDs.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex source /tmp/utils-resolveLocations.sh if [ "x${STORAGE_TYPE%-*}" == "xblock" ]; then OSD_DEVICE=$(readlink -f ${STORAGE_LOCATION}) ODEV=$(echo ${OSD_DEVICE} | sed 's/[0-9]//g' | cut -f 3 -d '/') OSD_PATH=$(cat /proc/mounts | awk '/ceph-/{print $2}') OSD_STORE=$(cat ${OSD_PATH}/type) DATA_PART=$(cat /proc/mounts | awk '/ceph-/{print $1}') ODEV_ROTATIONAL=$(cat /sys/block/${ODEV}/queue/rotational) ODEV_SCHEDULER=$(cat /sys/block/${ODEV}/queue/scheduler | tr -d '[]') # NOTE(supamatt): TODO implement bluestore defrag options once it's available upstream if [ "${ODEV_ROTATIONAL}" -eq "1" ] && [ "x${OSD_STORE}" == "xfilestore" ]; then # NOTE(supamatt): Switch to CFQ in order to not block I/O echo "cfq" | tee /sys/block/${ODEV}/queue/scheduler || true ionice -c 3 xfs_fsr "${OSD_DEVICE}" 2>/dev/null # NOTE(supamatt): Switch back to previous IO scheduler echo ${ODEV_SCHEDULER} | tee /sys/block/${ODEV}/queue/scheduler || true fi fi exit 0 ================================================ FILE: ceph-osd/templates/bin/utils/_resolveLocations.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex if [[ "${STORAGE_LOCATION}" ]]; then STORAGE_LOCATION=$(ls ${STORAGE_LOCATION}) if [[ `echo "${STORAGE_LOCATION}" | wc -w` -ge 2 ]]; then echo "ERROR- Multiple locations found: ${STORAGE_LOCATION}" exit 1 fi fi if [[ "${BLOCK_DB}" ]]; then BLOCK_DB=$(ls ${BLOCK_DB}) if [[ `echo "${BLOCK_DB}" | wc -w` -ge 2 ]]; then echo "ERROR- Multiple locations found: ${BLOCK_DB}" exit 1 fi fi if [[ "${BLOCK_WAL}" ]]; then BLOCK_WAL=$(ls ${BLOCK_WAL}) if [[ `echo "${BLOCK_WAL}" | wc -w` -ge 2 ]]; then echo "ERROR- Multiple locations found: ${BLOCK_WAL}" exit 1 fi fi ================================================ FILE: ceph-osd/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} post-apply.sh: | {{ tuple "bin/_post-apply.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-start.sh: | {{ tuple "bin/osd/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} log-tail.sh: | {{ tuple "bin/osd/_log-tail.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-directory-ceph-volume.sh: | {{ tuple "bin/osd/_directory.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-block-ceph-volume.sh: | {{ tuple "bin/osd/ceph-volume/_block.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-bluestore-ceph-volume.sh: | {{ tuple "bin/osd/ceph-volume/_bluestore.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-init-ceph-volume-helper-bluestore.sh: | {{ tuple "bin/osd/ceph-volume/_init-ceph-volume-helper-bluestore.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-init-ceph-volume-helper-directory.sh: | {{ tuple "bin/osd/ceph-volume/_init-ceph-volume-helper-directory.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-init-ceph-volume-helper-block-logical.sh: | {{ tuple "bin/osd/ceph-volume/_init-ceph-volume-helper-block-logical.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-init-ceph-volume.sh: | {{ tuple "bin/osd/ceph-volume/_init-with-ceph-volume.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-common-ceph-volume.sh: | {{ tuple "bin/osd/ceph-volume/_common.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-config.sh: | {{ tuple "bin/osd/_config.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-init.sh: | {{ tuple "bin/osd/_init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-check.sh: | {{ tuple "bin/osd/_check.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} osd-stop.sh: | {{ tuple "bin/osd/_stop.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} log-runner-stop.sh: | {{ tuple "bin/osd/_log-runner-stop.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} init-dirs.sh: | {{ tuple "bin/_init-dirs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} helm-tests.sh: | {{ tuple "bin/_helm-tests.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-checkDNS.sh: | {{ tuple "bin/utils/_checkDNS.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-defragOSDs.sh: | {{ tuple "bin/utils/_defragOSDs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-resolveLocations.sh: | {{ tuple "bin/utils/_resolveLocations.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: ceph-osd/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ceph.osd.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty .Values.conf.ceph.global.mon_host -}} {{- $monHost := tuple "ceph_mon" "internal" "mon_msgr2" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} {{- $_ := $monHost | set .Values.conf.ceph.global "mon_host" -}} {{- end -}} {{- if empty .Values.conf.ceph.global.fsid -}} {{- $_ := uuidv4 | set .Values.conf.ceph.global "fsid" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.cluster_network -}} {{- $_ := .Values.network.cluster | set .Values.conf.ceph.osd "cluster_network" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.public_network -}} {{- $_ := .Values.network.public | set .Values.conf.ceph.osd "public_network" -}} {{- end -}} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapName }} data: ceph.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.ceph | indent 4 }} storage.json: | {{ toPrettyJson .Values.conf.storage | indent 4 }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list (printf "%s-%s" .Release.Name "etc") . | include "ceph.osd.configmap.etc" }} {{- end }} ================================================ FILE: ceph-osd/templates/daemonset-osd.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "osdLivenessProbeTemplate" -}} exec: command: - /tmp/osd-check.sh {{- end -}} {{- define "osdReadinessProbeTemplate" -}} exec: command: - /tmp/osd-check.sh {{- end -}} {{- if .Values.manifests.daemonset_osd }} {{- $envAll := . }} {{- $serviceAccountName := (printf "%s" .Release.Name) }} {{ tuple . "osd" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - nodes verbs: - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io {{- end }} {{- define "ceph.osd.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} --- kind: DaemonSet apiVersion: apps/v1 metadata: name: ceph-osd annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "osd" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "ceph" "osd" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "osd" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "ceph" "osd" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "ceph-osd-default" "containerNames" (list "ceph-osd-default" "log-runner" "ceph-init-dirs" "ceph-log-ownership" "osd-init" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "osd" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.osd.node_selector_key }}: {{ .Values.labels.osd.node_selector_value }} hostNetwork: true hostPID: true hostIPC: true dnsPolicy: {{ .Values.pod.dns_policy }} initContainers: {{ tuple $envAll "osd" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-init-dirs {{ tuple $envAll "ceph_osd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "osd" "container" "ceph_init_dirs" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/init-dirs.sh env: # NOTE(portdirect): These environment variables will be populated # dynamicly at the point of render. # - name: JOURNAL_LOCATION # value: /var/lib/openstack-helm/ceph/osd/journal-one # - name: STORAGE_LOCATION # value: /var/lib/openstack-helm/ceph/osd/data-one # - name: JOURNAL_TYPE # value: directory # - name: STORAGE_TYPE # value: directory - name: CLUSTER value: "ceph" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-osd-bin mountPath: /tmp/init-dirs.sh subPath: init-dirs.sh readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/storage.json subPath: storage.json readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false - name: pod-var-lib-ceph-tmp mountPath: /var/lib/ceph/tmp readOnly: false - name: pod-var-crash mountPath: /var/crash mountPropagation: HostToContainer readOnly: false - name: ceph-log-ownership {{ tuple $envAll "ceph_osd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "osd" "container" "ceph_log_ownership" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: # NOTE(portdirect): These environment variables will be populated # dynamicly at the point of render and added to all containers in the # pod # - name: JOURNAL_LOCATION # value: /var/lib/openstack-helm/ceph/osd/journal-one # - name: STORAGE_LOCATION # value: /var/lib/openstack-helm/ceph/osd/data-one # - name: JOURNAL_TYPE # value: directory # - name: STORAGE_TYPE # value: directory - name: CLUSTER value: "ceph" - name: CEPH_GET_ADMIN_KEY value: "1" command: - chown - -R - ceph:root - /var/log/ceph volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: pod-var-log mountPath: /var/log/ceph readOnly: false - name: osd-init {{ tuple $envAll "ceph_osd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.osd | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "osd" "container" "osd_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: # NOTE(portdirect): These environment variables will be populated # dynamicly at the point of render and added to all containers in the # pod # - name: JOURNAL_LOCATION # value: /var/lib/openstack-helm/ceph/osd/journal-one # - name: STORAGE_LOCATION # value: /var/lib/openstack-helm/ceph/osd/data-one # - name: JOURNAL_TYPE # value: directory # - name: STORAGE_TYPE # value: directory - name: CLUSTER value: "ceph" - name: DEPLOY_TOOL value: {{ .Values.deploy.tool }} - name: OSD_FORCE_REPAIR value: {{ .Values.deploy.osd_force_repair | quote }} - name: CEPH_GET_ADMIN_KEY value: "1" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} command: - /tmp/osd-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-osd-bin mountPath: /tmp/osd-init.sh subPath: osd-init.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-config.sh subPath: osd-config.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/init-ceph-volume-helper-bluestore.sh subPath: osd-init-ceph-volume-helper-bluestore.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/init-ceph-volume-helper-directory.sh subPath: osd-init-ceph-volume-helper-directory.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/init-ceph-volume-helper-block-logical.sh subPath: osd-init-ceph-volume-helper-block-logical.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/init-ceph-volume.sh subPath: osd-init-ceph-volume.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-common-ceph-volume.sh subPath: osd-common-ceph-volume.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/utils-resolveLocations.sh subPath: utils-resolveLocations.sh readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/storage.json subPath: storage.json readOnly: true - name: ceph-bootstrap-osd-keyring mountPath: /var/lib/ceph/bootstrap-osd/ceph.keyring subPath: ceph.keyring readOnly: false - name: devices mountPath: /dev readOnly: false - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false - name: pod-var-lib-ceph-tmp mountPath: /var/lib/ceph/tmp readOnly: false - name: run-lvm mountPath: /run/lvm readOnly: false - name: run-udev mountPath: /run/udev readOnly: false - name: pod-etc-lvm mountPath: /etc/lvm readOnly: false - name: data mountPath: /var/lib/ceph/osd readOnly: false - name: journal mountPath: /var/lib/ceph/journal readOnly: false - name: pod-var-log mountPath: /var/log/ceph readOnly: false - name: pod-var-crash mountPath: /var/crash mountPropagation: HostToContainer readOnly: false containers: - name: log-runner {{ tuple $envAll "ceph_osd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "osd" "container" "log_runner" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: DAEMON_NAME value: "ceph-osd" - name: TRUNCATE_SIZE value: {{ .Values.logging.truncate.size | quote }} - name: TRUNCATE_PERIOD value: {{ .Values.logging.truncate.period | quote }} - name: WAIT_FOR_OSD_ID_TIMEOUT value: {{ .Values.logging.osd_id.timeout | quote }} command: - /tmp/log-tail.sh lifecycle: preStop: exec: command: - /tmp/log-runner-stop.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ceph-osd-bin mountPath: /tmp/log-tail.sh subPath: log-tail.sh readOnly: true - name: pod-var-log mountPath: /var/log/ceph readOnly: false - name: ceph-osd-bin mountPath: /tmp/log-runner-stop.sh subPath: log-runner-stop.sh readOnly: true - name: ceph-osd-default {{ tuple $envAll "ceph_osd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.osd | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "osd" "container" "osd_pod" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: # NOTE(portdirect): These environment variables will be populated # dynamicly at the point of render. # - name: JOURNAL_LOCATION # value: /var/lib/openstack-helm/ceph/osd/journal-one # - name: STORAGE_LOCATION # value: /var/lib/openstack-helm/ceph/osd/data-one # - name: JOURNAL_TYPE # value: directory # - name: STORAGE_TYPE # value: directory - name: CLUSTER value: "ceph" - name: DEPLOY_TOOL value: {{ .Values.deploy.tool }} - name: CEPH_GET_ADMIN_KEY value: "1" - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: MON_PORT value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MON_PORT_V2 value: {{ tuple "ceph_mon" "internal" "mon_msgr2" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} command: - /tmp/osd-start.sh lifecycle: preStop: exec: command: - /tmp/osd-stop.sh {{ dict "envAll" . "component" "ceph-osd" "container" "ceph-osd" "type" "liveness" "probeTemplate" (include "osdLivenessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} {{ dict "envAll" . "component" "ceph-osd" "container" "ceph-osd" "type" "readiness" "probeTemplate" (include "osdReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: pod-forego mountPath: /etc/forego - name: ceph-osd-bin mountPath: /tmp/osd-start.sh subPath: osd-start.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-directory-ceph-volume.sh subPath: osd-directory-ceph-volume.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-block-ceph-volume.sh subPath: osd-block-ceph-volume.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-bluestore-ceph-volume.sh subPath: osd-bluestore-ceph-volume.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-check.sh subPath: osd-check.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-stop.sh subPath: osd-stop.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/utils-checkDNS.sh subPath: utils-checkDNS.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/osd-common-ceph-volume.sh subPath: osd-common-ceph-volume.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/utils-resolveLocations.sh subPath: utils-resolveLocations.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/utils-defragOSDs.sh subPath: utils-defragOSDs.sh readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/storage.json subPath: storage.json readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-bootstrap-osd-keyring mountPath: /var/lib/ceph/bootstrap-osd/ceph.keyring subPath: ceph.keyring readOnly: false - name: devices mountPath: /dev readOnly: false - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: pod-var-lib-ceph-crash mountPath: /var/lib/ceph/crash readOnly: false - name: pod-var-lib-ceph-tmp mountPath: /var/lib/ceph/tmp readOnly: false - name: run-lvm mountPath: /run/lvm readOnly: false - name: run-udev mountPath: /run/udev readOnly: false - name: pod-etc-lvm mountPath: /etc/lvm readOnly: false - name: data mountPath: /var/lib/ceph/osd readOnly: false - name: journal mountPath: /var/lib/ceph/journal readOnly: false - name: pod-var-log mountPath: /var/log/ceph readOnly: false - name: pod-var-crash mountPath: /var/crash mountPropagation: HostToContainer readOnly: false volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: pod-etc-ceph emptyDir: {} - name: pod-forego emptyDir: {} - name: devices hostPath: path: /dev - name: run-lvm hostPath: path: /run/lvm - name: run-udev hostPath: path: /run/udev - name: pod-etc-lvm emptyDir: {} - name: pod-var-lib-ceph emptyDir: {} - name: pod-var-lib-ceph-crash hostPath: path: /var/lib/openstack-helm/ceph/crash type: DirectoryOrCreate - name: pod-var-lib-ceph-tmp hostPath: path: /var/lib/openstack-helm/ceph/var-tmp type: DirectoryOrCreate - name: pod-var-crash hostPath: path: /var/crash type: DirectoryOrCreate - name: pod-var-log emptyDir: {} - name: ceph-osd-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-osd-etc configMap: name: {{ $configMapName }} defaultMode: 0444 - name: ceph-bootstrap-osd-keyring secret: secretName: {{ .Values.secrets.keyrings.osd }} # NOTE(portdirect): If directory mounts are to be used for OSD's # they will automaticly be inserted here, with the format: # - name: data # hostPath: # path: /var/lib/foo # - name: journal # hostPath: # path: /var/lib/bar {{- end }} {{- end }} {{- if .Values.manifests.daemonset_osd }} {{- $daemonset := .Values.daemonset.prefix_name }} {{- $configMapName := (printf "%s-%s" .Release.Name "etc") }} {{- $serviceAccountName := (printf "%s" .Release.Name) }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "ceph.osd.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "ceph.osd.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "ceph.utils.osd_daemonset_overrides" }} {{- end }} ================================================ FILE: ceph-osd/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ceph-osd/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-osd-bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-osd-bootstrap labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "bootstrap" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-osd-bootstrap {{ tuple $envAll "ceph_bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "ceph_osd_bootstrap" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-osd-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-osd-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-osd-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-osd-etc configMap: name: {{ printf "%s-%s" $envAll.Release.Name "etc" | quote }} defaultMode: 0444 - name: ceph-osd-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} {{- end }} ================================================ FILE: ceph-osd/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ceph-osd" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: ceph-osd/templates/job-post-apply.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if eq .Values.pod.lifecycle.upgrades.daemonsets.pod_replacement_strategy "OnDelete" }} {{- if and .Values.manifests.job_post_apply }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "post-apply" }} {{ tuple $envAll "post-apply" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - '' resources: - pods - events - jobs - pods/exec verbs: - create - get - delete - list - apiGroups: - 'apps' resources: - daemonsets verbs: - get - list - apiGroups: - 'batch' resources: - jobs verbs: - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- apiVersion: batch/v1 kind: Job metadata: name: {{ $serviceAccountName }} labels: {{ tuple $envAll "ceph-upgrade" "post-apply" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph-upgrade" "post-apply" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "ceph-osd-post-apply" "containerNames" (list "ceph-osd-post-apply" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "post_apply" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "post-apply" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-osd-post-apply {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "post_apply" "container" "ceph_osd_post_apply" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: CEPH_NAMESPACE value: {{ .Release.Namespace }} - name: RELEASE_GROUP_NAME value: {{ .Release.Name }} - name: REQUIRED_PERCENT_OF_OSDS value: {{ .Values.conf.ceph.target.required_percent_of_osds | ceil | quote }} - name: DISRUPTIVE_OSD_RESTART value: {{ .Values.conf.storage.disruptive_osd_restart | quote }} - name: UNCONDITIONAL_OSD_RESTART value: {{ .Values.conf.storage.unconditional_osd_restart | quote }} command: - /tmp/post-apply.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-osd-bin mountPath: /tmp/post-apply.sh subPath: post-apply.sh readOnly: true - name: ceph-osd-bin mountPath: /tmp/wait-for-pods.sh subPath: wait-for-pods.sh readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-osd-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-osd-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-osd-etc configMap: name: {{ printf "%s-%s" $envAll.Release.Name "etc" | quote }} defaultMode: 0444 - name: ceph-osd-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} {{- end }} {{- end }} ================================================ FILE: ceph-osd/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.helm_tests }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" $envAll.Release.Name "test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ $serviceAccountName }} labels: {{ tuple $envAll "ceph-osd" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ dict "envAll" $envAll "podName" "ceph-osd-test" "containerNames" (list "init" "ceph-cluster-helm-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} restartPolicy: Never serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: ceph-cluster-helm-test {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "ceph_cluster_helm_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: - name: CLUSTER value: "ceph" - name: CEPH_DEPLOYMENT_NAMESPACE value: {{ .Release.Namespace }} - name: REQUIRED_PERCENT_OF_OSDS value: {{ .Values.conf.ceph.target.required_percent_of_osds | ceil | quote }} command: - /tmp/helm-tests.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-osd-bin mountPath: /tmp/helm-tests.sh subPath: helm-tests.sh readOnly: true - name: ceph-client-admin-keyring mountPath: /etc/ceph/ceph.client.admin.keyring subPath: ceph.client.admin.keyring readOnly: true - name: ceph-osd-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-osd-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "bin" | quote }} defaultMode: 0555 - name: ceph-client-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin }} - name: ceph-osd-etc configMap: name: {{ printf "%s-%s" $envAll.Release.Name "etc" | quote }} defaultMode: 0444 {{- end }} ================================================ FILE: ceph-osd/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: ceph-osd/templates/utils/_osd_daemonset_overrides.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ceph.utils.match_exprs_hash" }} {{- $match_exprs := index . 0 }} {{- $context := index . 1 }} {{- $_ := set $context.Values "__match_exprs_hash_content" "" }} {{- range $match_expr := $match_exprs }} {{- $_ := set $context.Values "__match_exprs_hash_content" (print $context.Values.__match_exprs_hash_content $match_expr.key $match_expr.operator ($match_expr.values | quote)) }} {{- end }} {{- $context.Values.__match_exprs_hash_content | sha256sum | trunc 8 }} {{- $_ := unset $context.Values "__match_exprs_hash_content" }} {{- end }} {{- define "ceph.utils.osd_daemonset_overrides" }} {{- $daemonset := index . 0 }} {{- $daemonset_yaml := index . 1 }} {{- $configmap_include := index . 2 }} {{- $configmap_name := index . 3 }} {{- $context := index . 4 }} {{- $_ := unset $context ".Files" }} {{- $_ := set $context.Values "__daemonset_yaml" $daemonset_yaml }} {{- $daemonset_root_name := printf "ceph_%s" $daemonset }} {{- $_ := set $context.Values "__daemonset_list" list }} {{- $_ := set $context.Values "__default" dict }} {{- if hasKey $context.Values.conf "overrides" }} {{- range $key, $val := $context.Values.conf.overrides }} {{- if eq $key $daemonset_root_name }} {{- range $type, $type_data := . }} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{/* dictionary that will contain all info needed to generate this iteration of the daemonset */}} {{- $current_dict := dict }} {{/* set daemonset name */}} {{- $_ := set $current_dict "name" $host_data.name }} {{/* apply overrides */}} {{- $override_conf_copy := $host_data.conf }} {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}} {{- $root_conf_copy := omit ($context.Values.conf | toYaml | fromYaml) "overrides" }} {{- $merged_dict := mergeOverwrite $root_conf_copy $override_conf_copy }} {{- $root_conf_copy2 := dict "conf" $merged_dict }} {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "conf") "__daemonset_list" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $current_dict "nodeData" $root_conf_copy4 }} {{/* Schedule to this host explicitly. */}} {{- $nodeSelector_dict := dict }} {{- $_ := set $nodeSelector_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $nodeSelector_dict "operator" "In" }} {{- $values_list := list $host_data.name }} {{- $_ := set $nodeSelector_dict "values" $values_list }} {{- $list_aggregate := list $nodeSelector_dict }} {{- $_ := set $current_dict "matchExpressions" $list_aggregate }} {{/* store completed daemonset entry/info into global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $current_dict }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- end }} {{- end }} {{- if eq $type "labels" }} {{- $_ := set $context.Values "__label_list" . }} {{- range $label_data := . }} {{/* dictionary that will contain all info needed to generate this iteration of the daemonset. */}} {{- $_ := set $context.Values "__current_label" dict }} {{/* set daemonset name */}} {{- $_ := set $context.Values.__current_label "name" $label_data.label.key }} {{/* apply overrides */}} {{- $override_conf_copy := $label_data.conf }} {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}} {{- $root_conf_copy := omit ($context.Values.conf | toYaml | fromYaml) "overrides" }} {{- $merged_dict := mergeOverwrite $root_conf_copy $override_conf_copy }} {{- $root_conf_copy2 := dict "conf" $merged_dict }} {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "conf") "__daemonset_list" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__current_label "nodeData" $root_conf_copy4 }} {{/* Schedule to the provided label value(s) */}} {{- $label_dict := omit $label_data.label "NULL" }} {{- $_ := set $label_dict "operator" "In" }} {{- $list_aggregate := list $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{/* Do not schedule to other specified labels, with higher precedence as the list position increases. Last defined label is highest priority. */}} {{- $other_labels := without $context.Values.__label_list $label_data }} {{- range $label_data2 := $other_labels }} {{- $label_dict := omit $label_data2.label "NULL" }} {{- $_ := set $label_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{- end }} {{- $_ := set $context.Values "__label_list" $other_labels }} {{/* Do not schedule to any other specified hosts */}} {{- range $type, $type_data := $val }} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{- $label_dict := dict }} {{- $_ := set $label_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $label_dict "operator" "NotIn" }} {{- $values_list := list $host_data.name }} {{- $_ := set $label_dict "values" $values_list }} {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{- end }} {{/* store completed daemonset entry/info into global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__current_label }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- $_ := unset $context.Values "__current_label" }} {{- end }} {{- end }} {{- end }} {{/* scheduler exceptions for the default daemonset */}} {{- $_ := set $context.Values.__default "matchExpressions" list }} {{- range $type, $type_data := . }} {{/* Do not schedule to other specified labels */}} {{- if eq $type "labels" }} {{- range $label_data := . }} {{- $default_dict := omit $label_data.label "NULL" }} {{- $_ := set $default_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }} {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{/* Do not schedule to other specified hosts */}} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{- $default_dict := dict }} {{- $_ := set $default_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $default_dict "operator" "NotIn" }} {{- $values_list := list $host_data.name }} {{- $_ := set $default_dict "values" $values_list }} {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }} {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{/* generate the default daemonset */}} {{/* set name */}} {{- $_ := set $context.Values.__default "name" "default" }} {{/* no overrides apply, so copy as-is */}} {{- $root_conf_copy1 := omit $context.Values.conf "overrides" }} {{- $root_conf_copy2 := dict "conf" $root_conf_copy1 }} {{- $context_values := omit $context.Values "conf" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__default "nodeData" $root_conf_copy4 }} {{/* add to global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__default }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- $_ := set $context.Values "__last_configmap_name" $configmap_name }} {{- range $current_dict := $context.Values.__daemonset_list }} {{- $context_novalues := omit $context "Values" }} {{- $merged_dict := mergeOverwrite $context_novalues $current_dict.nodeData }} {{- $_ := set $current_dict "nodeData" $merged_dict }} {{/* name needs to be a DNS-1123 compliant name. Ensure lower case */}} {{- $name_format1 := printf (print $daemonset_root_name "-" $current_dict.name) | lower }} {{/* labels may contain underscores which would be invalid here, so we replace them with dashes there may be other valid label names which would make for an invalid DNS-1123 name but these will be easier to handle in future with sprig regex* functions (not availabile in helm 2.5.1) */}} {{- $name_format2 := $name_format1 | replace "_" "-" | replace "." "-" }} {{/* To account for the case where the same label is defined multiple times in overrides (but with different label values), we add a sha of the scheduling data to ensure name uniqueness */}} {{- $_ := set $current_dict "dns_1123_name" dict }} {{- if hasKey $current_dict "matchExpressions" }} {{- $_ := set $current_dict "dns_1123_name" (printf (print $name_format2 "-" (list $current_dict.matchExpressions $context | include "ceph.utils.match_exprs_hash"))) }} {{- else }} {{- $_ := set $current_dict "dns_1123_name" $name_format2 }} {{- end }} {{/* set daemonset metadata name */}} {{- if not $context.Values.__daemonset_yaml.metadata }}{{- $_ := set $context.Values.__daemonset_yaml "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.metadata.name }}{{- $_ := set $context.Values.__daemonset_yaml.metadata "name" dict }}{{- end }} {{- $_ := set $context.Values.__daemonset_yaml.metadata "name" $current_dict.dns_1123_name }} {{/* cross-reference configmap name to container volume definitions */}} {{- $_ := set $context.Values "__volume_list" list }} {{- range $current_volume := $context.Values.__daemonset_yaml.spec.template.spec.volumes }} {{- $_ := set $context.Values "__volume" $current_volume }} {{- if hasKey $context.Values.__volume "configMap" }} {{- if eq $context.Values.__volume.configMap.name $context.Values.__last_configmap_name }} {{- $_ := set $context.Values.__volume.configMap "name" $current_dict.dns_1123_name }} {{- end }} {{- end }} {{- $updated_list := append $context.Values.__volume_list $context.Values.__volume }} {{- $_ := set $context.Values "__volume_list" $updated_list }} {{- end }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "volumes" $context.Values.__volume_list }} {{/* populate scheduling restrictions */}} {{- if hasKey $current_dict "matchExpressions" }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "affinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity "nodeAffinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity "requiredDuringSchedulingIgnoredDuringExecution" dict }}{{- end }} {{- $match_exprs := dict }} {{- $_ := set $match_exprs "matchExpressions" $current_dict.matchExpressions }} {{- $appended_match_expr := list $match_exprs }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution "nodeSelectorTerms" $appended_match_expr }} {{- end }} {{/* input value hash for current set of values overrides */}} {{- if not $context.Values.__daemonset_yaml.spec }}{{- $_ := set $context.Values.__daemonset_yaml "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template }}{{- $_ := set $context.Values.__daemonset_yaml.spec "template" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata.annotations }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata "annotations" dict }}{{- end }} {{- $cmap := list $current_dict.dns_1123_name $current_dict.nodeData | include $configmap_include }} {{- $values_hash := $cmap | quote | sha256sum }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata.annotations "configmap-etc-hash" $values_hash }} {{/* generate configmap */}} --- {{ $cmap }} {{/* generate daemonset yaml */}} {{ range $k, $v := index $current_dict.nodeData.Values.conf.storage "osd" }} --- {{- $_ := set $context.Values "__tmpYAML" dict }} {{ $dsNodeName := index $context.Values.__daemonset_yaml.metadata "name" }} {{ $localDsNodeName := print (trunc 54 $current_dict.dns_1123_name) "-" (print $dsNodeName $k | quote | sha256sum | trunc 8) }} {{- if not $context.Values.__tmpYAML.metadata }}{{- $_ := set $context.Values.__tmpYAML "metadata" dict }}{{- end }} {{- $_ := set $context.Values.__tmpYAML.metadata "name" $localDsNodeName }} {{ $podDataVols := index $context.Values.__daemonset_yaml.spec.template.spec "volumes" }} {{- $_ := set $context.Values "__tmpPodVols" $podDataVols }} {{ if eq $v.data.type "directory" }} {{ $dataDirVolume := dict "hostPath" (dict "path" $v.data.location) "name" "data" }} {{ $newPodDataVols := append $context.Values.__tmpPodVols $dataDirVolume }} {{- $_ := set $context.Values "__tmpPodVols" $newPodDataVols }} {{ else }} {{ $dataDirVolume := dict "emptyDir" dict "name" "data" }} {{ $newPodDataVols := append $context.Values.__tmpPodVols $dataDirVolume }} {{- $_ := set $context.Values "__tmpPodVols" $newPodDataVols }} {{ end }} {{- if ne $v.data.type "bluestore" }} {{ if eq $v.journal.type "directory" }} {{ $journalDirVolume := dict "hostPath" (dict "path" $v.journal.location) "name" "journal" }} {{ $newPodDataVols := append $context.Values.__tmpPodVols $journalDirVolume }} {{- $_ := set $context.Values "__tmpPodVols" $newPodDataVols }} {{ else }} {{ $dataDirVolume := dict "emptyDir" dict "name" "journal" }} {{ $newPodDataVols := append $context.Values.__tmpPodVols $dataDirVolume }} {{- $_ := set $context.Values "__tmpPodVols" $newPodDataVols }} {{ end }} {{ else }} {{ $dataDirVolume := dict "emptyDir" dict "name" "journal" }} {{ $newPodDataVols := append $context.Values.__tmpPodVols $dataDirVolume }} {{- $_ := set $context.Values "__tmpPodVols" $newPodDataVols }} {{- end }} {{- if not $context.Values.__tmpYAML.spec }}{{- $_ := set $context.Values.__tmpYAML "spec" dict }}{{- end }} {{- if not $context.Values.__tmpYAML.spec.template }}{{- $_ := set $context.Values.__tmpYAML.spec "template" dict }}{{- end }} {{- if not $context.Values.__tmpYAML.spec.template.spec }}{{- $_ := set $context.Values.__tmpYAML.spec.template "spec" dict }}{{- end }} {{- $_ := set $context.Values.__tmpYAML.spec.template.spec "volumes" $context.Values.__tmpPodVols }} {{- if not $context.Values.__tmpYAML.spec }}{{- $_ := set $context.Values.__tmpYAML "spec" dict }}{{- end }} {{- if not $context.Values.__tmpYAML.spec.template }}{{- $_ := set $context.Values.__tmpYAML.spec "template" dict }}{{- end }} {{- if not $context.Values.__tmpYAML.spec.template.spec }}{{- $_ := set $context.Values.__tmpYAML.spec.template "spec" dict }}{{- end }} {{- if not $context.Values.__tmpYAML.spec.template.spec.containers }}{{- $_ := set $context.Values.__tmpYAML.spec.template.spec "containers" list }}{{- end }} {{- if not $context.Values.__tmpYAML.spec.template.spec.initContainers }}{{- $_ := set $context.Values.__tmpYAML.spec.template.spec "initContainers" list }}{{- end }} {{- $_ := set $context.Values "__tmpYAMLcontainers" list }} {{- range $podContainer := $context.Values.__daemonset_yaml.spec.template.spec.containers }} {{- $_ := set $context.Values "_tmpYAMLcontainer" $podContainer }} {{- if empty $context.Values._tmpYAMLcontainer.env }} {{- $_ := set $context.Values._tmpYAMLcontainer "env" ( list ) }} {{- end }} {{- $tmpcontainerEnv := omit $context.Values._tmpYAMLcontainer "env" }} {{- if eq $v.data.type "bluestore" }} {{- if and $v.block_db $v.block_wal}} {{ $containerEnv := prepend (prepend (prepend ( prepend ( prepend ( prepend (index $context.Values._tmpYAMLcontainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "BLOCK_DB" "value" $v.block_db.location)) (dict "name" "BLOCK_DB_SIZE" "value" $v.block_db.size)) (dict "name" "BLOCK_WAL" "value" $v.block_wal.location)) (dict "name" "BLOCK_WAL_SIZE" "value" $v.block_wal.size) }} {{- $_ := set $tmpcontainerEnv "env" $containerEnv }} {{- else if $v.block_db }} {{ $containerEnv := prepend (prepend ( prepend ( prepend (index $context.Values._tmpYAMLcontainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "BLOCK_DB" "value" $v.block_db.location)) (dict "name" "BLOCK_DB_SIZE" "value" $v.block_db.size) }} {{- $_ := set $tmpcontainerEnv "env" $containerEnv }} {{- else if $v.block_wal }} {{ $containerEnv := prepend (prepend ( prepend ( prepend (index $context.Values._tmpYAMLcontainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "BLOCK_WAL" "value" $v.block_wal.location)) (dict "name" "BLOCK_WAL_SIZE" "value" $v.block_wal.size) }} {{- $_ := set $tmpcontainerEnv "env" $containerEnv }} {{ else }} {{ $containerEnv := prepend (prepend (index $context.Values._tmpYAMLcontainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location) }} {{- $_ := set $tmpcontainerEnv "env" $containerEnv }} {{- end }} {{ else }} {{ $containerEnv := prepend (prepend (prepend ( prepend (index $context.Values._tmpYAMLcontainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "JOURNAL_TYPE" "value" $v.journal.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "JOURNAL_LOCATION" "value" $v.journal.location) }} {{- $_ := set $tmpcontainerEnv "env" $containerEnv }} {{- end }} {{- $localInitContainerEnv := omit $context.Values._tmpYAMLcontainer "env" }} {{- $_ := set $localInitContainerEnv "env" $tmpcontainerEnv.env }} {{ $containerList := append $context.Values.__tmpYAMLcontainers $localInitContainerEnv }} {{ $_ := set $context.Values "__tmpYAMLcontainers" $containerList }} {{ end }} {{- $_ := set $context.Values.__tmpYAML.spec.template.spec "containers" $context.Values.__tmpYAMLcontainers }} {{- $_ := set $context.Values "__tmpYAMLinitContainers" list }} {{- range $podContainer := $context.Values.__daemonset_yaml.spec.template.spec.initContainers }} {{- $_ := set $context.Values "_tmpYAMLinitContainer" $podContainer }} {{- $tmpinitcontainerEnv := omit $context.Values._tmpYAMLinitContainer "env" }} {{- if eq $v.data.type "bluestore" }} {{- if and $v.block_db $v.block_wal}} {{ $initcontainerEnv := prepend (prepend (prepend ( prepend ( prepend ( prepend (index $context.Values._tmpYAMLinitContainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "BLOCK_DB" "value" $v.block_db.location)) (dict "name" "BLOCK_DB_SIZE" "value" $v.block_db.size)) (dict "name" "BLOCK_WAL" "value" $v.block_wal.location)) (dict "name" "BLOCK_WAL_SIZE" "value" $v.block_wal.size) }} {{- $_ := set $tmpinitcontainerEnv "env" $initcontainerEnv }} {{- else if $v.block_db }} {{ $initcontainerEnv := prepend (prepend ( prepend ( prepend (index $context.Values._tmpYAMLinitContainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "BLOCK_DB" "value" $v.block_db.location)) (dict "name" "BLOCK_DB_SIZE" "value" $v.block_db.size) }} {{- $_ := set $tmpinitcontainerEnv "env" $initcontainerEnv }} {{- else if $v.block_wal }} {{ $initcontainerEnv := prepend (prepend ( prepend ( prepend (index $context.Values._tmpYAMLinitContainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "BLOCK_WAL" "value" $v.block_wal.location)) (dict "name" "BLOCK_WAL_SIZE" "value" $v.block_wal.size) }} {{- $_ := set $tmpinitcontainerEnv "env" $initcontainerEnv }} {{ else }} {{ $initcontainerEnv := prepend (prepend (index $context.Values._tmpYAMLinitContainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location) }} {{- $_ := set $tmpinitcontainerEnv "env" $initcontainerEnv }} {{- end }} {{ else }} {{ $initcontainerEnv := prepend (prepend (prepend ( prepend (index $context.Values._tmpYAMLinitContainer "env") (dict "name" "STORAGE_TYPE" "value" $v.data.type)) (dict "name" "JOURNAL_TYPE" "value" $v.journal.type)) (dict "name" "STORAGE_LOCATION" "value" $v.data.location)) (dict "name" "JOURNAL_LOCATION" "value" $v.journal.location) }} {{- $_ := set $tmpinitcontainerEnv "env" $initcontainerEnv }} {{- end }} {{- $localInitContainerEnv := omit $context.Values._tmpYAMLinitContainer "env" }} {{- $_ := set $localInitContainerEnv "env" $tmpinitcontainerEnv.env }} {{ $initContainerList := append $context.Values.__tmpYAMLinitContainers $localInitContainerEnv }} {{ $_ := set $context.Values "__tmpYAMLinitContainers" $initContainerList }} {{ end }} {{- $_ := set $context.Values.__tmpYAML.spec.template.spec "initContainers" $context.Values.__tmpYAMLinitContainers }} {{- $_ := set $context.Values.__tmpYAML.spec.template.spec "volumes" $context.Values.__tmpPodVols }} {{ merge $context.Values.__tmpYAML $context.Values.__daemonset_yaml | toYaml }} {{ end }} --- {{- $_ := set $context.Values "__last_configmap_name" $current_dict.dns_1123_name }} {{- end }} {{- end }} ================================================ FILE: ceph-osd/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for ceph-osd. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- images: pull_policy: IfNotPresent tags: ceph_osd: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_bootstrap: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_config_helper: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' image_repo_sync: 'quay.io/airshipit/docker:27.5.0' local_registry: active: false exclude: - dep_check - image_repo_sync labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled osd: node_selector_key: ceph-osd node_selector_value: enabled # The default deploy tool is ceph-volume. "ceph-disk" was finally removed as it # had been deprecated from Nautilus and was not being used. deploy: tool: "ceph-volume" # NOTE: set this to 1 if osd disk needs wiping in case of reusing from previous deployment osd_force_repair: 1 pod: security_context: osd: pod: runAsUser: 65534 container: ceph_init_dirs: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: true ceph_log_ownership: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: true osd_init: runAsUser: 0 privileged: true readOnlyRootFilesystem: true osd_pod: runAsUser: 0 privileged: true readOnlyRootFilesystem: true log_runner: # run as "ceph" user runAsUser: 64045 allowPrivilegeEscalation: false readOnlyRootFilesystem: true bootstrap: pod: runAsUser: 65534 container: ceph_osd_bootstrap: allowPrivilegeEscalation: false readOnlyRootFilesystem: true post_apply: pod: runAsUser: 65534 container: ceph_osd_post_apply: allowPrivilegeEscalation: false readOnlyRootFilesystem: true test: pod: runAsUser: 65534 container: ceph_cluster_helm_test: allowPrivilegeEscalation: false readOnlyRootFilesystem: true dns_policy: "ClusterFirstWithHostNet" lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate osd: enabled: true min_ready_seconds: 0 max_unavailable: 1 affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 resources: enabled: false osd: requests: memory: "2Gi" cpu: "1000m" limits: memory: "5Gi" cpu: "2000m" tests: requests: memory: "10Mi" cpu: "250m" limits: memory: "50Mi" cpu: "500m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" probes: ceph-osd: ceph-osd: readiness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 60 timeoutSeconds: 5 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 60 timeoutSeconds: 5 secrets: keyrings: osd: ceph-bootstrap-osd-keyring admin: ceph-client-admin-keyring oci_image_registry: ceph-osd: ceph-osh-oci-image-registry-key network: public: 192.168.0.0/16 cluster: 192.168.0.0/16 jobs: ceph_defragosds: # Execute the 1st of each month cron: "0 0 1 * *" history: # Number of successful job to keep successJob: 1 # Number of failed job to keep failJob: 1 concurrency: # Skip new job if previous job still active execPolicy: Forbid startingDeadlineSecs: 60 conf: ceph: global: # auth cephx: true cephx_require_signatures: false cephx_cluster_require_signatures: true cephx_service_require_signatures: false objecter_inflight_op_bytes: "1073741824" objecter_inflight_ops: 10240 debug_ms: "0/0" mon_osd_down_out_interval: 1800 mon_osd_down_out_subtree_limit: root mon_osd_min_in_ratio: 0 mon_osd_min_up_ratio: 0 osd: osd_mkfs_type: xfs osd_mkfs_options_xfs: -f -i size=2048 osd_max_object_name_len: 256 ms_bind_port_min: 6800 ms_bind_port_max: 7100 osd_snap_trim_priority: 1 osd_snap_trim_sleep: 0.1 osd_pg_max_concurrent_snap_trims: 1 filestore_merge_threshold: -10 filestore_split_multiple: 12 filestore_max_sync_interval: 10 osd_scrub_begin_hour: 22 osd_scrub_end_hour: 4 osd_scrub_during_recovery: false osd_scrub_sleep: 0.1 osd_scrub_chunk_min: 1 osd_scrub_chunk_max: 4 osd_scrub_load_threshold: 10.0 osd_deep_scrub_stride: "1048576" osd_scrub_priority: 1 osd_recovery_op_priority: 1 osd_recovery_max_active: 1 osd_mount_options_xfs: "rw,noatime,largeio,inode64,swalloc,logbufs=8,logbsize=256k,allocsize=4M" osd_journal_size: 10240 osd_crush_update_on_start: false bluestore_elastic_shared_blobs: false target: # This is just for helm tests to proceed the deployment if we have mentioned % of # osds are up and running. required_percent_of_osds: 75 storage: # NOTE(supamatt): By default use host based buckets for failure domains. Any `failure_domain` defined must # match the failure domain used on your CRUSH rules for pools. For example with a crush rule of # rack_replicated_rule you would specify "rack" as the `failure_domain` to use. # `failure_domain`: Set the CRUSH bucket type for your OSD to reside in. See the supported CRUSH configuration # as listed here: Supported CRUSH configuration is listed here: http://docs.ceph.com/docs/nautilus/rados/operations/crush-map/ # if failure domain is rack then it will check for node label "rack" and get the value from it to create the rack, if there # is no label rack then it will use following options. # `failure_domain_by_hostname`: Specify the portion of the hostname to use for your failure domain bucket name. # `failure_domain_by_hostname_map`: Explicit mapping of hostname to failure domain, as a simpler alternative to overrides. # `failure_domain_name`: Manually name the failure domain bucket name. This configuration option should only be used # when using host based overrides. failure_domain: "host" failure_domain_by_hostname: "false" failure_domain_by_hostname_map: {} # Example: # failure_domain_map_hostname_map: # hostfoo: rack1 # hostbar: rack1 # hostbaz: rack2 # hostqux: rack2 failure_domain_name: "false" # Note: You can override the device class by adding the value (e.g., hdd, ssd or nvme). # Leave it empty if you don't need to modify the device class. device_class: "" # NOTE(portdirect): for homogeneous clusters the `osd` key can be used to # define OSD pods that will be deployed across the cluster. # when specifing whole disk (/dev/sdf) for journals, ceph-osd chart will create # needed partitions for each OSDs. osd: # Below is the current configuration default, which is Bluestore with co-located metadata # - data: # type: bluestore # location: /dev/sdb # Use a valid device here # Separate block devices may be used for block.db and/or block.wal # Specify the location and size in Gb. It is recommended that the # block_db size isn't smaller than 4% of block. For example, if the # block size is 1TB, then block_db shouldn't be less than 40GB. # A size suffix of K for kilobytes, M for megabytes, G for gigabytes, # T for terabytes, P for petabytes or E for exabytes is optional. # Default unit is megabytes. # block_db: # location: /dev/sdc # size: "96GB" # block_wal: # location: /dev/sdc # size: "2GB" # Block-based Filestore OSDs with separate journal block devices # - data: # type: block-logical # location: /dev/sdd # journal: # type: block-logical # location: /dev/sdf1 # - data: # type: block-logical # location: /dev/sde # journal: # type: block-logical # location: /dev/sdf2 # Block-based Filestore OSDs with directory-based journals # - data: # type: block-logical # location: /dev/sdg # journal: # type: directory # location: /var/lib/openstack-helm/ceph/osd/journal-sdg # Directory-based Filestore OSD # - data: # type: directory # location: /var/lib/openstack-helm/ceph/osd/osd-one # journal: # type: directory # location: /var/lib/openstack-helm/ceph/osd/journal-one # The post-apply job will restart OSDs without disruption by default. Set # this value to "true" to restart all OSDs at once. This will accomplish # OSD restarts more quickly with disruption. disruptive_osd_restart: "false" # The post-apply job will try to determine if OSDs need to be restarted and # only restart them if necessary. Set this value to "true" to restart OSDs # unconditionally. unconditional_osd_restart: "false" # NOTE(portdirect): for heterogeneous clusters the overrides section can be used to define # OSD pods that will be deployed upon specifc nodes. # overrides: # ceph_osd: # hosts: # - name: host1.fqdn # conf: # storage: # failure_domain_name: "rack1" # osd: # - data: # type: directory # location: /var/lib/openstack-helm/ceph/osd/data-three # journal: # type: directory # location: /var/lib/openstack-helm/ceph/osd/journal-three daemonset: prefix_name: "osd" dependencies: dynamic: common: local_image_registry: jobs: - ceph-osd-image-repo-sync services: - endpoint: node service: local_image_registry static: osd: jobs: - ceph-storage-keys-generator - ceph-osd-keyring-generator services: - endpoint: internal service: ceph_mon image_repo_sync: services: - endpoint: internal service: local_image_registry tests: jobs: - ceph-storage-keys-generator - ceph-osd-keyring-generator services: - endpoint: internal service: ceph_mon logging: truncate: size: 0 period: 3600 osd_id: timeout: 300 bootstrap: enabled: true script: | ceph -s endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ceph-osd: username: ceph-osd password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null ceph_mon: namespace: null hosts: default: ceph-mon discovery: ceph-mon-discovery host_fqdn_override: default: null port: mon: default: 6789 mon_msgr2: default: 3300 manifests: configmap_bin: true configmap_etc: true configmap_test_bin: true daemonset_osd: true job_bootstrap: false job_post_apply: true job_image_repo_sync: true helm_tests: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ceph-provisioners/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Ceph Provisioner name: ceph-provisioners version: 2025.2.0 home: https://github.com/ceph/ceph dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ceph-provisioners/crds/snapshot.storage.k8s.io_volumesnapshotclasses.yaml ================================================ --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.8.0 api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshotclasses.snapshot.storage.k8s.io spec: group: snapshot.storage.k8s.io names: kind: VolumeSnapshotClass listKind: VolumeSnapshotClassList plural: volumesnapshotclasses shortNames: - vsclass - vsclasses singular: volumesnapshotclass scope: Cluster versions: - additionalPrinterColumns: - jsonPath: .driver name: Driver type: string - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. jsonPath: .deletionPolicy name: DeletionPolicy type: string - jsonPath: .metadata.creationTimestamp name: Age type: date name: v1 schema: openAPIV3Schema: description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string deletionPolicy: description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. enum: - Delete - Retain type: string driver: description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string parameters: additionalProperties: type: string description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. type: object required: - deletionPolicy - driver type: object served: true storage: true subresources: {} status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] ... ================================================ FILE: ceph-provisioners/crds/snapshot.storage.k8s.io_volumesnapshotcontents.yaml ================================================ --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.8.0 api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshotcontents.snapshot.storage.k8s.io spec: group: snapshot.storage.k8s.io names: kind: VolumeSnapshotContent listKind: VolumeSnapshotContentList plural: volumesnapshotcontents shortNames: - vsc - vscs singular: volumesnapshotcontent scope: Cluster versions: - additionalPrinterColumns: - description: Indicates if the snapshot is ready to be used to restore a volume. jsonPath: .status.readyToUse name: ReadyToUse type: boolean - description: Represents the complete size of the snapshot in bytes jsonPath: .status.restoreSize name: RestoreSize type: integer - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. jsonPath: .spec.deletionPolicy name: DeletionPolicy type: string - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. jsonPath: .spec.driver name: Driver type: string - description: Name of the VolumeSnapshotClass to which this snapshot belongs. jsonPath: .spec.volumeSnapshotClassName name: VolumeSnapshotClass type: string - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. jsonPath: .spec.volumeSnapshotRef.name name: VolumeSnapshot type: string - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. jsonPath: .spec.volumeSnapshotRef.namespace name: VolumeSnapshotNamespace type: string - jsonPath: .metadata.creationTimestamp name: Age type: date name: v1 schema: openAPIV3Schema: description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string spec: description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. properties: deletionPolicy: description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. enum: - Delete - Retain type: string driver: description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. type: string source: description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. properties: snapshotHandle: description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. type: string volumeHandle: description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. type: string type: object oneOf: - required: ["snapshotHandle"] - required: ["volumeHandle"] sourceVolumeMode: description: SourceVolumeMode is the mode of the volume whose snapshot is taken. Can be either “Filesystem” or “Block”. If not specified, it indicates the source volume's mode is unknown. This field is immutable. This field is an alpha field. type: string volumeSnapshotClassName: description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. type: string volumeSnapshotRef: description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. properties: apiVersion: description: API version of the referent. type: string fieldPath: description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' type: string kind: description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string namespace: description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' type: string resourceVersion: description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' type: string uid: description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' type: string type: object required: - deletionPolicy - driver - source - volumeSnapshotRef type: object status: description: status represents the current information of a snapshot. properties: creationTime: description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. format: int64 type: integer error: description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. properties: message: description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' type: string time: description: time is the timestamp when the error was encountered. format: date-time type: string type: object readyToUse: description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. type: boolean restoreSize: description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. format: int64 minimum: 0 type: integer snapshotHandle: description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. type: string type: object required: - spec type: object served: true storage: true subresources: status: {} status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] ... ================================================ FILE: ceph-provisioners/crds/snapshot.storage.k8s.io_volumesnapshots.yaml ================================================ --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.8.0 api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/665" creationTimestamp: null name: volumesnapshots.snapshot.storage.k8s.io spec: group: snapshot.storage.k8s.io names: kind: VolumeSnapshot listKind: VolumeSnapshotList plural: volumesnapshots shortNames: - vs singular: volumesnapshot scope: Namespaced versions: - additionalPrinterColumns: - description: Indicates if the snapshot is ready to be used to restore a volume. jsonPath: .status.readyToUse name: ReadyToUse type: boolean - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. jsonPath: .spec.source.persistentVolumeClaimName name: SourcePVC type: string - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. jsonPath: .spec.source.volumeSnapshotContentName name: SourceSnapshotContent type: string - description: Represents the minimum size of volume required to rehydrate from this snapshot. jsonPath: .status.restoreSize name: RestoreSize type: string - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. jsonPath: .spec.volumeSnapshotClassName name: SnapshotClass type: string - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. jsonPath: .status.boundVolumeSnapshotContentName name: SnapshotContent type: string - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. jsonPath: .status.creationTime name: CreationTime type: date - jsonPath: .metadata.creationTimestamp name: Age type: date name: v1 schema: openAPIV3Schema: description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string spec: description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' properties: source: description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. properties: persistentVolumeClaimName: description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. type: string volumeSnapshotContentName: description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. type: string type: object oneOf: - required: ["persistentVolumeClaimName"] - required: ["volumeSnapshotContentName"] volumeSnapshotClassName: description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' type: string required: - source type: object status: description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. properties: boundVolumeSnapshotContentName: description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' type: string creationTime: description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. format: date-time type: string error: description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurs during the snapshot creation. Upon success, this error field will be cleared. properties: message: description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' type: string time: description: time is the timestamp when the error was encountered. format: date-time type: string type: object readyToUse: description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. type: boolean restoreSize: type: string description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true type: object required: - spec type: object served: true storage: true subresources: status: {} status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] ... ================================================ FILE: ceph-provisioners/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: ceph-provisioners/templates/bin/_helm-tests.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex function reset_test_env() { pvc_namespace=$1 pod_name=$2 pvc_name=$3 echo "--> Resetting POD and PVC before/after test" if kubectl get pod -n $pvc_namespace $pod_name; then kubectl delete pod -n $pvc_namespace $pod_name fi if kubectl get cm -n $pvc_namespace ${pod_name}-bin; then kubectl delete cm -n $pvc_namespace ${pod_name}-bin fi if kubectl get pvc -n $pvc_namespace $pvc_name; then kubectl delete pvc -n $pvc_namespace $pvc_name; fi } function storageclass_validation() { pvc_namespace=$1 pod_name=$2 pvc_name=$3 storageclass=$4 echo "--> Starting validation" # storageclass check if ! kubectl get storageclass $storageclass; then echo "Storageclass: $storageclass is not provisioned." exit 1 fi tee < Checking RBD storage class." storageclass={{ $val.metadata.name }} storageclass_validation $PVC_NAMESPACE $RBD_TEST_POD_NAME $RBD_TEST_PVC_NAME $storageclass reset_test_env $PVC_NAMESPACE $RBD_TEST_POD_NAME $RBD_TEST_PVC_NAME fi if [ {{ $val.provisioner }} == "ceph.rbd.csi.ceph.com" ] && [ {{ $val.provision_storage_class }} == true ]; then echo "--> Checking CSI RBD storage class." storageclass={{ $val.metadata.name }} storageclass_validation $PVC_NAMESPACE $CSI_RBD_TEST_POD_NAME $CSI_RBD_TEST_PVC_NAME $storageclass reset_test_env $PVC_NAMESPACE $CSI_RBD_TEST_POD_NAME $CSI_RBD_TEST_PVC_NAME fi if [ {{ $val.provisioner }} == "ceph.com/cephfs" ] && [ {{ $val.provision_storage_class }} == true ]; then echo "--> Checking cephfs storage class." storageclass={{ $val.metadata.name }} storageclass_validation $PVC_NAMESPACE $CEPHFS_TEST_POD_NAME $CEPHFS_TEST_PVC_NAME $storageclass reset_test_env $PVC_NAMESPACE $CEPHFS_TEST_POD_NAME $CEPHFS_TEST_PVC_NAME fi {{- end }} ================================================ FILE: ceph-provisioners/templates/bin/provisioner/cephfs/_client-key-manager.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- $envAll := . }} CEPH_CEPHFS_KEY=$(kubectl get secret ${PVC_CEPH_CEPHFS_STORAGECLASS_ADMIN_SECRET_NAME} \ --namespace=${PVC_CEPH_CEPHFS_STORAGECLASS_DEPLOYED_NAMESPACE} \ -o json ) ceph_activate_namespace() { kube_namespace=$1 secret_type=$2 secret_name=$3 ceph_key=$4 { cat <= 0.1.0" ... ================================================ FILE: ceph-rgw/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: ceph-rgw/templates/bin/_ceph-admin-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat < /etc/ceph/ceph.client.admin.keyring [client.admin] key = $(cat /tmp/client-keyring) EOF exit 0 ================================================ FILE: ceph-rgw/templates/bin/_ceph-rgw-storage-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x if [ "x$STORAGE_BACKEND" == "xceph-rgw" ]; then SECRET=$(mktemp --suffix .yaml) KEYRING=$(mktemp --suffix .keyring) function cleanup { rm -f ${SECRET} ${KEYRING} } trap cleanup EXIT fi function kube_ceph_keyring_gen () { CEPH_KEY=$1 CEPH_KEY_TEMPLATE=$2 sed "s|{{"{{"}} key {{"}}"}}|${CEPH_KEY}|" /tmp/ceph-templates/${CEPH_KEY_TEMPLATE} | base64 -w0 | tr -d '\n' } set -ex if [ "x$STORAGE_BACKEND" == "xceph-rgw" ]; then ceph -s if USERINFO=$(ceph auth get client.bootstrap-rgw); then KEYSTR=$(echo $USERINFO | sed 's/.*\( key = .*\) caps mon.*/\1/') echo $KEYSTR > ${KEYRING} else #NOTE(Portdirect): Determine proper privs to assign keyring ceph auth get-or-create client.bootstrap-rgw \ mon "allow profile bootstrap-rgw" \ -o ${KEYRING} fi FINAL_KEYRING=$(sed -n 's/^[[:blank:]]*key[[:blank:]]\+=[[:blank:]]\(.*\)/\1/p' ${KEYRING}) cat > ${SECRET} </dev/null || true) if [[ -z "$RGW_PLACEMENT_TARGET_EXISTS" ]]; then create_rgw_placement_target "$RGW_ZONEGROUP" "$RGW_PLACEMENT_TARGET" add_rgw_zone_placement "$RGW_ZONE" "$RGW_PLACEMENT_TARGET" "$RGW_PLACEMENT_TARGET_DATA_POOL" "$RGW_PLACEMENT_TARGET_INDEX_POOL" "$RGW_PLACEMENT_TARGET_DATA_EXTRA_POOL" RGW_PLACEMENT_TARGET_EXISTS=$(radosgw-admin zonegroup placement get --placement-id "$RGW_PLACEMENT_TARGET" 2>/dev/null || true) fi if [[ -n "$RGW_PLACEMENT_TARGET_EXISTS" ]] && [[ "true" == "$RGW_DELETE_PLACEMENT_TARGET" ]]; then rm_rgw_zone_placement "$RGW_ZONE" "$RGW_PLACEMENT_TARGET" delete_rgw_placement_target "$RGW_ZONEGROUP" "$RGW_PLACEMENT_TARGET" fi {{- end }} ================================================ FILE: ceph-rgw/templates/bin/_helm-tests.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex tmpdir=$(mktemp -d) declare -a objects_list total_objects=10 #NOTE: This function tests keystone based auth. It uses ceph_config_helper #container image that has openstack and ceph installed function rgw_keystone_bucket_validation () { echo "function: rgw_keystone_bucket_validation" openstack service list bucket_stat="$(openstack container list | grep openstack_test_container || true)" if [[ -n "${bucket_stat}" ]]; then echo "--> deleting openstack_test_container container" openstack container delete --recursive openstack_test_container fi echo "--> creating openstack_test_container container" openstack container create 'openstack_test_container' echo "--> list containers" openstack container list bucket_stat="$(openstack container list | grep openstack_test_container || true)" if [[ -z "${bucket_stat}" ]]; then echo "--> container openstack_test_container not found" exit 1 else echo "--> container openstack_test_container found" for i in $(seq $total_objects); do openstack object create --name "${objects_list[$i]}" openstack_test_container "${objects_list[$i]}" echo "--> file ${objects_list[$i]} uploaded to openstack_test_container container" done echo "--> list contents of openstack_test_container container" openstack object list openstack_test_container for i in $(seq $total_objects); do echo "--> downloading ${objects_list[$i]} object from openstack_test_container container to ${objects_list[$i]}_object${i} file" openstack object save --file "${objects_list[$i]}_object${i}" openstack_test_container "${objects_list[$i]}" check_result $? "Error during openstack CLI execution" "The object downloaded successfully" echo "--> comparing files: ${objects_list[$i]} and ${objects_list[$i]}_object${i}" cmp "${objects_list[$i]}" "${objects_list[$i]}_object${i}" check_result $? "The files are not equal" "The files are equal" echo "--> deleting ${objects_list[$i]} object from openstack_test_container container" openstack object delete openstack_test_container "${objects_list[$i]}" check_result $? "Error during openstack CLI execution" "The object deleted successfully" done echo "--> deleting openstack_test_container container" openstack container delete --recursive openstack_test_container echo "--> bucket list after deleting container" openstack container list fi } #NOTE: This function tests s3 based auto. It uses ceph_rgw container image which has # s3cmd util install function rgw_s3_bucket_validation () { echo "function: rgw_s3_bucket_validation" bucket=s3://rgw-test-bucket {{- if .Values.manifests.certificates }} params="--host=$RGW_HOST --host-bucket=$RGW_HOST --access_key=$S3_ADMIN_ACCESS_KEY --secret_key=$S3_ADMIN_SECRET_KEY --ca-certs=/etc/tls/ca.crt" {{- else }} params="--host=$RGW_HOST --host-bucket=$RGW_HOST --access_key=$S3_ADMIN_ACCESS_KEY --secret_key=$S3_ADMIN_SECRET_KEY --no-ssl" {{- end }} bucket_stat="$(s3cmd ls $params | grep ${bucket} || true)" if [[ -n "${bucket_stat}" ]]; then s3cmd del --recursive --force $bucket $params check_result $? "Error during s3cmd execution" "Bucket is deleted" fi s3cmd mb $bucket $params if [ $? -eq 0 ]; then echo "Bucket $bucket created" for i in $(seq $total_objects); do s3cmd put "${objects_list[$i]}" $bucket $params check_result $? "Error during s3cmd execution" "File ${objects_list[$i]##*/} uploaded to bucket" done s3cmd ls $bucket $params check_result $? "Error during s3cmd execution" "Got list of objects" for i in $(seq $total_objects); do s3cmd get "${bucket}/${objects_list[$i]##*/}" -> "${objects_list[$i]}_s3_object${i}" $params check_result $? "Error during s3cmd execution" "File ${objects_list[$i]##*/} downloaded from bucket" echo "Comparing files: ${objects_list[$i]} and ${objects_list[$i]}_s3_object${i}" cmp "${objects_list[$i]}" "${objects_list[$i]}_s3_object${i}" check_result $? "The files are not equal" "The files are equal" s3cmd del "${bucket}/${objects_list[$i]##*/}" $params check_result $? "Error during s3cmd execution" "File from bucket is deleted" done s3cmd del --recursive --force $bucket $params check_result $? "Error during s3cmd execution" "Bucket is deleted" else echo "Error during s3cmd execution" exit 1 fi } function check_result () { red='\033[0;31m' green='\033[0;32m' bw='\033[0m' if [ "$1" -ne 0 ]; then echo -e "${red}$2${bw}" exit 1 else echo -e "${green}$3${bw}" fi } function prepare_objects () { echo "Preparing ${total_objects} files for test" for i in $(seq $total_objects); do objects_list[$i]="$(mktemp -p "$tmpdir")" echo "${objects_list[$i]}" dd if=/dev/urandom of="${objects_list[$i]}" bs=1M count=8 done } prepare_objects if [ "$RGW_TEST_TYPE" == RGW_KS ]; then echo "--> Keystone is enabled. Calling function to test keystone based auth " rgw_keystone_bucket_validation fi if [ "$RGW_TEST_TYPE" == RGW_S3 ]; then echo "--> S3 is enabled. Calling function to test S3 based auth " rgw_s3_bucket_validation fi ================================================ FILE: ceph-rgw/templates/bin/_init-dirs.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C : "${HOSTNAME:=$(uname -n)}" : "${RGW_NAME:=${HOSTNAME}}" : "${RGW_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-rgw/${CLUSTER}.keyring}" for keyring in ${RGW_BOOTSTRAP_KEYRING}; do mkdir -p "$(dirname "$keyring")" done # Let's create the ceph directories for DIRECTORY in radosgw tmp; do mkdir -p "/var/lib/ceph/${DIRECTORY}" done # Create socket directory mkdir -p /run/ceph # Creating rados directories mkdir -p "/var/lib/ceph/radosgw/${RGW_NAME}" # Clean the folder rm -f "$(dirname "${RGW_BOOTSTRAP_KEYRING}"/*)" # Adjust the owner of all those directories chown -R ceph. /run/ceph/ /var/lib/ceph/* ================================================ FILE: ceph-rgw/templates/bin/_rgw-restart.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} export LC_ALL=C TIMEOUT="{{ .Values.conf.rgw_restart.timeout | default 600 }}s" kubectl rollout restart deployment ceph-rgw kubectl rollout status --timeout=${TIMEOUT} deployment ceph-rgw if [ "$?" -ne 0 ]; then echo "Ceph rgw deployment was not able to restart in ${TIMEOUT}" fi ================================================ FILE: ceph-rgw/templates/bin/rgw/_init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" : "${EP:=ceph-mon-discovery}" {{- if empty .Values.endpoints.ceph_mon.namespace -}} MON_NS=ceph {{ else }} MON_NS={{ .Values.endpoints.ceph_mon.namespace }} {{- end }} {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} if [[ ! -e ${CEPH_CONF}.template ]]; then echo "ERROR- ${CEPH_CONF}.template must exist." exit 1 fi ENDPOINT=$(mon_host_from_k8s_ep "${MON_NS}" "${EP}") if [[ -z "${ENDPOINT}" ]]; then /bin/sh -c -e "cat ${CEPH_CONF}.template | tee ${CEPH_CONF}" || true else /bin/sh -c -e "cat ${CEPH_CONF}.template | sed 's#mon_host.*#mon_host = ${ENDPOINT}#g' | tee ${CEPH_CONF}" || true fi cat >> ${CEPH_CONF} < /tmp/ceph-rbd-pool.json kubectl -n ${CEPH_NS} delete job ceph-rbd-pool jq 'del(.spec.selector) | del(.spec.template.metadata.creationTimestamp) | del(.spec.template.metadata.labels) | del(.metadata.creationTimestamp) | del(.metadata.uid) | del(.status)' /tmp/ceph-rbd-pool.json | \ kubectl create -f - while [[ -z "$(kubectl -n ${CEPH_NS} get pods | grep ceph-rbd-pool | grep Completed)" ]] do sleep 5 done fi ================================================ FILE: ceph-rgw/templates/bin/rgw/_start.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export LC_ALL=C : "${CEPH_GET_ADMIN_KEY:=0}" : "${RGW_NAME:=$(uname -n)}" : "${RGW_ZONEGROUP:=}" : "${RGW_ZONE:=}" : "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" : "${RGW_KEYRING:=/var/lib/ceph/radosgw/${RGW_NAME}/keyring}" : "${RGW_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-rgw/${CLUSTER}.keyring}" if [[ ! -e "/etc/ceph/${CLUSTER}.conf" ]]; then echo "ERROR- /etc/ceph/${CLUSTER}.conf must exist; get it from your existing mon" exit 1 fi if [ "${CEPH_GET_ADMIN_KEY}" -eq 1 ]; then if [[ ! -e "${ADMIN_KEYRING}" ]]; then echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" exit 1 fi fi # Check to see if our RGW has been initialized if [ ! -e "${RGW_KEYRING}" ]; then if [ ! -e "${RGW_BOOTSTRAP_KEYRING}" ]; then echo "ERROR- ${RGW_BOOTSTRAP_KEYRING} must exist. You can extract it from your current monitor by running 'ceph auth get client.bootstrap-rgw -o ${RGW_BOOTSTRAP_KEYRING}'" exit 1 fi timeout 10 ceph --cluster "${CLUSTER}" --name "client.bootstrap-rgw" --keyring "${RGW_BOOTSTRAP_KEYRING}" health || exit 1 # Generate the RGW key ceph --cluster "${CLUSTER}" --name "client.bootstrap-rgw" --keyring "${RGW_BOOTSTRAP_KEYRING}" auth get-or-create "client.rgw.${RGW_NAME}" osd 'allow rwx' mon 'allow rw' -o "${RGW_KEYRING}" chown ceph. "${RGW_KEYRING}" chmod 0600 "${RGW_KEYRING}" fi /usr/bin/radosgw \ --cluster "${CLUSTER}" \ --setuser "ceph" \ --setgroup "ceph" \ -d \ -n "client.rgw.${RGW_NAME}" \ -k "${RGW_KEYRING}" \ --rgw-socket-path="" \ --rgw-zonegroup="${RGW_ZONEGROUP}" \ --rgw-zone="${RGW_ZONE}" ================================================ FILE: ceph-rgw/templates/bin/utils/_checkDNS.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} : "${CEPH_CONF:="/etc/ceph/${CLUSTER}.conf"}" ENDPOINT="{$1}" function check_mon_dns () { GREP_CMD=$(grep -rl 'ceph-mon' ${CEPH_CONF}) if [[ "${ENDPOINT}" == "{up}" ]]; then echo "If DNS is working, we are good here" elif [[ "${ENDPOINT}" != "" ]]; then if [[ ${GREP_CMD} != "" ]]; then # No DNS, write CEPH MONs IPs into ${CEPH_CONF} sh -c -e "cat ${CEPH_CONF}.template | sed 's/mon_host.*/mon_host = ${ENDPOINT}/g' | tee ${CEPH_CONF}" > /dev/null 2>&1 else echo "endpoints are already cached in ${CEPH_CONF}" exit fi fi } check_mon_dns exit ================================================ FILE: ceph-rgw/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{ $object_store_name := "object_store" }} {{- if .Values.conf.rgw_s3.enabled }} {{ $object_store_name = "ceph_object_store" }} {{- end }} {{- if .Values.manifests.certificates }} {{ dict "envAll" . "service" $object_store_name "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end }} ================================================ FILE: ceph-rgw/templates/configmap-bin-ks.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.configmap_bin_ks .Values.conf.rgw_ks.enabled }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: ceph-rgw-bin-ks data: ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- end }} ================================================ FILE: ceph-rgw/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.configmap_bin .Values.deployment.ceph }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: ceph-rgw-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} rgw-restart.sh: | {{ tuple "bin/_rgw-restart.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} init-dirs.sh: | {{ tuple "bin/_init-dirs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rgw-start.sh: | {{ tuple "bin/rgw/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rgw-init.sh: | {{ tuple "bin/rgw/_init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rerun-pool-job.sh: | {{ tuple "bin/rgw/_rerun-pool-job.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} storage-init.sh: | {{ tuple "bin/_ceph-rgw-storage-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ceph-admin-keyring.sh: | {{ tuple "bin/_ceph-admin-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rgw-s3-admin.sh: | {{- include "helm-toolkit.scripts.create_s3_user" . | indent 4 }} create-rgw-placement-targets.sh: | {{ tuple "bin/_create-rgw-placement-targets.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} helm-tests.sh: | {{ tuple "bin/_helm-tests.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} utils-checkDNS.sh: | {{ tuple "bin/utils/_checkDNS.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: ceph-rgw/templates/configmap-ceph-rgw-templates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.configmap_ceph_templates .Values.manifests.job_ceph_rgw_storage_init }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.Release.Name "ceph-templates" | quote }} data: bootstrap.keyring.rgw: | {{ .Values.conf.templates.keyring.bootstrap.rgw | indent 4 }} {{- end }} ================================================ FILE: ceph-rgw/templates/configmap-etc-client.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ceph.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if or (.Values.deployment.ceph) (.Values.deployment.client_secrets) }} {{- if empty .Values.conf.ceph.global.mon_host -}} {{- $monHost := tuple "ceph_mon" "internal" "mon_msgr2" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} {{- $_ := $monHost | set .Values.conf.ceph.global "mon_host" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.cluster_network -}} {{- $_ := .Values.network.cluster | set .Values.conf.ceph.osd "cluster_network" -}} {{- end -}} {{- if empty .Values.conf.ceph.osd.public_network -}} {{- $_ := .Values.network.public | set .Values.conf.ceph.osd "public_network" -}} {{- end -}} {{- if empty .Values.conf.rgw_ks.config.rgw_swift_url -}} {{- $_ := tuple "object_store" "public" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | trimSuffix .Values.endpoints.object_store.path.default | set .Values.conf.rgw_ks.config "rgw_swift_url" -}} {{- end -}} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapName }} data: ceph.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.ceph | indent 4 }} {{- end }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "ceph-rgw-etc" . | include "ceph.configmap.etc" }} {{- end }} ================================================ FILE: ceph-rgw/templates/deployment-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "readinessProbeTemplate" }} {{- $object_store_name := "object_store" }} {{- if .Values.conf.rgw_s3.enabled }} {{ $object_store_name = "ceph_object_store" }} {{- end }} httpGet: path: / port: {{ tuple $object_store_name "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} scheme: {{ tuple $object_store_name "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} {{- end }} {{- define "livenessProbeTemplate" }} {{- $object_store_name := "object_store" }} {{- if .Values.conf.rgw_s3.enabled }} {{ $object_store_name = "ceph_object_store" }} {{- end }} httpGet: path: / port: {{ tuple $object_store_name "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} scheme: {{ tuple $object_store_name "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} {{- end }} {{- if and .Values.manifests.deployment_rgw ( and .Values.deployment.ceph .Values.conf.features.rgw ) }} {{- $envAll := . }} {{ $object_store_name := "object_store" }} {{ $tls_secret := .Values.secrets.tls.object_store.api.internal | quote }} {{- if .Values.conf.rgw_s3.enabled }} {{ $object_store_name = "ceph_object_store" }} {{ $tls_secret = .Values.secrets.tls.ceph_object_store.api.internal | quote }} {{- end }} {{- $serviceAccountName := "ceph-rgw" }} {{- $checkDnsServiceAccountName := "ceph-checkdns" }} {{- $_ := set $envAll.Values "__depParams" ( list ) }} {{- if .Values.conf.rgw_ks.enabled -}} {{- $__updateDepParams := append $envAll.Values.__depParams "keystone" -}} {{- $_ := set $envAll.Values "__depParams" $__updateDepParams -}} {{- end -}} {{- if .Values.conf.rgw_s3.enabled -}} {{- $__updateDepParams := append $envAll.Values.__depParams "s3" -}} {{- $_ := set $envAll.Values "__depParams" $__updateDepParams -}} {{- end -}} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.__depParams "dependencyKey" "rgw" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ printf "%s-%s" $serviceAccountName $envAll.Release.Namespace }} namespace: {{ .Values.endpoints.ceph_mon.namespace }} rules: - apiGroups: - "" resources: - endpoints verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ printf "%s-%s" $serviceAccountName $envAll.Release.Namespace }} namespace: {{ .Values.endpoints.ceph_mon.namespace }} roleRef: kind: Role name: {{ printf "%s-%s" $serviceAccountName $envAll.Release.Namespace }} apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- # This role bindig refers to the ClusterRole for # check-dns deployment. # See: openstack-helm/ceph-client/deployment-checkdns.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ printf "%s-from-%s-to-%s" $checkDnsServiceAccountName $envAll.Values.endpoints.ceph_mon.namespace $envAll.Release.Namespace }} namespace: {{ $envAll.Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: clusterrole-checkdns subjects: - kind: ServiceAccount name: {{ $checkDnsServiceAccountName }} namespace: {{ .Values.endpoints.ceph_mon.namespace }} --- kind: Deployment apiVersion: apps/v1 metadata: name: ceph-rgw annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ceph" "rgw" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.rgw }} selector: matchLabels: {{ tuple $envAll "ceph" "rgw" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "ceph" "rgw" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-client-hash: {{ tuple "configmap-etc-client.yaml" . | include "helm-toolkit.utils.hash" }} secret-keystone-rgw-hash: {{ tuple "secret-keystone-rgw.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-rgw" "containerNames" (list "init" "ceph-rgw" "ceph-init-dirs" "ceph-rgw-init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "rgw" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ceph" "rgw" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ tuple $envAll "rgw" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} nodeSelector: {{ .Values.labels.rgw.node_selector_key }}: {{ .Values.labels.rgw.node_selector_value }} initContainers: {{ tuple $envAll "pod_dependency" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-init-dirs {{ tuple $envAll "ceph_rgw" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw" "container" "init_dirs" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/init-dirs.sh env: - name: CLUSTER value: "ceph" volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/init-dirs.sh subPath: init-dirs.sh readOnly: true - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false - name: ceph-rgw-init {{ tuple $envAll "ceph_rgw" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.rgw | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw" "container" "rgw_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name {{ if .Values.conf.rgw_ks.enabled }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.user_rgw "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: KEYSTONE_URL value: {{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | trimSuffix .Values.endpoints.identity.path.default | quote }} {{ end }} - name: RGW_FRONTEND_PORT value: "{{ tuple $object_store_name "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" command: - /tmp/rgw-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/rgw-init.sh subPath: rgw-init.sh readOnly: true - name: ceph-rgw-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true {{- if .Values.conf.rgw_ks.enabled }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.object_store.api.keystone | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} containers: - name: ceph-rgw {{ tuple $envAll "ceph_rgw" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.rgw | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw" "container" "rgw" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CLUSTER value: "ceph" - name: RGW_FRONTEND_PORT value: "{{ tuple $object_store_name "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" command: - /tmp/rgw-start.sh ports: - containerPort: {{ tuple $object_store_name "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" . "component" "api" "container" "ceph-rgw" "type" "liveness" "probeTemplate" (include "livenessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} {{ dict "envAll" . "component" "api" "container" "ceph-rgw" "type" "readiness" "probeTemplate" (include "readinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/rgw-start.sh subPath: rgw-start.sh readOnly: true - name: ceph-rgw-bin mountPath: /tmp/utils-checkDNS.sh subPath: utils-checkDNS.sh readOnly: true - name: ceph-rgw-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true - name: ceph-bootstrap-rgw-keyring mountPath: /var/lib/ceph/bootstrap-rgw/ceph.keyring subPath: ceph.keyring readOnly: false - name: pod-var-lib-ceph mountPath: /var/lib/ceph readOnly: false {{- dict "enabled" .Values.manifests.certificates "name" $tls_secret "path" "/etc/tls" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: pod-etc-ceph emptyDir: {} - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 - name: ceph-rgw-etc configMap: name: ceph-rgw-etc defaultMode: 0444 - name: pod-var-lib-ceph emptyDir: {} - name: ceph-bootstrap-rgw-keyring secret: secretName: {{ .Values.secrets.keyrings.rgw }} {{- dict "enabled" .Values.manifests.certificates "name" $tls_secret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- if .Values.conf.rgw_ks.enabled }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.object_store.api.keystone | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} {{- end }} ================================================ FILE: ceph-rgw/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ceph-rgw/templates/ingress-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_rgw ( and .Values.deployment.ceph (and .Values.network.api.ingress.public .Values.conf.features.rgw) ) }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "object_store" "backendPort" "ceph-rgw" -}} {{- if .Values.manifests.certificates }} {{- if .Values.conf.rgw_ks.enabled }} {{- $ingressOpts = dict "envAll" . "backendServiceType" "object_store" "backendPort" "ceph-rgw" "certIssuer" .Values.endpoints.object_store.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{- if .Values.conf.rgw_s3.enabled }} {{- $ingressOpts = dict "envAll" . "backendServiceType" "ceph_object_store" "backendPort" "ceph-rgw" "certIssuer" .Values.endpoints.ceph_object_store.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-rgw-bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - create - update - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-rgw-bootstrap labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-rgw-bootstrap" "containerNames" (list "ceph-keyring-placement" "init" "ceph-rgw-bootstrap") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "bootstrap" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-keyring-placement {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ceph-admin-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true - name: ceph-rgw-admin-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true containers: - name: ceph-rgw-bootstrap {{ tuple $envAll "ceph_bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "bootstrap" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true - name: ceph-rgw-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-rgw-admin-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 - name: ceph-rgw-etc configMap: name: {{ .Values.ceph_client.configmap }} defaultMode: 0444 - name: ceph-rgw-admin-keyring secret: secretName: {{ .Values.secrets.keyrings.admin | quote }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ceph-rgw" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_ks_endpoints .Values.conf.rgw_ks.enabled }} {{- $ksServiceJob := dict "envAll" . "configMapBin" "ceph-rgw-bin-ks" "serviceName" "ceph" "serviceTypes" ( tuple "object-store" ) -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.object_store.api.internal -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_ks_service .Values.conf.rgw_ks.enabled }} {{- $ksServiceJob := dict "envAll" . "configMapBin" "ceph-rgw-bin-ks" "serviceName" "ceph" "serviceTypes" ( tuple "object-store" ) -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.object_store.api.internal -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_ks_user .Values.conf.rgw_ks.enabled }} {{- $ksUserJob := dict "envAll" . "configMapBin" "ceph-rgw-bin-ks" "serviceName" "ceph" "serviceUser" "swift" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.object_store.api.internal -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-rgw-placement-targets.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_rgw_placement_targets .Values.conf.features.rgw }} {{- $envAll := . }} {{- $serviceAccountName := "rgw-placement-targets" }} {{ tuple $envAll "rgw_placement_targets" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - create - update - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-rgw-placement-targets labels: {{ tuple $envAll "ceph" "rgw-placement-targets" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "rgw-placement-targets" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-rgw-placement-targets" "containerNames" (list "ceph-keyring-placement" "init" "create-rgw-placement-targets") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "rgw_placement_targets" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "rgw_placement_targets" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-keyring-placement {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_placement_targets" "container" "keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ceph-admin-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true containers: - name: create-rgw-placement-targets image: {{ .Values.images.tags.rgw_placement_targets }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.rgw_placement_targets | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_placement_targets" "container" "create_rgw_placement_targets" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/create-rgw-placement-targets.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/create-rgw-placement-targets.sh subPath: create-rgw-placement-targets.sh readOnly: true - name: ceph-rgw-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 - name: ceph-rgw-etc configMap: name: ceph-rgw-etc defaultMode: 0444 - name: ceph-keyring secret: secretName: {{ .Values.secrets.keyrings.admin | quote }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-rgw-pool.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This job is required for Reef and later because Ceph now disallows the # creation of internal pools (pools names beginning with a ".") and the # ceph-rbd-pool job therefore can't configure them if they don't yet exist. # This job simply deletes and re-creates the ceph-rbd-pool job after deploying # ceph-rgw so it can apply the correct configuration to the .rgw.root pool. {{- if and .Values.manifests.job_rgw_pool .Values.deployment.ceph }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-rgw-pool" }} {{ tuple $envAll "rgw_pool" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }}-{{ $envAll.Release.Namespace }} rules: - apiGroups: - '' resources: - pods - jobs verbs: - create - get - delete - list - apiGroups: - 'batch' resources: - jobs verbs: - create - get - delete - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }}-{{ $envAll.Release.Namespace }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }}-{{ $envAll.Release.Namespace }} apiGroup: rbac.authorization.k8s.io --- apiVersion: batch/v1 kind: Job metadata: name: ceph-rgw-pool labels: {{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: name: ceph-rgw-pool labels: {{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "ceph-rgw-pool" "containerNames" (list "ceph-rgw-pool" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "rgw_pool" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: {{ $envAll.Values.jobs.rgw_pool.restartPolicy | quote }} affinity: {{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ $envAll.Values.labels.job.node_selector_key }}: {{ $envAll.Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "rgw_pool" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-rgw-pool {{ tuple $envAll "ceph_rgw_pool" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.rgw_pool | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_pool" "container" "rgw_pool" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/rerun-pool-job.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ceph-rgw-bin mountPath: /tmp/rerun-pool-job.sh subPath: rerun-pool-job.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 - name: pod-run emptyDir: medium: "Memory" {{- end }} ================================================ FILE: ceph-rgw/templates/job-rgw-restart.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_rgw_restart }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "rgw-restart" }} {{ tuple $envAll "rgw_restart" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - 'apps' resources: - deployments verbs: - get - list - update - patch - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- apiVersion: batch/v1 kind: Job metadata: name: ceph-rgw-restart labels: {{ tuple $envAll "ceph" "rgw-restart" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "rgw-restart" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-rgw-restart" "containerNames" (list "init" "ceph-rgw-restart") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "rgw_restart" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "rgw_restart" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ceph-rgw-restart {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.rgw_restart | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_restart" "container" "ceph-rgw-restart" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/rgw-restart.sh volumeMounts: - name: ceph-rgw-bin mountPath: /tmp/rgw-restart.sh subPath: rgw-restart.sh readOnly: true volumes: - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 {{- end }} ================================================ FILE: ceph-rgw/templates/job-rgw-storage-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_ceph_rgw_storage_init .Values.deployment.ceph }} {{- $envAll := . }} {{- $serviceAccountName := "ceph-rgw-storage-init" }} {{ tuple $envAll "rgw_storage_init" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - create - update - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-rgw-storage-init labels: {{ tuple $envAll "ceph" "rgw-storage-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "rgw-storage-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-rgw-storage-init" "containerNames" (list "ceph-keyring-placement" "init" "ceph-rgw-storage-init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "rgw_storage_init" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "rgw_storage_init" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-keyring-placement {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_storage_init" "container" "keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ceph-admin-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true containers: - name: ceph-rgw-storage-init {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.rgw_storage_init | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_storage_init" "container" "rgw_storage_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: STORAGE_BACKEND value: "ceph-rgw" command: - /tmp/storage-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/storage-init.sh subPath: storage-init.sh readOnly: true - name: ceph-templates mountPath: /tmp/ceph-templates readOnly: true - name: ceph-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 - name: ceph-etc configMap: name: {{ .Values.ceph_client.configmap }} defaultMode: 0444 - name: ceph-templates configMap: name: {{ printf "%s-%s" $envAll.Release.Name "ceph-templates" | quote }} defaultMode: 0444 - name: ceph-keyring secret: secretName: {{ .Values.secrets.keyrings.admin | quote }} {{- end }} ================================================ FILE: ceph-rgw/templates/job-s3-admin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_s3_admin ( and .Values.conf.features.rgw .Values.conf.rgw_s3.enabled ) }} {{- $envAll := . }} {{- $serviceAccountName := "rgw-s3-admin" }} {{ tuple $envAll "rgw_s3_admin" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $s3AdminSecret := .Values.secrets.rgw_s3.admin }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - create - update - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: ceph-rgw-s3-admin labels: {{ tuple $envAll "ceph" "rgw-s3-admin" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "ceph" "rgw-s3-admin" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "ceph-rgw-s3-admin" "containerNames" (list "ceph-keyring-placement" "init" "create-s3-admin") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "rgw_s3_admin" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "rgw_s3_admin" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-keyring-placement {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_s3_admin" "container" "keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ceph-admin-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true containers: - name: create-s3-admin image: {{ .Values.images.tags.rgw_s3_admin }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.rgw_s3_admin | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "rgw_s3_admin" "container" "create_s3_admin" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: S3_USERNAME valueFrom: secretKeyRef: name: {{ $s3AdminSecret }} key: S3_ADMIN_USERNAME - name: S3_ACCESS_KEY valueFrom: secretKeyRef: name: {{ $s3AdminSecret }} key: S3_ADMIN_ACCESS_KEY - name: S3_SECRET_KEY valueFrom: secretKeyRef: name: {{ $s3AdminSecret }} key: S3_ADMIN_SECRET_KEY command: - /tmp/rgw-s3-admin.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/rgw-s3-admin.sh subPath: rgw-s3-admin.sh readOnly: true - name: ceph-rgw-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 - name: ceph-rgw-etc configMap: name: ceph-rgw-etc defaultMode: 0444 - name: ceph-keyring secret: secretName: {{ .Values.secrets.keyrings.admin | quote }} {{- end }} ================================================ FILE: ceph-rgw/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "key" "rgw" "labels" (dict "application" "ceph" "component" "rgw") -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: ceph-rgw/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.helm_tests .Values.deployment.ceph }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" $envAll.Release.Name "test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ $serviceAccountName }} labels: {{ tuple $envAll "ceph" "rgw-test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ dict "envAll" $envAll "podName" "ceph-rgw-test" "containerNames" (list "ceph-rgw-ks-validation" "ceph-rgw-s3-validation") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "rgw_test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} restartPolicy: Never serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} containers: {{ if .Values.conf.rgw_ks.enabled }} - name: ceph-rgw-ks-validation {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "rgw_test" "container" "ceph_rgw_ks_validation" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.user_rgw "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} - name: OS_AUTH_TYPE valueFrom: secretKeyRef: name: {{ $.Values.secrets.identity.user_rgw }} key: OS_AUTH_TYPE - name: OS_TENANT_NAME valueFrom: secretKeyRef: name: {{ $.Values.secrets.identity.user_rgw }} key: OS_TENANT_NAME {{- end }} - name: "RGW_TEST_TYPE" value: "RGW_KS" command: - /tmp/helm-tests.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/helm-tests.sh subPath: helm-tests.sh readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true - name: ceph-rgw-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.object_store.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{- end }} {{ if .Values.conf.rgw_s3.enabled }} - name: ceph-rgw-s3-validation {{ tuple $envAll "ceph_rgw" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "rgw_test" "container" "ceph_rgw_s3_validation" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: {{- with $env := dict "s3AdminSecret" $envAll.Values.secrets.rgw_s3.admin }} {{- include "helm-toolkit.snippets.rgw_s3_admin_env_vars" $env | indent 8 }} {{- end }} - name: RGW_HOST value: {{ tuple "ceph_object_store" "internal" "api" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} - name: "RGW_TEST_TYPE" value: "RGW_S3" command: - /tmp/helm-tests.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-ceph mountPath: /etc/ceph - name: ceph-rgw-bin mountPath: /tmp/helm-tests.sh subPath: helm-tests.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.ceph_object_store.api.internal "path" "/etc/tls" | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-ceph emptyDir: {} - name: ceph-rgw-bin configMap: name: ceph-rgw-bin defaultMode: 0555 - name: ceph-keyring secret: secretName: {{ .Values.secrets.keyrings.admin | quote }} - name: ceph-rgw-etc configMap: name: ceph-rgw-etc defaultMode: 0444 {{- if .Values.conf.rgw_ks.enabled }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.object_store.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} {{- if .Values.conf.rgw_s3.enabled }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.ceph_object_store.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} {{- end }} ================================================ FILE: ceph-rgw/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_ingress_tls ( and .Values.deployment.ceph .Values.conf.features.rgw ) }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "object_store" ) }} {{- end }} ================================================ FILE: ceph-rgw/templates/secret-keystone-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_keystone_rgw .Values.deployment.ceph }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "swift" }} {{- $secretName := index $envAll.Values.secrets.identity "user_rgw" }} {{- $auth := index $envAll.Values.endpoints.identity.auth $userClass }} {{ $osAuthType := $auth.os_auth_type }} {{ $osTenantName := $auth.os_tenant_name }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 }} OS_AUTH_TYPE: {{ $osAuthType | b64enc }} OS_TENANT_NAME: {{ $osTenantName | b64enc }} {{ end }} {{- end }} ================================================ FILE: ceph-rgw/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_keystone .Values.conf.rgw_ks.enabled }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "swift" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: ceph-rgw/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: ceph-rgw/templates/secret-s3-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_s3_rgw }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.rgw_s3.admin }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: S3_ADMIN_USERNAME: {{ .Values.endpoints.ceph_object_store.auth.admin.username | b64enc }} S3_ADMIN_ACCESS_KEY: {{ .Values.endpoints.ceph_object_store.auth.admin.access_key | b64enc }} S3_ADMIN_SECRET_KEY: {{ .Values.endpoints.ceph_object_store.auth.admin.secret_key | b64enc }} {{- end }} ================================================ FILE: ceph-rgw/templates/service-ingress-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{ $object_store_name := "object_store" }} {{- if .Values.conf.rgw_s3.enabled }} {{ $object_store_name = "ceph_object_store" }} {{- end }} {{- if and .Values.manifests.service_ingress_rgw ( and .Values.deployment.ceph (and .Values.network.api.ingress.public .Values.conf.features.rgw ) ) }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" $object_store_name -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: ceph-rgw/templates/service-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_rgw ( and .Values.deployment.ceph .Values.conf.features.rgw ) }} {{- $envAll := . }} {{ $object_store_name := "object_store" }} {{- if .Values.conf.rgw_s3.enabled }} {{ $object_store_name = "ceph_object_store" }} {{- end }} --- apiVersion: v1 kind: Service metadata: name: ceph-rgw spec: ports: - name: ceph-rgw port: {{ tuple $object_store_name "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: {{ tuple $object_store_name "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "ceph" "rgw" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: ceph-rgw/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for ceph-client. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- deployment: ceph: false release_group: null images: pull_policy: IfNotPresent tags: ceph_bootstrap: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_config_helper: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' ceph_rgw: 'quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407' ceph_rgw_pool: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' image_repo_sync: 'quay.io/airshipit/docker:27.5.0' rgw_s3_admin: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' rgw_placement_targets: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' ks_endpoints: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble' ks_service: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble' ks_user: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble' local_registry: active: false exclude: - dep_check - image_repo_sync labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled rgw: node_selector_key: ceph-rgw node_selector_value: enabled pod: security_context: rgw: pod: runAsUser: 64045 container: init_dirs: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rgw_init: runAsUser: 0 readOnlyRootFilesystem: true rgw: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rgw_storage_init: pod: runAsUser: 64045 container: keyring_placement: runAsUser: 0 readOnlyRootFilesystem: true rgw_storage_init: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rgw_restart: pod: runAsUser: 65534 container: ceph-rgw-restart: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rgw_s3_admin: pod: runAsUser: 64045 container: keyring_placement: runAsUser: 0 readOnlyRootFilesystem: true create_s3_admin: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rgw_placement_targets: pod: runAsUser: 64045 container: keyring_placement: runAsUser: 0 readOnlyRootFilesystem: true create_rgw_placement_targets: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rgw_test: pod: runAsUser: 64045 rgw_test: ceph_rgw_ks_validation: allowPrivilegeEscalation: false readOnlyRootFilesystem: true ceph_rgw_s3_validation: allowPrivilegeEscalation: false readOnlyRootFilesystem: true bootstrap: pod: runAsUser: 65534 container: keyring_placement: allowPrivilegeEscalation: false readOnlyRootFilesystem: true bootstrap: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rgw_pool: pod: runAsUser: 65534 container: rgw_pool: allowPrivilegeEscalation: false readOnlyRootFilesystem: true dns_policy: "ClusterFirstWithHostNet" replicas: rgw: 2 lifecycle: upgrades: deployments: pod_replacement_strategy: RollingUpdate revision_history: 3 rolling_update: max_surge: 50% max_unavailable: 50% affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 resources: enabled: false rgw: requests: memory: "128Mi" cpu: "250m" limits: memory: "512Mi" cpu: "1000m" jobs: bootstrap: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" ceph-rgw-storage-init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks-endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rgw_s3_admin: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rgw_placement_targets: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rgw_restart: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" rgw_pool: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tolerations: rgw: tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 60 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 60 - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule probes: api: ceph-rgw: readiness: enabled: true params: timeoutSeconds: 5 liveness: enabled: true params: initialDelaySeconds: 120 timeoutSeconds: 5 network_policy: rgw: ingress: - {} egress: - {} ceph_client: configmap: ceph-etc secrets: keyrings: mon: ceph-mon-keyring mds: ceph-bootstrap-mds-keyring osd: ceph-bootstrap-osd-keyring rgw: os-ceph-bootstrap-rgw-keyring mgr: ceph-bootstrap-mgr-keyring admin: pvc-ceph-client-key identity: admin: ceph-keystone-admin swift: ceph-keystone-user user_rgw: ceph-keystone-user-rgw oci_image_registry: ceph-rgw: ceph-rgw-oci-image-registry-key rgw_s3: admin: radosgw-s3-admin-creds tls: object_store: api: public: ceph-tls-public internal: ceph-rgw-ks-tls-api keystone: keystone-tls-api ceph_object_store: api: public: ceph-rgw-s3-tls-public internal: ceph-rgw-s3-tls-api network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0" haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30004 public: 192.168.0.0/16 cluster: 192.168.0.0/16 conf: templates: keyring: admin: | [client.admin] key = {{ key }} auid = 0 caps mds = "allow" caps mon = "allow *" caps osd = "allow *" caps mgr = "allow *" bootstrap: rgw: | [client.bootstrap-rgw] key = {{ key }} caps mgr = "allow profile bootstrap-rgw" features: rgw: true pool: # NOTE(portdirect): this drives a simple approximation of # https://ceph.com/pgcalc/, the `target.osd` key should be set to match the # expected number of osds in a cluster, and the `target.pg_per_osd` should be # set to match the desired number of placement groups on each OSD. crush: # NOTE(portdirect): to use RBD devices with Ubuntu 16.04's 4.4.x series # kernel this should be set to `hammer` tunables: null target: # NOTE(portdirect): arbitrarily we set the default number of expected OSD's to 5 # to match the number of nodes in the OSH gate. osd: 5 pg_per_osd: 100 default: # NOTE(portdirect): this should be 'same_host' for a single node # cluster to be in a healthy state crush_rule: replicated_rule # NOTE(portdirect): this section describes the pools that will be managed by # the ceph pool management job, as it tunes the pgs and crush rule, based on # the above. spec: # RBD pool - name: rbd application: rbd replication: 3 percent_total_data: 40 # CephFS pools - name: cephfs_metadata application: cephfs replication: 3 percent_total_data: 5 - name: cephfs_data application: cephfs replication: 3 percent_total_data: 10 # RadosGW pools - name: .rgw.root application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.control application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.data.root application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.gc application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.log application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.intent-log application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.meta application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.usage application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.keys application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.email application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.swift application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.users.uid application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.buckets.extra application: rgw replication: 3 percent_total_data: 0.1 - name: default.rgw.buckets.index application: rgw replication: 3 percent_total_data: 3 - name: default.rgw.buckets.data application: rgw replication: 3 percent_total_data: 34.8 rgw_placement_targets: - name: default-placement data_pool: default.rgw.buckets.data # Set 'delete' to true to delete an existing placement target. A # non-existent placement target will be created and deleted in a single # step. # delete: true rgw: config: # NOTE (portdirect): See http://tracker.ceph.com/issues/21226 rgw_keystone_token_cache_size: 0 # NOTE (JCL): See http://tracker.ceph.com/issues/7073 rgw_gc_max_objs: 997 # NOTE (JCL): See http://tracker.ceph.com/issues/24937 # NOTE (JCL): See https://tracker.ceph.com/issues/24551 rgw_dynamic_resharding: false rgw_override_bucket_index_max_shards: 8 rgw_restart: timeout: 600 rgw_ks: enabled: false config: rgw_keystone_api_version: 3 rgw_keystone_accepted_roles: "admin, member" rgw_keystone_implicit_tenants: true rgw_keystone_make_new_tenants: true rgw_s3_auth_use_keystone: true rgw_s3_auth_order: "local, external, sts" rgw_swift_account_in_url: true rgw_swift_url: null rgw_s3: enabled: false admin_caps: "users=*;buckets=*;zone=*" config: # NOTE (supamatt): Unfortunately we do not conform to S3 compliant names with some of our charts rgw_relaxed_s3_bucket_names: true ceph: global: # auth cephx: true cephx_require_signatures: false cephx_cluster_require_signatures: true cephx_service_require_signatures: false objecter_inflight_op_bytes: "1073741824" debug_ms: "0/0" log_file: /dev/stdout mon_cluster_log_file: /dev/stdout # CNTT certification required fields rgw_max_attr_name_len: 64 rgw_max_attrs_num_in_req: 32 rgw_max_attr_size: 1024 rgw_swift_versioning_enabled: true osd: osd_mkfs_type: xfs osd_mkfs_options_xfs: -f -i size=2048 osd_max_object_name_len: 256 ms_bind_port_min: 6800 ms_bind_port_max: 7100 dependencies: dynamic: common: local_image_registry: jobs: - ceph-rgw-image-repo-sync services: - endpoint: node service: local_image_registry targeted: keystone: rgw: services: - endpoint: internal service: identity s3: rgw: {} static: rgw: jobs: - ceph-rgw-storage-init rgw_restart: services: - endpoint: internal service: ceph_object_store image_repo_sync: services: - endpoint: internal service: local_image_registry ks_endpoints: jobs: - ceph-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rgw_s3_admin: services: - endpoint: internal service: ceph_object_store rgw_placement_targets: services: - endpoint: internal service: ceph_object_store rgw_pool: jobs: - ceph-rgw-storage-init tests: services: - endpoint: internal service: ceph_object_store bootstrap: enabled: false script: | ceph -s function ensure_pool () { ceph osd pool stats $1 || ceph osd pool create $1 $2 if [[ $(ceph mon versions | awk '/version/{print $3}' | cut -d. -f1) -ge 12 ]]; then ceph osd pool application enable $1 $3 fi } #ensure_pool volumes 8 cinder endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ceph-rgw: username: ceph-rgw password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone namespace: null auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default os_auth_type: password os_tenant_name: admin swift: role: admin region_name: RegionOne username: swift password: password project_name: service user_domain_name: service project_domain_name: service os_auth_type: password os_tenant_name: admin hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 object_store: name: swift namespace: null hosts: default: ceph-rgw public: radosgw host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: /swift/v1/KEY_$(tenant_id)s scheme: default: http port: api: default: 8088 public: 80 ceph_object_store: name: radosgw namespace: null auth: admin: # NOTE(srwilkers): These defaults should be used for testing only, and # should be changed before deploying to production username: s3_admin access_key: "admin_access_key" secret_key: "admin_secret_key" hosts: default: ceph-rgw public: radosgw host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 8088 public: 80 ceph_mon: namespace: null hosts: default: ceph-mon discovery: ceph-mon-discovery host_fqdn_override: default: null port: mon: default: 6789 mon_msgr2: default: 3300 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns_tcp: default: 53 dns: default: 53 protocol: UDP jobs: rgw_pool: restartPolicy: OnFailure manifests: certificates: false configmap_ceph_templates: true configmap_bin: true configmap_bin_ks: true configmap_test_bin: true configmap_etc: true deployment_rgw: true ingress_rgw: true job_bootstrap: false job_rgw_restart: false job_ceph_rgw_storage_init: true job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_s3_admin: true job_rgw_placement_targets: false job_rgw_pool: true secret_s3_rgw: true secret_keystone_rgw: true secret_ingress_tls: true secret_keystone: true secret_registry: true service_ingress_rgw: true service_rgw: true helm_tests: true network_policy: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: cert-rotation/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: "1.0" description: Rotate the certificates generated by cert-manager home: https://cert-manager.io/ name: cert-rotation version: 2025.2.0 dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: cert-rotation/templates/bin/_rotate-certs.sh.tpl ================================================ #!/bin/bash set -x {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} COMMAND="${@:-rotate_job}" namespace={{ .Release.Namespace }} minDaysToExpiry={{ .Values.jobs.rotate.max_days_to_expiry }} rotateBefore=$(($(date +%s) + (86400*$minDaysToExpiry))) function rotate_and_get_certs_list(){ # Rotate the certificates if the expiry date of certificates is within the # max_days_to_expiry days # List of secret and certificates rotated local -n secRotated=$1 deleteAllSecrets=$2 certRotated=() for certificate in $(kubectl get certificates -n ${namespace} --no-headers | awk '{ print $1 }') do certInfo=($(kubectl get certificate -n ${namespace} ${certificate} -o json | jq -r '.spec["secretName"],.status["notAfter"]')) secretName=${certInfo[0]} notAfter=$(date -d"${certInfo[1]}" '+%s') deleteSecret=false if ${deleteAllSecrets} || [ ${rotateBefore} -gt ${notAfter} ] then # Rotate the certificates/secrets and add to list. echo "Deleting secret: ${secretName}" kubectl delete secret -n ${namespace} $secretName secRotated+=(${secretName}) certRotated+=(${certificate}) fi done # Ensure certificates are re-issued if [ ! -z ${certRotated} ] then for cert in ${certRotated[@]} do counter=0 retried=false while [ "$(kubectl get certificate -n ${namespace} ${cert} -o json | jq -r '.status.conditions[].status')" != "True" ] do # Wait for secret to become ready. Wait for 300 seconds maximum. Sleep for 10 seconds if [ ${counter} -ge 30 ] then # Seems certificate is not in ready state yet, may be there is an issue be renewing the certificate. # Try one more time before failing it. The name of the secret would be different at this time (when in # process of issuing) priSeckeyName=$(kubectl get certificate -n ${namespace} ${cert} -o json | jq -r '.status["nextPrivateKeySecretName"]') if [ ${retried} = false ] && [ ! -z ${priSeckeyName} ] then echo "Deleting interim failed secret ${priSeckeyName} in namespace ${namespace}" kubectl delete secret -n ${namespace} ${priSeckeyName} retried=true counter=0 else # Tried 2 times to renew the certificate, something is not right. Log error and # continue to check the status of next certificate. Once the status of all the # certificates has been checked, the pods need to be restarted so that the successfully # renewed certificates can be deployed. echo "ERROR: Rotated certificate ${cert} in ${namespace} is not ready." break fi fi echo "Rotated certificate ${cert} in ${namespace} is not ready yet ... waiting" counter=$((counter+1)) sleep 10 done done fi } function get_cert_list_rotated_by_cert_manager_rotate(){ local -n secRotated=$1 # Get the time when the last cron job was run successfully lastCronTime=$(kubectl get jobs -n ${namespace} --no-headers -l application=cert-manager,component=cert-rotate -o json | jq -r '.items[] | select(.status.succeeded != null) | .status.completionTime' | sort -r | head -n 1) if [ ! -z ${lastCronTime} ] then lastCronTimeSec=$(date -d"${lastCronTime}" '+%s') for certificate in $(kubectl get certificates -n ${namespace} --no-headers | awk '{ print $1 }') do certInfo=($(kubectl get certificate -n ${namespace} ${certificate} -o json | jq -r '.spec["secretName"],.status["notBefore"]')) secretName=${certInfo[0]} notBefore=$(date -d"${certInfo[1]}" '+%s') # if the certificate was created after last cronjob run means it was # rotated by the cert-manager, add to the list. if [[ ${notBefore} -gt ${lastCronTimeSec} ]] then secRotated+=(${secretName}) fi done fi } function restart_the_pods(){ local -n secRotated=$1 if [ -z ${secRotated} ] then echo "All certificates are still valid in ${namespace} namespace. No pod needs restart" exit 0 fi # Restart the pods using kubernetes rollout restart. This will restarts the applications # with zero downtime. for kind in statefulset deployment daemonset do # Need to find which kinds mounts the secret that has been rotated. To do this # for a kind (statefulset, deployment, or daemonset) # - get the name of the kind (which will index 1 = idx=0 of the output) # - get the names of the secrets mounted on this kind (which will be index 2 = idx+1) # - find if tls.crt was mounted to the container: get the subpaths of volumeMount in # the container and grep for tls.crt. (This will be index 3 = idx+2) # - or, find if tls.crt was mounted to the initContainer (This will be index 4 = idx+3) resource=($(kubectl get ${kind} -n ${namespace} -o custom-columns='NAME:.metadata.name,SECRETS:.spec.template.spec.volumes[*].secret.secretName,TLS-CONTAINER:.spec.template.spec.containers[*].volumeMounts[*].subPath,TLS-INIT:.spec.template.spec.initContainers[*].volumeMounts[*].subPath' --no-headers | grep tls.crt || true)) idx=0 while [[ $idx -lt ${#resource[@]} ]] do # Name of the kind resourceName=${resource[$idx]} # List of secrets mounted to this kind resourceSecrets=${resource[$idx+1]} # For each secret mounted to this kind, check if it was rotated (present in # the list secRotated) and if it was, then trigger rolling restart for this kind. for secret in ${resourceSecrets//,/ } do if [[ "${secRotated[@]}" =~ "${secret}" ]] then echo "Restarting ${kind} ${resourceName} in ${namespace} namespace." kubectl rollout restart -n ${namespace} ${kind} ${resourceName} break fi done # Since we have 4 custom columns in the output, every 5th index will be start of new tuple. # Jump to the next tuple. idx=$((idx+4)) done done } function rotate_cron(){ # Rotate cronjob invoked this script. # 1. If the expiry date of certificates is within the max_days_to_expiry days # the rotate the certificates and restart the pods # 2. Else if the certificates were rotated by cert-manager, then restart # the pods. secretsRotated=() deleteAllSecrets=false rotate_and_get_certs_list secretsRotated $deleteAllSecrets if [ ! -z ${secretsRotated} ] then # Certs rotated, restart pods restart_the_pods secretsRotated else # Check if the certificates were rotated by the cert-manager and get the list of # rotated certificates so that the corresponding pods can be restarted get_cert_list_rotated_by_cert_manager_rotate secretsRotated if [ ! -z ${secretsRotated} ] then restart_the_pods secretsRotated else echo "All certificates are still valid in ${namespace} namespace" fi fi } function rotate_job(){ # Rotate job invoked this script. # 1. Rotate all certificates by deleting the secrets and restart the pods secretsRotated=() deleteAllSecrets=true rotate_and_get_certs_list secretsRotated $deleteAllSecrets if [ ! -z ${secretsRotated} ] then # Certs rotated, restart pods restart_the_pods secretsRotated else echo "All certificates are still valid in ${namespace} namespace" fi } $COMMAND exit 0 ================================================ FILE: cert-rotation/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: cert-rotate-bin data: rotate-certs.sh: | {{ tuple "bin/_rotate-certs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{ end }} ================================================ FILE: cert-rotation/templates/cron-job-cert-rotate.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_cert_rotate}} {{- $envAll := . }} {{- $serviceAccountName := "cert-rotate-cron" }} {{ tuple $envAll "cert_rotate" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - cert-manager.io resources: - certificates verbs: - get - list - update - patch - apiGroups: - "*" resources: - pods - secrets - jobs - statefulsets - daemonsets - deployments verbs: - get - list - update - patch - delete --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: CronJob metadata: name: cert-rotate annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "cert-manager" "cert-rotate-cron" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: suspend: {{ .Values.jobs.rotate.suspend }} schedule: {{ .Values.jobs.rotate.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.rotate.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.rotate.history.failed }} {{- if .Values.jobs.rotate.starting_deadline }} startingDeadlineSeconds: {{ .Values.jobs.rotate.starting_deadline }} {{- end }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "cert-manager" "cert-rotate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "cert-manager" "cert-rotate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "cert_rotate" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "cert_rotate" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: cert-rotate {{ tuple $envAll "cert_rotation" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.cert_rotate | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "cert_rotate" "container" "cert_rotate" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - /tmp/rotate-certs.sh - rotate_cron volumeMounts: - name: pod-tmp mountPath: /tmp - name: cert-rotate-bin mountPath: /tmp/rotate-certs.sh subPath: rotate-certs.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: cert-rotate-bin configMap: name: cert-rotate-bin defaultMode: 0555 {{- end }} ================================================ FILE: cert-rotation/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: cert-rotation/templates/job-cert-rotate.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_cert_rotate}} {{- $envAll := . }} {{- $serviceAccountName := "cert-rotate-job" }} {{ tuple $envAll "cert_rotate" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - cert-manager.io resources: - certificates verbs: - get - list - update - patch - apiGroups: - "*" resources: - pods - secrets - jobs - statefulsets - daemonsets - deployments verbs: - get - list - update - patch - delete --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: cert-rotate-job labels: {{ tuple $envAll "cert-manager" "cert-rotate-job" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "cert-manager" "cert-rotate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "cert_rotate" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "cert_rotate" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: cert-rotate {{ tuple $envAll "cert_rotation" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.cert_rotate | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "cert_rotate" "container" "cert_rotate" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/rotate-certs.sh - rotate_job volumeMounts: - name: pod-tmp mountPath: /tmp - name: cert-rotate-bin mountPath: /tmp/rotate-certs.sh subPath: rotate-certs.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: cert-rotate-bin configMap: name: cert-rotate-bin defaultMode: 0555 {{- end }} ================================================ FILE: cert-rotation/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: cert-rotation/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: cert_rotation: 'quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy' dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' local_registry: active: false labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled jobs: rotate: # Run at 1:00AM on 1st of each month cron: "0 1 1 * *" starting_deadline: 600 history: success: 3 failed: 1 # Number of day before expiry should certs be rotated. max_days_to_expiry: 45 suspend: false pod: security_context: cert_rotate: pod: runAsUser: 42424 container: cert_rotate: readOnlyRootFilesystem: true allowPrivilegeEscalation: false resources: enabled: false jobs: cert_rotate: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: static: cert_rotate: null secrets: oci_image_registry: cert-rotation: cert-rotation-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false cert-rotation: username: cert-rotation password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null manifests: configmap_bin: true cron_job_cert_rotate: false job_cert_rotate: false secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: cinder/.helmignore ================================================ values_overrides ================================================ FILE: cinder/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Cinder name: cinder version: 2025.2.0 home: https://docs.openstack.org/cinder/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Cinder/OpenStack_Project_Cinder_vertical.png sources: - https://opendev.org/openstack/cinder - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: cinder/templates/bin/_backup-storage-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x if [[ $STORAGE_BACKEND =~ 'cinder.backup.drivers.ceph' ]]; then SECRET=$(mktemp --suffix .yaml) KEYRING=$(mktemp --suffix .keyring) function cleanup { rm -f ${SECRET} ${KEYRING} } trap cleanup EXIT fi set -ex if [[ $STORAGE_BACKEND =~ 'cinder.backup.drivers.swift' ]] || \ [[ $STORAGE_BACKEND =~ 'cinder.backup.drivers.posix' ]]; then echo "INFO: no action required to use $STORAGE_BACKEND" elif [[ $STORAGE_BACKEND =~ 'cinder.backup.drivers.ceph' ]]; then ceph -s function ensure_pool () { ceph osd pool stats $1 || ceph osd pool create $1 $2 if [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -ge 12 ]]; then ceph osd pool application enable $1 $3 fi size_protection=$(ceph osd pool get $1 nosizechange | cut -f2 -d: | tr -d '[:space:]') ceph osd pool set $1 nosizechange 0 ceph osd pool set $1 size ${RBD_POOL_REPLICATION} --yes-i-really-mean-it ceph osd pool set $1 nosizechange ${size_protection} ceph osd pool set $1 crush_rule "${RBD_POOL_CRUSH_RULE}" } ensure_pool ${RBD_POOL_NAME} ${RBD_POOL_CHUNK_SIZE} ${RBD_POOL_APP_NAME} if USERINFO=$(ceph auth get client.${RBD_POOL_USER}); then echo "Cephx user client.${RBD_POOL_USER} already exists" echo "Update its cephx caps" ceph auth caps client.${RBD_POOL_USER} \ mon "profile rbd" \ osd "profile rbd pool=${RBD_POOL_NAME}" ceph auth get client.${RBD_POOL_USER} -o ${KEYRING} else ceph auth get-or-create client.${RBD_POOL_USER} \ mon "profile rbd" \ osd "profile rbd pool=${RBD_POOL_NAME}" \ -o ${KEYRING} fi ENCODED_KEYRING=$(sed -n 's/^[[:blank:]]*key[[:blank:]]\+=[[:blank:]]\(.*\)/\1/p' ${KEYRING} | base64 -w0) cat > ${SECRET} < /etc/ceph/ceph.client.admin.keyring [client.admin] {{- if .Values.conf.ceph.admin_keyring }} key = {{ .Values.conf.ceph.admin_keyring }} {{- else }} key = $(cat /tmp/client-keyring) {{- end }} EOF exit 0 ================================================ FILE: cinder/templates/bin/_ceph-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat < /etc/ceph/ceph.client.${RBD_USER}.keyring [client.${RBD_USER}] key = $(cat /tmp/client-keyring) EOF {{- if and .Values.ceph_client.enable_external_ceph_backend .Values.ceph_client.external_ceph.rbd_user }} cat < /etc/ceph/ceph.client.${EXTERNAL_RBD_USER}.keyring [client.${EXTERNAL_RBD_USER}] key = $(cat /tmp/external-ceph-client-keyring) EOF {{- end }} exit 0 ================================================ FILE: cinder/templates/bin/_cinder-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars mkdir -p ${APACHE_RUN_DIR} fi {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} if [ -f /var/run/apache2/apache2.pid ]; then # Remove the stale pid for debian/ubuntu images rm -f /var/run/apache2/apache2.pid fi # Starts Apache2 exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} {{- else }} exec uwsgi --ini /etc/cinder/cinder-api-uwsgi.ini {{- end }} } function stop () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars mkdir -p ${APACHE_RUN_DIR} fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop {{- else }} kill -TERM 1 {{- end }} } $COMMAND ================================================ FILE: cinder/templates/bin/_cinder-backup.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec cinder-backup \ --config-file /etc/cinder/cinder.conf \ --config-dir /etc/cinder/cinder.conf.d ================================================ FILE: cinder/templates/bin/_cinder-scheduler.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec cinder-scheduler \ --config-file /etc/cinder/cinder.conf \ --config-dir /etc/cinder/cinder.conf.d ================================================ FILE: cinder/templates/bin/_cinder-volume.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec cinder-volume \ --config-file /etc/cinder/cinder.conf \ --config-file /etc/cinder/conf/backends.conf \ --config-file /tmp/pod-shared/internal_tenant.conf \ --config-dir /etc/cinder/cinder.conf.d ================================================ FILE: cinder/templates/bin/_clean-secrets.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec kubectl delete secret \ --namespace ${NAMESPACE} \ --ignore-not-found=true \ ${RBD_POOL_SECRET} ================================================ FILE: cinder/templates/bin/_create-internal-tenant-id.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex USER_PROJECT_ID=$(openstack project create --or-show --enable -f value -c id \ --domain="${PROJECT_DOMAIN_ID}" \ "${INTERNAL_PROJECT_NAME}"); USER_ID=$(openstack user create --or-show --enable -f value -c id \ --domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ "${INTERNAL_USER_NAME}"); ================================================ FILE: cinder/templates/bin/_db-purge.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec cinder-manage \ --config-file /etc/cinder/cinder.conf \ --config-dir /etc/cinder/cinder.conf.d \ db purge {{ .Values.conf.db_purge.before }} ================================================ FILE: cinder/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec cinder-manage db sync ================================================ FILE: cinder/templates/bin/_external-ceph-rbd-admin-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- if .Values.backup.external_ceph_rbd.admin_keyring }} cat < /etc/ceph/ceph.client.admin.keyring [client.admin] key = {{ .Values.backup.external_ceph_rbd.admin_keyring }} EOF {{- else }} echo "ERROR: You must define the ceph admin keyring in values.yaml to use external_ceph_rbd." exit 1 {{- end }} exit 0 ================================================ FILE: cinder/templates/bin/_iscsiadm.tpl ================================================ #!/bin/bash {{/* Copyright 2020 The Openstack-Helm Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} chroot /mnt/host-rootfs /usr/bin/env -i PATH="/sbin:/bin:/usr/bin" \ iscsiadm "${@:1}" ================================================ FILE: cinder/templates/bin/_multipath.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} chroot /mnt/host-rootfs /usr/bin/env -i PATH="/sbin:/bin:/usr/bin" \ multipath "${@:1}" ================================================ FILE: cinder/templates/bin/_multipathd.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} chroot /mnt/host-rootfs /usr/bin/env -i PATH="/sbin:/bin:/usr/bin" \ multipathd "${@:1}" ================================================ FILE: cinder/templates/bin/_retrieve-internal-tenant-id.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex USER_PROJECT_ID=$(openstack project show -f value -c id \ "${INTERNAL_PROJECT_NAME}"); USER_ID=$(openstack user show -f value -c id \ "${INTERNAL_USER_NAME}"); tee /tmp/pod-shared/internal_tenant.conf < ${SECRET} <: # - # - # <...> # : # - # <...> # Volume QoS if any. By default, None QoS is created. # Below values with a number at the end need to be replaced # with real names. # volume_qos: # qos_name_1: # consumer: front-end # properties: # key_1: value_1 # key_2: value_2 # associates: # - volume_type_1 # - volume_type_2 network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30877 ceph_client: # enable this when there is a need to create second ceph backed pointing # to external ceph cluster enable_external_ceph_backend: false # change this in case of first ceph backend name pointing to internal ceph cluster # is diffrent internal_ceph_backend: rbd1 configmap: ceph-etc user_secret_name: pvc-ceph-client-key external_ceph: # Only when enable_external_ceph_backend is true and rbd_user is NOT null # secret for external ceph keyring will be created. rbd_user: null rbd_user_keyring: null configmap: null conf: global: null osd: null conf: paste: composite:osapi_volume: use: call:cinder.api:root_app_factory /: apiversions /healthcheck: healthcheck /v3: openstack_volume_api_v3 composite:openstack_volume_api_v3: use: call:cinder.api.middleware.auth:pipeline_factory noauth: cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv3 keystone: cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken audit keystonecontext apiv3 keystone_nolimit: cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken audit keystonecontext apiv3 filter:request_id: paste.filter_factory: oslo_middleware.request_id:RequestId.factory filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: cinder filter:faultwrap: paste.filter_factory: cinder.api.middleware.fault:FaultWrapper.factory filter:osprofiler: paste.filter_factory: osprofiler.web:WsgiMiddleware.factory filter:noauth: paste.filter_factory: cinder.api.middleware.auth:NoAuthMiddleware.factory filter:sizelimit: paste.filter_factory: oslo_middleware.sizelimit:RequestBodySizeLimiter.factory app:apiv3: paste.app_factory: cinder.api.v3.router:APIRouter.factory app:healthcheck: paste.app_factory: oslo_middleware:Healthcheck.app_factory backends: disable_by_file disable_by_file_path: /etc/cinder/healthcheck_disable pipeline:apiversions: pipeline: cors http_proxy_to_wsgi faultwrap osvolumeversionapp app:osvolumeversionapp: paste.app_factory: cinder.api.versions:Versions.factory filter:keystonecontext: paste.filter_factory: cinder.api.middleware.auth:CinderKeystoneContext.factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:audit: paste.filter_factory: keystonemiddleware.audit:filter_factory audit_map_file: /etc/cinder/api_audit_map.conf policy: {} api_audit_map: DEFAULT: target_endpoint_type: None custom_actions: associate: update/associate disassociate: update/disassociate_all disassociate_all: update/disassociate_all associations: read/list/associations path_keywords: defaults: None detail: None limits: None os-quota-specs: project qos-specs: qos-spec snapshots: snapshot types: type volumes: volume service_endpoints: volumev3: service/storage/block cinder_sudoers: | # This sudoers file supports rootwrap for both Kolla and LOCI Images. Defaults !requiretty Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin:/var/lib/kolla/venv/bin" cinder ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/cinder-rootwrap /etc/cinder/rootwrap.conf *, /var/lib/openstack/bin/cinder-rootwrap /etc/cinder/rootwrap.conf * rootwrap: | # Configuration for cinder-rootwrap # This file should be owned by (and only-writeable by) the root user [DEFAULT] # List of directories to load filter definitions from (separated by ','). # These directories MUST all be only writeable by root ! filters_path=/etc/cinder/rootwrap.d # List of directories to search executables in, in case filters do not # explicitely specify a full path (separated by ',') # If not specified, defaults to system PATH environment variable. # These directories MUST all be only writeable by root ! exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin,/var/lib/openstack/bin,/var/lib/kolla/venv/bin # Enable logging to syslog # Default value is False use_syslog=False # Which syslog facility to use. # Valid values include auth, authpriv, syslog, local0, local1... # Default value is 'syslog' syslog_log_facility=syslog # Which messages to log. # INFO means log all usage # ERROR means only log unsuccessful attempts syslog_log_level=ERROR rootwrap_filters: volume: pods: - volume content: | # cinder-rootwrap command filters for volume nodes # This file should be owned by (and only-writeable by) the root user [Filters] # cinder/volume/iscsi.py: iscsi_helper '--op' ... ietadm: CommandFilter, ietadm, root tgtadm: CommandFilter, tgtadm, root iscsictl: CommandFilter, iscsictl, root tgt-admin: CommandFilter, tgt-admin, root cinder-rtstool: CommandFilter, cinder-rtstool, root scstadmin: CommandFilter, scstadmin, root # LVM related show commands pvs: EnvFilter, env, root, LC_ALL=C, pvs vgs: EnvFilter, env, root, LC_ALL=C, vgs lvs: EnvFilter, env, root, LC_ALL=C, lvs lvdisplay: EnvFilter, env, root, LC_ALL=C, lvdisplay # -LVM related show commands with suppress fd warnings pvs_fdwarn: EnvFilter, env, root, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, pvs vgs_fdwarn: EnvFilter, env, root, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, vgs lvs_fdwarn: EnvFilter, env, root, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, lvs lvdisplay_fdwarn: EnvFilter, env, root, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, lvdisplay # -LVM related show commands conf var pvs_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, pvs vgs_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, vgs lvs_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, lvs lvdisplay_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, lvdisplay # -LVM conf var with suppress fd_warnings pvs_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, pvs vgs_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, vgs lvs_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, lvs lvdisplay_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, lvdisplay # os-brick library commands # os_brick.privileged.run_as_root oslo.privsep context # This line ties the superuser privs with the config files, context name, # and (implicitly) the actual python code invoked. privsep-rootwrap: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, os_brick.privileged.default, --privsep_sock_path, /tmp/.* # The following and any cinder/brick/* entries should all be obsoleted # by privsep, and may be removed once the os-brick version requirement # is updated appropriately. scsi_id: CommandFilter, /lib/udev/scsi_id, root drbdadm: CommandFilter, drbdadm, root # cinder/brick/local_dev/lvm.py: 'vgcreate', vg_name, pv_list vgcreate: CommandFilter, vgcreate, root # cinder/brick/local_dev/lvm.py: 'lvcreate', '-L', sizestr, '-n', volume_name,.. # cinder/brick/local_dev/lvm.py: 'lvcreate', '-L', ... lvcreate: EnvFilter, env, root, LC_ALL=C, lvcreate lvcreate_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, lvcreate lvcreate_fdwarn: EnvFilter, env, root, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, lvcreate lvcreate_lvmconf_fdwarn: EnvFilter, env, root, LVM_SYSTEM_DIR=, LVM_SUPPRESS_FD_WARNINGS=, LC_ALL=C, lvcreate # cinder/volume/driver.py: 'dd', 'if=%s' % srcstr, 'of=%s' % deststr,... dd: CommandFilter, dd, root # cinder/volume/driver.py: 'lvremove', '-f', %s/%s % ... lvremove: CommandFilter, lvremove, root # cinder/volume/driver.py: 'lvrename', '%(vg)s', '%(orig)s' '(new)s'... lvrename: CommandFilter, lvrename, root # cinder/brick/local_dev/lvm.py: 'lvextend', '-L' '%(new_size)s', '%(lv_name)s' ... # cinder/brick/local_dev/lvm.py: 'lvextend', '-L' '%(new_size)s', '%(thin_pool)s' ... lvextend: EnvFilter, env, root, LC_ALL=C, lvextend lvextend_lvmconf: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, lvextend lvextend_fdwarn: EnvFilter, env, root, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, lvextend lvextend_lvmconf_fdwarn: EnvFilter, env, root, LVM_SYSTEM_DIR=, LC_ALL=C, LVM_SUPPRESS_FD_WARNINGS=, lvextend # cinder/brick/local_dev/lvm.py: 'lvchange -a y -K ' lvchange: CommandFilter, lvchange, root # cinder/brick/local_dev/lvm.py: 'lvconvert', '--merge', snapshot_name lvconvert: CommandFilter, lvconvert, root # cinder/volume/driver.py: 'iscsiadm', '-m', 'discovery', '-t',... # cinder/volume/driver.py: 'iscsiadm', '-m', 'node', '-T', ... iscsiadm: CommandFilter, iscsiadm, root # cinder/volume/utils.py: utils.temporary_chown(path, 0) chown: CommandFilter, chown, root # cinder/volume/utils.py: copy_volume(..., ionice='...') ionice_1: ChainingRegExpFilter, ionice, root, ionice, -c[0-3], -n[0-7] ionice_2: ChainingRegExpFilter, ionice, root, ionice, -c[0-3] # cinder/volume/utils.py: setup_blkio_cgroup() cgcreate: CommandFilter, cgcreate, root cgset: CommandFilter, cgset, root cgexec: ChainingRegExpFilter, cgexec, root, cgexec, -g, blkio:\S+ # cinder/volume/driver.py dmsetup: CommandFilter, dmsetup, root ln: CommandFilter, ln, root # cinder/image/image_utils.py qemu-img: EnvFilter, env, root, LC_ALL=C, qemu-img qemu-img_convert: CommandFilter, qemu-img, root udevadm: CommandFilter, udevadm, root # cinder/volume/driver.py: utils.read_file_as_root() cat: CommandFilter, cat, root # cinder/volume/nfs.py stat: CommandFilter, stat, root mount: CommandFilter, mount, root df: CommandFilter, df, root du: CommandFilter, du, root truncate: CommandFilter, truncate, root chmod: CommandFilter, chmod, root rm: CommandFilter, rm, root # cinder/volume/drivers/remotefs.py mkdir: CommandFilter, mkdir, root # cinder/volume/drivers/netapp/nfs.py: netapp_nfs_find: RegExpFilter, find, root, find, ^[/]*([^/\0]+(/+)?)*$, -maxdepth, \d+, -name, img-cache.*, -amin, \+\d+ # cinder/volume/drivers/glusterfs.py chgrp: CommandFilter, chgrp, root umount: CommandFilter, umount, root fallocate: CommandFilter, fallocate, root # cinder/volumes/drivers/hds/hds.py: hus-cmd: CommandFilter, hus-cmd, root hus-cmd_local: CommandFilter, /usr/local/bin/hus-cmd, root # cinder/volumes/drivers/hds/hnas_backend.py ssc: CommandFilter, ssc, root # cinder/brick/initiator/connector.py: ls: CommandFilter, ls, root tee: CommandFilter, tee, root multipath: CommandFilter, multipath, root multipathd: CommandFilter, multipathd, root systool: CommandFilter, systool, root # cinder/volume/drivers/block_device.py blockdev: CommandFilter, blockdev, root # cinder/volume/drivers/ibm/gpfs.py # cinder/volume/drivers/tintri.py mv: CommandFilter, mv, root # cinder/volume/drivers/ibm/gpfs.py cp: CommandFilter, cp, root mmgetstate: CommandFilter, /usr/lpp/mmfs/bin/mmgetstate, root mmclone: CommandFilter, /usr/lpp/mmfs/bin/mmclone, root mmlsattr: CommandFilter, /usr/lpp/mmfs/bin/mmlsattr, root mmchattr: CommandFilter, /usr/lpp/mmfs/bin/mmchattr, root mmlsconfig: CommandFilter, /usr/lpp/mmfs/bin/mmlsconfig, root mmlsfs: CommandFilter, /usr/lpp/mmfs/bin/mmlsfs, root mmlspool: CommandFilter, /usr/lpp/mmfs/bin/mmlspool, root mkfs: CommandFilter, mkfs, root mmcrfileset: CommandFilter, /usr/lpp/mmfs/bin/mmcrfileset, root mmlinkfileset: CommandFilter, /usr/lpp/mmfs/bin/mmlinkfileset, root mmunlinkfileset: CommandFilter, /usr/lpp/mmfs/bin/mmunlinkfileset, root mmdelfileset: CommandFilter, /usr/lpp/mmfs/bin/mmdelfileset, root mmcrsnapshot: CommandFilter, /usr/lpp/mmfs/bin/mmcrsnapshot, root mmdelsnapshot: CommandFilter, /usr/lpp/mmfs/bin/mmdelsnapshot, root # cinder/volume/drivers/ibm/gpfs.py # cinder/volume/drivers/ibm/ibmnas.py find_maxdepth_inum: RegExpFilter, find, root, find, ^[/]*([^/\0]+(/+)?)*$, -maxdepth, \d+, -ignore_readdir_race, -inum, \d+, -print0, -quit # cinder/brick/initiator/connector.py: aoe-revalidate: CommandFilter, aoe-revalidate, root aoe-discover: CommandFilter, aoe-discover, root aoe-flush: CommandFilter, aoe-flush, root # cinder/brick/initiator/linuxscsi.py: sg_scan: CommandFilter, sg_scan, root #cinder/backup/services/tsm.py dsmc:CommandFilter,/usr/bin/dsmc,root # cinder/volume/drivers/hitachi/hbsd_horcm.py raidqry: CommandFilter, raidqry, root raidcom: CommandFilter, raidcom, root pairsplit: CommandFilter, pairsplit, root paircreate: CommandFilter, paircreate, root pairdisplay: CommandFilter, pairdisplay, root pairevtwait: CommandFilter, pairevtwait, root horcmstart.sh: CommandFilter, horcmstart.sh, root horcmshutdown.sh: CommandFilter, horcmshutdown.sh, root horcmgr: EnvFilter, env, root, HORCMINST=, /etc/horcmgr # cinder/volume/drivers/hitachi/hbsd_snm2.py auman: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auman auluref: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auluref auhgdef: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auhgdef aufibre1: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/aufibre1 auhgwwn: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auhgwwn auhgmap: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auhgmap autargetmap: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/autargetmap aureplicationvvol: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/aureplicationvvol auluadd: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auluadd auludel: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auludel auluchgsize: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auluchgsize auchapuser: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auchapuser autargetdef: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/autargetdef autargetopt: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/autargetopt autargetini: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/autargetini auiscsi: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/auiscsi audppool: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/audppool aureplicationlocal: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/aureplicationlocal aureplicationmon: EnvFilter, env, root, LANG=, STONAVM_HOME=, LD_LIBRARY_PATH=, STONAVM_RSP_PASS=, STONAVM_ACT=, /usr/stonavm/aureplicationmon # cinder/volume/drivers/hgst.py vgc-cluster: CommandFilter, vgc-cluster, root # cinder/volume/drivers/vzstorage.py pstorage-mount: CommandFilter, pstorage-mount, root pstorage: CommandFilter, pstorage, root ploop: CommandFilter, ploop, root # initiator/connector.py: drv_cfg: CommandFilter, /opt/emc/scaleio/sdc/bin/drv_cfg, root, /opt/emc/scaleio/sdc/bin/drv_cfg, --query_guid ceph: override: append: monitors: [] admin_keyring: null pools: backup: replication: 3 crush_rule: replicated_rule chunk_size: 8 app_name: cinder-backup cinder.volumes: replication: 3 crush_rule: replicated_rule chunk_size: 8 app_name: cinder-volume cinder: DEFAULT: state_path: /var/lib/cinder volume_usage_audit_period: hour resource_query_filters_file: /etc/cinder/resource_filters.json log_config_append: /etc/cinder/logging.conf use_syslog: false use_stderr: true volume_name_template: "%s" osapi_volume_workers: 1 glance_api_version: 2 os_region_name: RegionOne host: cinder-volume-worker # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. osapi_volume_listen_port: null enabled_backends: "rbd1" default_volume_type: "rbd1" # NOTE(portdirect): "cinder.backup.drivers.ceph" and # "cinder.backup.drivers.posix" also supported # NOTE(rchurch): As of Stein, drivers by class name are required # - cinder.backup.drivers.swift.SwiftBackupDriver # - cinder.backup.drivers.ceph.CephBackupDriver # - cinder.backup.drivers.posix.PosixBackupDriver backup_driver: "cinder.backup.drivers.swift.SwiftBackupDriver" # Backup: Ceph RBD options backup_ceph_conf: "/etc/ceph/ceph.conf" backup_ceph_user: cinderbackup backup_ceph_pool: cinder.backups # Backup: Posix options backup_posix_path: /var/lib/cinder/backup auth_strategy: keystone # Internal tenant id internal_project_name: internal_cinder internal_user_name: internal_cinder database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: service_token_roles: service service_token_roles_required: true auth_version: v3 auth_type: password memcache_security_strategy: ENCRYPT service_type: volumev3 nova: auth_type: password auth_version: v3 interface: internal oslo_policy: policy_file: /etc/cinder/policy.yaml oslo_concurrency: lock_path: /var/lock oslo_messaging_notifications: driver: messagingv2 oslo_middleware: enable_proxy_headers_parsing: true oslo_messaging_rabbit: rabbit_ha_queues: true coordination: backend_url: file:///var/lib/cinder/coordination service_user: auth_type: password send_service_user_token: true logging: loggers: keys: - root - cinder handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_cinder: level: INFO handlers: - stdout qualname: cinder logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" rabbitmq: # NOTE(rk760n): adding rmq policy to mirror messages from notification queues and set expiration time for the ones policies: - vhost: "cinder" name: "ha_ttl_cinder" definition: # mirror messges to other nodes in rmq cluster ha-mode: "all" ha-sync-mode: "automatic" # 70s message-ttl: 70000 priority: 0 apply-to: all pattern: '^(?!(amq\.|reply_)).*' backends: # Those options will be written to backends.conf as-is. rbd1: volume_driver: cinder.volume.drivers.rbd.RBDDriver volume_backend_name: rbd1 rbd_pool: cinder.volumes rbd_ceph_conf: "/etc/ceph/ceph.conf" rbd_flatten_volume_from_snapshot: false report_discard_supported: true rbd_max_clone_depth: 5 rbd_store_chunk_size: 4 rados_connect_timeout: -1 rbd_user: cinder rbd_secret_uuid: 457eb676-33da-42ec-9a8c-9293d545c337 image_volume_cache_enabled: true image_volume_cache_max_size_gb: 200 image_volume_cache_max_count: 50 rally_tests: run_tempest: false clean_up: | VOLUMES=$(openstack volume list -f value | grep -e "^s_rally_" | awk '{ print $1 }') if [ -n "$VOLUMES" ]; then echo $VOLUMES | xargs openstack volume delete fi tests: CinderVolumes.create_and_delete_volume: - args: size: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 - args: size: max: 5 min: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 resource_filters: volume: - name - status - metadata - bootable - migration_status - availability_zone - group_id backup: - name - status - volume_id snapshot: - name - status - volume_id - metadata - availability_zone group: [] group_snapshot: - status - group_id attachment: - volume_id - status - instance_id - attach_status message: - resource_uuid - resource_type - event_id - request_id - message_level pool: - name - volume_type volume_type: [] enable_iscsi: false enable_conversion_tmpfs: false conversion_tmpfs_size: "10Gi" cinder_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "cinder-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/cinder-wsgi stats: 0.0.0.0:1717 stats-http: true db_purge: before: 30 backup: external_ceph_rbd: enabled: false admin_keyring: null configmap: null conf: global: null osd: null posix: volume: class_name: general size: 10Gi dependencies: dynamic: common: local_image_registry: jobs: - cinder-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - cinder-db-sync - cinder-ks-user - cinder-ks-endpoints - cinder-rabbit-init - cinder-storage-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity backup: jobs: - cinder-db-sync - cinder-ks-user - cinder-ks-endpoints - cinder-rabbit-init - cinder-storage-init - cinder-backup-storage-init services: - endpoint: internal service: identity - endpoint: internal service: volumev3 backup_storage_init: jobs: null bootstrap: services: - endpoint: internal service: identity - endpoint: internal service: volumev3 pod: - requireSameNode: false labels: application: cinder component: volume clean: jobs: null db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - cinder-db-init services: - endpoint: internal service: oslo_db db_purge: jobs: - cinder-db-sync - cinder-db-init - cinder-ks-user - cinder-ks-endpoints - cinder-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity ks_endpoints: jobs: - cinder-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - service: oslo_messaging endpoint: internal scheduler: jobs: - cinder-db-sync - cinder-ks-user - cinder-ks-endpoints - cinder-rabbit-init - cinder-storage-init services: - endpoint: internal service: identity - endpoint: internal service: volumev3 storage_init: jobs: null tests: services: - endpoint: internal service: identity - endpoint: internal service: volumev3 volume: jobs: - cinder-db-sync - cinder-ks-user - cinder-ks-endpoints - cinder-rabbit-init - cinder-storage-init services: - endpoint: internal service: identity - endpoint: internal service: volumev3 volume_usage_audit: jobs: - cinder-db-sync - cinder-ks-user - cinder-ks-endpoints - cinder-rabbit-init - cinder-storage-init services: - endpoint: internal service: identity - endpoint: internal service: volumev3 image_repo_sync: services: - endpoint: internal service: local_image_registry create_internal_tenant: services: - endpoint: internal service: identity # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: cinder-keystone-admin cinder: cinder-keystone-user glance: cinder-keystone-glance nova: cinder-keystone-nova swift: cinder-keystone-swift service: cinder-keystone-service test: cinder-keystone-test oslo_db: admin: cinder-db-admin cinder: cinder-db-user rbd: backup: cinder-backup-rbd-keyring volume: cinder-volume-rbd-keyring volume_external: cinder-volume-external-rbd-keyring oslo_messaging: admin: cinder-rabbitmq-admin cinder: cinder-rabbitmq-user tls: volumev3: api: public: cinder-tls-public internal: cinder-tls-api oci_image_registry: cinder: cinder-oci-image-registry # We use a different layout of the endpoints here to account for versioning # this swaps the service name and type, and should be rolled out to other # services. endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false cinder: username: cinder password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default cinder: role: admin,service region_name: RegionOne username: cinder password: password project_name: service user_domain_name: service project_domain_name: service glance: role: admin,service region_name: RegionOne username: glance password: password project_name: service user_domain_name: service project_domain_name: service nova: role: admin,service region_name: RegionOne project_name: service username: cinder_nova password: password user_domain_name: service project_domain_name: service swift: role: admin,service region_name: RegionOne project_name: service username: cinder_swift password: password user_domain_name: service project_domain_name: service service: role: admin,service region_name: RegionOne project_name: service username: cinder_service_user password: password user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: cinder-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 image: name: glance hosts: default: glance-api public: glance host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 9292 public: 80 volumev3: name: cinderv3 hosts: default: cinder-api public: cinder host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: '/v3' healthcheck: /healthcheck scheme: default: 'http' port: api: default: 8776 public: 80 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct cinder: username: cinder password: password hosts: default: mariadb host_fqdn_override: default: null path: /cinder scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct cinder: username: cinder password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /cinder scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 network_policy: cinder: ingress: - {} egress: - {} tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false configmap_bin: true configmap_etc: true cron_volume_usage_audit: true cron_db_purge: false deployment_api: true deployment_backup: true deployment_scheduler: true deployment_volume: true ingress_api: true job_backup_storage_init: true job_bootstrap: true job_clean: true job_create_internal_tenant: true job_db_init: true job_image_repo_sync: true job_rabbit_init: true job_db_sync: true job_db_drop: false job_ks_endpoints: true job_ks_service: true job_ks_user: true job_storage_init: true pdb_api: true pod_rally_test: true pvc_backup: true network_policy: false secret_db: true secret_ingress_tls: true secret_keystone: true secret_ks_etc: true secret_rabbitmq: true secret_registry: true service_api: true service_ingress_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: cloudkitty/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Cloudkitty name: cloudkitty version: 2025.2.0 home: https://docs.openstack.org/cloudkitty/latest/ icon: https://opendev.org/openstack/cloudkitty/media/branch/master/doc/source/images/cloudkitty-logo.png sources: - https://opendev.org/openstack/cloudkitty - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: cloudkitty/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2017 The Openstack-Helm Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: cloudkitty/templates/bin/_cloudkitty-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/cloudkitty/cloudkitty-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: cloudkitty/templates/bin/_cloudkitty-processor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec cloudkitty-processor \ --config-file /etc/cloudkitty/cloudkitty.conf \ --config-dir /etc/cloudkitty/cloudkitty.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: cloudkitty/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex cloudkitty-dbsync upgrade ================================================ FILE: cloudkitty/templates/bin/_storage-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex cloudkitty-storage-init ================================================ FILE: cloudkitty/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: cloudkitty-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} cloudkitty-processor.sh: | {{ tuple "bin/_cloudkitty-processor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} cloudkitty-api.sh: | {{ tuple "bin/_cloudkitty-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} storage-init.sh: | {{ tuple "bin/_storage-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: cloudkitty/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "cloudkitty.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty .Values.conf.cloudkitty.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.cloudkitty.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.cloudkitty.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.cloudkitty.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.cloudkitty.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.cloudkitty.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.cloudkitty.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.cloudkitty.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.cloudkitty.database.connection)) (empty .Values.conf.cloudkitty.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "cloudkitty" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.cloudkitty.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.cloudkitty.database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "cloudkitty" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.cloudkitty.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.os_privileged_user_name -}} {{- $_ := set .Values.conf.cloudkitty.DEFAULT "os_privileged_user_name" .Values.endpoints.identity.auth.cloudkitty.username }} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.os_privileged_user_password -}} {{- $_ := set .Values.conf.cloudkitty.DEFAULT "os_privileged_user_password" .Values.endpoints.identity.auth.cloudkitty.password }} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.os_privileged_user_auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.cloudkitty.DEFAULT "os_privileged_user_auth_url" }} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.os_privileged_user_tenant -}} {{- $_ := set .Values.conf.cloudkitty.DEFAULT "os_privileged_user_tenant" .Values.endpoints.identity.auth.cloudkitty.project_name }} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.os_region_name -}} {{- $_ := set .Values.conf.cloudkitty.DEFAULT "os_region_name" .Values.endpoints.identity.auth.cloudkitty.region_name }} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.os_user_domain_name -}} {{- $_ := set .Values.conf.cloudkitty.DEFAULT "os_user_domain_name" .Values.endpoints.identity.auth.cloudkitty.user_domain_name }} {{- end -}} {{- if empty .Values.conf.cloudkitty.DEFAULT.os_project_domain_name -}} {{- $_ := set .Values.conf.cloudkitty.DEFAULT "os_project_domain_name" .Values.endpoints.identity.auth.cloudkitty.user_domain_name }} {{- end -}} {{- if empty (index .Values.conf.cloudkitty_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "rating" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.cloudkitty_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: cloudkitty.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.cloudkitty | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.paste | b64enc }} metrics.yml: {{ $envAll.Values.conf.processor_metrics | b64enc }} cloudkitty_sudoers: {{ $envAll.Values.conf.cloudkitty_sudoers | b64enc }} cloudkitty-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.cloudkitty_api_uwsgi | b64enc }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "cloudkitty-etc" . | include "cloudkitty.configmap.etc" }} {{- end }} ================================================ FILE: cloudkitty/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "cloudkittyApiLivenessProbeTemplate" }} httpGet: scheme: {{ tuple "rating" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "rating" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "cloudkittyApiReadinessProbeTemplate" }} httpGet: scheme: HTTP path: / port: {{ tuple "rating" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_cloudkitty_api := .Values.pod.mounts.cloudkitty_api.cloudkitty_api }} {{- $mounts_cloudkitty_api_init := .Values.pod.mounts.cloudkitty_api.init_container }} {{- $etcSources := .Values.pod.etcSources.cloudkitty_api }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "cloudkitty-ks-etc")) }} {{- end }} {{- $serviceAccountName := "cloudkitty-api" }} {{- tuple $envAll "cloudkitty_api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: cloudkitty-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "cloudkitty" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.cloudkitty_api }} selector: matchLabels: {{ tuple $envAll "cloudkitty" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "cloudkitty" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "cloudkitty_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "cloudkitty-api" "containerNames" (list "cloudkitty-api-init" "cloudkitty-api" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "cloudkitty" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "cloudkitty" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.cloudkitty.node_selector_key }}: {{ .Values.labels.cloudkitty.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.cloudkitty_api.timeout | default "30" }} initContainers: {{ tuple $envAll "cloudkitty_api" $mounts_cloudkitty_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: cloudkitty-api {{ tuple $envAll "cloudkitty_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.cloudkitty_api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "cloudkitty" "container" "cloudkitty_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/cloudkitty-api.sh - start lifecycle: preStop: exec: command: - /tmp/cloudkitty-api.sh - stop ports: - name: c-api containerPort: {{ tuple "rating" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "cloudkitty" "container" "default" "type" "liveness" "probeTemplate" (include "cloudkittyApiLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "cloudkitty" "container" "default" "type" "readiness" "probeTemplate" (include "cloudkittyApiReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.cloudkitty.oslo_concurrency.lock_path }} - name: cloudkitty-bin mountPath: /tmp/cloudkitty-api.sh subPath: cloudkitty-api.sh - name: etccloudkitty mountPath: /etc/cloudkitty - name: cloudkitty-etc mountPath: /etc/cloudkitty/cloudkitty.conf subPath: cloudkitty.conf - name: cloudkitty-etc mountPath: /etc/cloudkitty/metrics.yml subPath: metrics.yml - name: cloudkitty-etc mountPath: /etc/cloudkitty/logging.conf subPath: logging.conf - name: cloudkitty-etc mountPath: /etc/cloudkitty/api-paste.ini subPath: api-paste.ini - name: cloudkitty-etc mountPath: /etc/cloudkitty/cloudkitty-api-uwsgi.ini subPath: cloudkitty-api-uwsgi.ini - name: cloudkitty-etc-snippets mountPath: /etc/cloudkitty/cloudkitty.conf.d/ readOnly: true {{ if $mounts_cloudkitty_api.volumeMounts }}{{ toYaml $mounts_cloudkitty_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: etccloudkitty emptyDir: {} - name: cloudkitty-bin configMap: name: cloudkitty-bin defaultMode: 0555 - name: cloudkitty-etc secret: secretName: cloudkitty-etc defaultMode: 0444 - name: cloudkitty-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_cloudkitty_api.volumes }}{{ toYaml $mounts_cloudkitty_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: cloudkitty/templates/deployment-processor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_processor }} {{- $envAll := . }} {{- $mounts_cloudkitty_processor := .Values.pod.mounts.cloudkitty_processor.cloudkitty_processor }} {{- $mounts_cloudkitty_processor_init := .Values.pod.mounts.cloudkitty_processor.init_container }} {{- $etcSources := .Values.pod.etcSources.cloudkitty_processor }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "cloudkitty-ks-etc")) }} {{- end }} {{- $serviceAccountName := "cloudkitty-processor" }} {{- tuple $envAll "cloudkitty_processor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: cloudkitty-processor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "cloudkitty" "processor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.cloudkitty_processor }} selector: matchLabels: {{ tuple $envAll "cloudkitty" "processor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "cloudkitty" "processor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "cloudkitty_processor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "cloudkitty-processor" "containerNames" (list "cloudkitty-processor-init" "cloudkitty-processor" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "cloudkitty-processor" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "cloudkitty" "processor" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.cloudkitty.node_selector_key }}: {{ .Values.labels.cloudkitty.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.cloudkitty_processor.timeout | default "30" }} initContainers: {{ tuple $envAll "cloudkitty_processor" $mounts_cloudkitty_processor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: cloudkitty-processor {{ tuple $envAll "cloudkitty_processor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.cloudkitty_processor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "cloudkitty" "container" "cloudkitty_processor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/cloudkitty-processor.sh - start lifecycle: preStop: exec: command: - /tmp/cloudkitty-processor.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.cloudkitty.oslo_concurrency.lock_path }} - name: cloudkitty-bin mountPath: /tmp/cloudkitty-processor.sh subPath: cloudkitty-processor.sh readOnly: true - name: etccloudkitty mountPath: /etc/cloudkitty - name: cloudkitty-etc mountPath: /etc/cloudkitty/cloudkitty.conf subPath: cloudkitty.conf - name: cloudkitty-etc mountPath: /etc/cloudkitty/logging.conf subPath: logging.conf - name: cloudkitty-etc mountPath: /etc/cloudkitty/metrics.yml subPath: metrics.yml - name: cloudkitty-etc-snippets mountPath: /etc/cloudkitty/cloudkitty.conf.d/ readOnly: true {{ if $mounts_cloudkitty_processor.volumeMounts }}{{ toYaml $mounts_cloudkitty_processor.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: etccloudkitty emptyDir: {} - name: cloudkitty-bin configMap: name: cloudkitty-bin defaultMode: 0555 - name: cloudkitty-etc secret: secretName: cloudkitty-etc defaultMode: 0444 - name: cloudkitty-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_cloudkitty_processor.volumes}}{{ toYaml $mounts_cloudkitty_processor.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: cloudkitty/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: cloudkitty/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "rating" "backendPort" "c-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "cloudkitty" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.cloudkitty.DEFAULT.log_config_append -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbToDrop := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.cloudkitty -}} {{- $dbDropJob := dict "envAll" . "serviceName" "cloudkitty" "dbToDrop" $dbToDrop -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "cloudkitty" -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml ) }} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "cloudkitty" "podVolMounts" .Values.pod.mounts.cloudkitty_db_sync.cloudkitty_db_sync.volumeMounts "podVols" .Values.pod.mounts.cloudkitty_db_sync.cloudkitty_db_sync.volumes -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.cloudkitty.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "cloudkitty" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "cloudkitty" "serviceTypes" ( tuple "rating" ) -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml ) }} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "cloudkitty" "serviceTypes" ( tuple "rating" ) -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml ) }} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "cloudkitty" -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml ) }} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-rabbitmq-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "cloudkitty" -}} {{- $_ := set $rmqUserJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: cloudkitty/templates/job-storage-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_storage_init }} {{- $envAll := . }} {{- $serviceAccountName := "cloudkitty-storage-init" }} {{ tuple $envAll "storage_init" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: cloudkitty-storage-init annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} "helm.sh/hook": "post-install,post-upgrade" "helm.sh/hook-weight": "-4" spec: template: metadata: labels: {{ tuple $envAll "cloudkitty" "db-migrate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "storage_init" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: cloudkitty-storage-init {{ tuple $envAll "cloudkitty_storage_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.storage_init | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "cloudkitty" "container" "cloudkitty_storage_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/storage-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: cloudkitty-bin mountPath: /tmp/storage-init.sh subPath: storage-init.sh - name: etccloudkitty mountPath: /etc/cloudkitty - name: cloudkitty-etc mountPath: /etc/cloudkitty/cloudkitty.conf subPath: cloudkitty.conf - name: cloudkitty-etc mountPath: /etc/cloudkitty/logging.conf subPath: logging.conf volumes: - name: pod-tmp emptyDir: {} - name: etccloudkitty emptyDir: {} - name: cloudkitty-etc secret: secretName: cloudkitty-etc defaultMode: 0444 - name: cloudkitty-bin configMap: name: cloudkitty-bin defaultMode: 0555 {{- end }} ================================================ FILE: cloudkitty/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "cloudkitty" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: cloudkitty/templates/pbd-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: cloudkitty-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.cloudkitty_api.min_available }} selector: matchLabels: {{ tuple $envAll "cloudkitty" "cloudkitty_api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: cloudkitty/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "cloudkitty" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: cloudkitty/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "cloudkitty" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: cloudkitty/templates/secret-ks-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ks_etc }} {{- $envAll := . -}} {{/* the endpoints.identity.auth sections with the oslo conf sections they get rendered to */}} {{- $ksUsers := dict "cloudkitty" "keystone_authtoken" -}} {{ dict "envAll" $envAll "serviceName" "cloudkitty" "serviceUserSections" $ksUsers | include "helm-toolkit.manifests.secret_ks_etc" }} {{- end }} ================================================ FILE: cloudkitty/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "cloudkitty" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} TRANSPORT_URL: {{ tuple "oslo_messaging" "internal" $userClass "amqp" $envAll | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: cloudkitty/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: cloudkitty/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "rating" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: c-api port: {{ tuple "rating" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "cloudkitty" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: cloudkitty/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble cloudkitty_api: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble cloudkitty_db_sync: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble cloudkitty_processor: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble cloudkitty_storage_init: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: cloudkitty: node_selector_key: openstack-control-plane node_selector_value: enabled processor: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false cloudkitty: username: cloudkitty password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null rating: name: cloudkitty hosts: default: cloudkitty-api public: cloudkitty-api host_fqdn_override: default: null path: default: "" scheme: default: "http" port: api: default: 8089 public: 80 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct cloudkitty: username: cloudkitty password: password hosts: default: mariadb host_fqdn_override: default: null path: /cloudkitty scheme: mysql+pymysql port: mysql: default: 3306 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default cloudkitty: role: admin region_name: RegionOne username: cloudkitty password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct cloudkitty: username: cloudkitty password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /cloudkitty scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: "http" port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 secrets: identity: admin: cloudkitty-keystone-admin cloudkitty: cloudkitty-keystone-user test: cloudkitty-keystone-test oslo_db: admin: cloudkitty-db-admin cloudkitty: cloudkitty-db-user oslo_messaging: admin: cloudkitty-rabbitmq-admin cloudkitty: cloudkitty-rabbitmq-user oci_image_registry: cloudkitty: cloudkitty-oci-image-registry bootstrap: enabled: false ks_user: cloudkitty script: | openstack token issue dependencies: dynamic: common: local_image_registry: jobs: - cloudkitty-image-repo-sync services: - endpoint: node service: local_image_registry static: cloudkitty_api: jobs: - cloudkitty-db-sync - cloudkitty-storage-init - cloudkitty-ks-user - cloudkitty-ks-endpoints - cloudkitty-ks-service services: - endpoint: internal service: identity cloudkitty_processor: jobs: - cloudkitty-db-sync - cloudkitty-storage-init - cloudkitty-ks-user - cloudkitty-ks-endpoints - cloudkitty-ks-service services: - endpoint: internal service: identity db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - cloudkitty-db-init services: - endpoint: internal service: oslo_db storage_init: jobs: - cloudkitty-db-sync servcies: - endpoint: internal service: oslo_db ks_endpoints: jobs: - cloudkitty-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - service: oslo_messaging endpoint: internal image_repo_sync: services: - endpoint: internal service: local_image_registry pod: security_context: cloudkitty: pod: runAsUser: 42424 container: cloudkitty_api: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 42424 cloudkitty_processor: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 42424 cloudkitty_db_sync: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 42424 test: pod: runAsUser: 42424 container: horizon_test: readOnlyRootFilesystem: true allowPrivilegeEscalation: false probes: cloudkitty: default: liveness: enabled: true params: {} readiness: enabled: true params: {} cloudkitty-processor: default: liveness: enabled: true params: {} readiness: enabled: true params: {} affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: cloudkitty_api: 1 cloudkitty_processor: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: cloudkitty_api: min_available: 0 cloudkitty_processor: min_available: 0 termination_grace_period: cloudkitty_api: timeout: 30 cloudkitty_processor: timeout: 30 tolerations: cloudkitty: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: cloudkitty_api: init_container: null cloudkitty_api: volumeMounts: volumes: cloudkitty_processor: init_container: null cloudkitty_processor: volumeMounts: volumes: cloudkitty_db_sync: cloudkitty_db_sync: volumeMounts: volumes: cloudkitty_db_init: cloudkitty_db_sync: volumeMounts: volumes: cloudkitty_ks_users: cloudkitty_db_sync: volumeMounts: volumes: cloudkitty_ks_service: cloudkitty_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/cloudkitty/cloudkitty.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: cloudkitty_api: [] cloudkitty_processor: [] cloudkitty_db_sync: [] resources: enabled: false cloudkitty_api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" cloudkitty_processor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" storage_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conf: paste: pipeline:cloudkitty+noauth: pipeline: cors healthcheck http_proxy_to_wsgi request_id ck_api pipeline:cloudkitty+keystone: pipeline: cors healthcheck http_proxy_to_wsgi request_id authtoken ck_api app:ck_api: paste.app_factory: cloudkitty.api.app:app_factory filter:authtoken: acl_public_routes: /, /v1, /v2, /healthcheck paste.filter_factory: cloudkitty.api.middleware:AuthTokenMiddleware.factory filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: cloudkitty filter:healthcheck: paste.filter_factory: oslo_middleware:Healthcheck.factory backends: disable_by_file disable_by_file_path: /etc/cloudkitty/healthcheck_disable filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory oslo_config_project: cloudkitty cloudkitty_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "cloudkitty-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/cloudkitty-api processes: 1 stats: 0.0.0.0:1717 stats-http: true cloudkitty: DEFAULT: log_config_append: /etc/cloudkitty/logging.conf api_paste_config: /etc/cloudkitty/api-paste.ini auth_strategy: keystone debug: false keystone_authtoken: auth_type: password username: cloudkitty service_token_roles_required: true service_token_roles: admin,rating,service service_type: rating database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" oslo_concurrency: lock_path: /var/lock collect: collector: gnocchi collector_gnocchi: auth_section: keystone_authtoken fetcher: backend: gnocchi fetcher_gnocchi: auth_section: keystone_authtoken output: pipeline: osrf basepath: /var/cloudkitty/reports backend: cloudkitty.backend.file.FileBackend storage: backend: sqlalchemy version: 1 logging: loggers: keys: - root - cloudkitty handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: DEBUG handlers: - stdout logger_cloudkitty: level: DEBUG handlers: - stdout qualname: cloudkitty logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" cloudkitty_sudoers: | Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin" cloudkitty ALL=(ALL:ALL) NOPASSWD: /var/lib/openstack/bin/privsep-helper processor_metrics: | metrics: cpu: alt_name: instance extra_args: aggregation_method: mean resource_type: instance groupby: - id - user_id - project_id metadata: - flavor_name - flavor_id - vcpus mutate: NUMBOOL unit: instance image.size: extra_args: aggregation_method: mean resource_type: image factor: 1/1048576 groupby: - id - user_id - project_id metadata: - container_format - disk_format unit: MiB ip.floating: extra_args: aggregation_method: mean resource_type: network groupby: - id - user_id - project_id metadata: - state mutate: NUMBOOL unit: ip network.incoming.bytes.rate: extra_args: aggregation_method: mean resource_type: instance_network_interface factor: 3600/1000000 groupby: - id - project_id - user_id metadata: - instance_id unit: MB network.outgoing.bytes.rate: extra_args: aggregation_method: mean resource_type: instance_network_interface factor: 3600/1000000 groupby: - id - project_id - user_id metadata: - instance_id unit: MB radosgw.objects.size: extra_args: aggregation_method: mean resource_type: ceph_account factor: 1/1073741824 groupby: - id - user_id - project_id unit: GiB volume.size: extra_args: aggregation_method: mean resource_type: volume groupby: - id - user_id - project_id metadata: - volume_type unit: GiB network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 33053 network_policy: cloudkitty: ingress: - from: - podSelector: matchLabels: application: cloudkitty - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: ingress - podSelector: matchLabels: application: gnocchi ports: - protocol: TCP port: 80 - protocol: TCP port: 8089 manifests: configmap_bin: true configmap_etc: true deployment_api: true deployment_processor: true ingress_api: true job_bootstrap: true job_ks_user: true job_db_sync: true job_db_init: true job_db_drop: false job_ks_endpoints: true job_ks_service: true job_rabbit_init: true job_storage_init: true pdb_api: true network_policy: false secret_db: true secret_rabbitmq: true secret_keystone: true secret_registry: true service_api: true secret_ks_etc: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: cyborg/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Cyborg name: cyborg version: 2025.2.0 home: https://docs.openstack.org/cyborg icon: https://www.openstack.org/themes/openstack/images/project-mascots/Cyborg/OpenStack_Project_Cyborg_vertical.png sources: - https://opendev.org/openstack/cyborg - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: cyborg/templates/bin/_cyborg-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec cyborg-agent \ --config-file /etc/cyborg/cyborg.conf \ --log-config-append /tmp/logging-cyborg.conf ================================================ FILE: cyborg/templates/bin/_cyborg-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec cyborg-api \ --config-file /etc/cyborg/cyborg.conf \ --log-config-append /tmp/logging-cyborg.conf \ ${OPTIONS} } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: cyborg/templates/bin/_cyborg-conductor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec cyborg-conductor \ --config-file /etc/cyborg/cyborg.conf \ --log-config-append /tmp/logging-cyborg.conf ================================================ FILE: cyborg/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex cyborg-dbsync --config-file /etc/cyborg/cyborg.conf upgrade ================================================ FILE: cyborg/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: cyborg-bin data: db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} cyborg-api.sh: | {{ tuple "bin/_cyborg-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} cyborg-conductor.sh: | {{ tuple "bin/_cyborg-conductor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} cyborg-agent.sh: | {{ tuple "bin/_cyborg-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: cyborg/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "cyborg.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty .Values.conf.cyborg.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.cyborg.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.cyborg.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "region_name" .Values.endpoints.identity.auth.cyborg.region_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "password" .Values.endpoints.identity.auth.cyborg.password -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "project_name" .Values.endpoints.identity.auth.cyborg.project_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "password" .Values.endpoints.identity.auth.cyborg.password -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.cyborg.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "password" .Values.endpoints.identity.auth.cyborg.password -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.cyborg.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.username -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "password" .Values.endpoints.identity.auth.cyborg.password -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "username" .Values.endpoints.identity.auth.cyborg.username -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.password -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "password" .Values.endpoints.identity.auth.cyborg.password -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.cyborg.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.cyborg.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.cyborg.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.cyborg.database.connection)) (empty .Values.conf.cyborg.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "cyborg" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set .Values.conf.cyborg.database "connection" -}} {{- end -}} {{- if empty .Values.conf.cyborg.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "cyborg" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.cyborg.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.cyborg.placement.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.cyborg.placement "auth_url" -}} {{- end -}} {{- if empty .Values.conf.cyborg.placement.project_name -}} {{- $_ := set .Values.conf.cyborg.placement "project_name" .Values.endpoints.identity.auth.placement.project_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.placement.project_domain_name -}} {{- $_ := set .Values.conf.cyborg.placement "project_domain_name" .Values.endpoints.identity.auth.placement.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.placement.user_domain_name -}} {{- $_ := set .Values.conf.cyborg.placement "user_domain_name" .Values.endpoints.identity.auth.placement.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.placement.username -}} {{- $_ := set .Values.conf.cyborg.placement "username" .Values.endpoints.identity.auth.placement.username -}} {{- end -}} {{- if empty .Values.conf.cyborg.placement.password -}} {{- $_ := set .Values.conf.cyborg.placement "password" .Values.endpoints.identity.auth.placement.password -}} {{- end -}} {{- if empty .Values.conf.cyborg.nova.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.cyborg.nova "auth_url" -}} {{- end -}} {{- if empty .Values.conf.cyborg.nova.project_name -}} {{- $_ := set .Values.conf.cyborg.nova "project_name" .Values.endpoints.identity.auth.nova.project_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.nova.project_domain_name -}} {{- $_ := set .Values.conf.cyborg.nova "project_domain_name" .Values.endpoints.identity.auth.nova.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.nova.user_domain_name -}} {{- $_ := set .Values.conf.cyborg.nova "user_domain_name" .Values.endpoints.identity.auth.nova.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.nova.username -}} {{- $_ := set .Values.conf.cyborg.nova "username" .Values.endpoints.identity.auth.nova.username -}} {{- end -}} {{- if empty .Values.conf.cyborg.nova.password -}} {{- $_ := set .Values.conf.cyborg.nova "password" .Values.endpoints.identity.auth.nova.password -}} {{- end -}} {{- if empty .Values.conf.cyborg.service_catalog.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.cyborg.service_catalog "auth_url" -}} {{- end -}} {{- if empty .Values.conf.cyborg.service_catalog.project_name -}} {{- $_ := set .Values.conf.cyborg.service_catalog "project_name" .Values.endpoints.identity.auth.cyborg.project_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.service_catalog.project_domain_name -}} {{- $_ := set .Values.conf.cyborg.service_catalog "project_domain_name" .Values.endpoints.identity.auth.cyborg.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.service_catalog.user_domain_name -}} {{- $_ := set .Values.conf.cyborg.service_catalog "user_domain_name" .Values.endpoints.identity.auth.cyborg.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.cyborg.service_catalog.username -}} {{- $_ := set .Values.conf.cyborg.service_catalog "username" .Values.endpoints.identity.auth.cyborg.username -}} {{- end -}} {{- if empty .Values.conf.cyborg.service_catalog.password -}} {{- $_ := set .Values.conf.cyborg.service_catalog "password" .Values.endpoints.identity.auth.cyborg.password -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: cyborg.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.cyborg | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "cyborg-etc" . | include "cyborg.etc" }} {{- end }} ================================================ FILE: cyborg/templates/daemonset-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "cyborg.agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_cyborg := .Values.pod.mounts.cyborg_agent.cyborg_agent }} {{- $mounts_cyborg_agent_init := .Values.pod.mounts.cyborg_agent.init_container }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: cyborg-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "cyborg_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.agent.node_selector_key }}: {{ .Values.labels.agent.node_selector_value }} hostNetwork: true hostPID: true hostIPC: true dnsPolicy: ClusterFirstWithHostNet initContainers: {{ tuple $envAll "cyborg" $mounts_cyborg_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: cyborg-agent {{ tuple $envAll "cyborg_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: 0 privileged: true env: - name: HOST_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.hostIP command: - /tmp/cyborg-agent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.cyborg.oslo_concurrency.lock_path }} - name: cyborg-bin mountPath: /tmp/cyborg-agent.sh subPath: cyborg-agent.sh readOnly: true - name: cyborg-etc mountPath: /etc/cyborg/cyborg.conf subPath: cyborg.conf readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-shared emptyDir: {} - name: cyborg-bin configMap: name: cyborg-bin defaultMode: 0555 - name: cyborg-etc secret: secretName: cyborg-etc defaultMode: 0444 {{- end }} {{- end }} {{- if .Values.manifests.daemonset_agent }} {{- $envAll := . }} {{- $daemonset := "agent" }} {{- $configMapName := "cyborg-etc" }} {{- $serviceAccountName := "cyborg-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "agent" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "cyborg.agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "cyborg.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: cyborg/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_cyborg_api := .Values.pod.mounts.cyborg_api.cyborg_api }} {{- $mounts_cyborg_api_init := .Values.pod.mounts.cyborg_api.init_container }} {{- $serviceAccountName := "cyborg-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: cyborg-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "cyborg" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "cyborg" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "cyborg" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "cyborg_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "cyborg-api" "containerNames" (list "cyborg" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "cyborg" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "cyborg" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_cyborg_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: cyborg {{ tuple $envAll "cyborg_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "cyborg" "container" "cyborg" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: HOST_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.hostIP command: - /tmp/cyborg-api.sh - start lifecycle: preStop: exec: command: - /tmp/cyborg-api.sh - stop ports: - name: cyborg-api containerPort: {{ tuple "accelerator" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "accelerator" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} livenessProbe: tcpSocket: port: {{ tuple "accelerator" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.cyborg.oslo_concurrency.lock_path }} - name: pod-var-cyborg mountPath: /var/lib/cyborg - name: cyborg-bin mountPath: /tmp/cyborg-api.sh subPath: cyborg-api.sh readOnly: true - name: cyborg-etc mountPath: /etc/cyborg/cyborg.conf subPath: cyborg.conf readOnly: true - name: cyborg-etc mountPath: /etc/cyborg/api-paste.ini subPath: api-paste.ini readOnly: true - name: cyborg-etc mountPath: /etc/cyborg/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_cyborg_api.volumeMounts }}{{ toYaml $mounts_cyborg_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-cyborg emptyDir: {} - name: cyborg-bin configMap: name: cyborg-bin defaultMode: 0555 - name: cyborg-etc secret: secretName: cyborg-etc defaultMode: 0444 {{ if $mounts_cyborg_api.volumes}}{{ toYaml $mounts_cyborg_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: cyborg/templates/deployment-conductor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_conductor }} {{- $envAll := . }} {{- $mounts_cyborg_conductor := .Values.pod.mounts.cyborg_conductor.cyborg_conductor }} {{- $mounts_cyborg_conductor_init := .Values.pod.mounts.cyborg_conductor.init_container }} {{- $serviceAccountName := "cyborg-conductor" }} {{ tuple $envAll "conductor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: cyborg-conductor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "cyborg" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.conductor }} selector: matchLabels: {{ tuple $envAll "cyborg" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "cyborg" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "cyborg_conductor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "cyborg-conductor" "containerNames" (list "cyborg-conductor" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "cyborg" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "cyborg" "conductor" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.conductor.node_selector_key }}: {{ .Values.labels.conductor.node_selector_value }} initContainers: {{ tuple $envAll "conductor" $mounts_cyborg_conductor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: cyborg-conductor {{ tuple $envAll "cyborg_conductor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.conductor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "cyborg" "container" "cyborg_conductor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: HOST_IP valueFrom: fieldRef: apiVersion: v1 fieldPath: status.hostIP command: - /tmp/cyborg-conductor.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.cyborg.oslo_concurrency.lock_path }} - name: cyborg-bin mountPath: /tmp/cyborg-conductor.sh subPath: cyborg-conductor.sh readOnly: true - name: cyborg-etc mountPath: /etc/cyborg/cyborg.conf subPath: cyborg.conf readOnly: true - name: cyborg-etc mountPath: /etc/cyborg/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_cyborg_conductor.volumeMounts }}{{ toYaml $mounts_cyborg_conductor.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: cyborg-bin configMap: name: cyborg-bin defaultMode: 0555 - name: cyborg-etc secret: secretName: cyborg-etc defaultMode: 0444 {{ if $mounts_cyborg_conductor.volumes }}{{ toYaml $mounts_cyborg_conductor.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: cyborg/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: cyborg/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "accelerator" "backendPort" "cyborg-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: cyborg/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "cyborg" -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: cyborg/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "cyborg" -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: cyborg/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "cyborg" -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: cyborg/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "cyborg" "serviceTypes" ( tuple "accelerator" ) -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: cyborg/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "cyborg" "serviceTypes" ( tuple "accelerator" ) "configMapBin" "cyborg-bin" -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: cyborg/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "cyborg" -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: cyborg/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "cyborg" -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: cyborg/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "cyborg" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: cyborg/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: cyborg-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "cyborg" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: cyborg/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "cyborg" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: cyborg/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "cyborg" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: cyborg/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "cyborg" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: cyborg/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: cyborg/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "accelerator" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: cyborg-api port: {{ tuple "accelerator" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "cyborg" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: cyborg/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "accelerator" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: cyborg/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble cyborg_db_sync: quay.io/airshipit/cyborg:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble cyborg_api: quay.io/airshipit/cyborg:2025.1-ubuntu_noble cyborg_conductor: quay.io/airshipit/cyborg:2025.1-ubuntu_noble cyborg_agent: quay.io/airshipit/cyborg:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled conductor: node_selector_key: openstack-control-plane node_selector_value: enabled agent: node_selector_key: openstack-compute-node node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false cyborg: username: cyborg password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null accelerator: name: cyborg hosts: default: cyborg-api admin: cyborg public: cyborg host_fqdn_override: default: null path: default: /v2 scheme: default: http port: api: default: 6666 admin: 80 public: 80 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct cyborg: username: cyborg password: password hosts: default: mariadb host_fqdn_override: default: null path: /cyborg scheme: mysql+pymysql port: mysql: default: 3306 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default cyborg: role: admin region_name: RegionOne username: cyborg password: password project_name: service user_domain_name: service project_domain_name: service placement: role: admin region_name: RegionOne username: placement password: password project_name: service user_domain_name: service project_domain_name: service nova: role: admin region_name: RegionOne username: nova password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: neutron-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct cyborg: username: cyborg password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /cyborg scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 secrets: identity: admin: cyborg-keystone-admin cyborg: cyborg-keystone-user test: cyborg-keystone-test oslo_db: admin: cyborg-db-admin cyborg: cyborg-db-user oslo_messaging: admin: cyborg-rabbitmq-admin cyborg: cyborg-rabbitmq-user oci_image_registry: cyborg: cyborg-oci-image-registry dependencies: static: api: jobs: - cyborg-db-sync - cyborg-ks-user - cyborg-ks-endpoints - cyborg-ks-service services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging conductor: jobs: - cyborg-db-sync - cyborg-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity agent: jobs: - cyborg-db-sync - cyborg-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: placement db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - cyborg-db-init services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - cyborg-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution conductor: requiredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: cyborg_api: init_container: null cyborg_api: volumeMounts: volumes: cyborg_conductor: init_container: null cyborg_conductor: volumeMounts: volumes: cyborg_agent: init_container: null cyborg_agent: volumeMounts: volumes: cyborg_db_sync: cyborg_db_sync: volumeMounts: - name: db-sync-sh mountPath: /tmp/env.py subPath: env.py readOnly: true volumes: replicas: api: 3 conductor: 3 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 daemonsets: pod_replacement_strategy: RollingUpdate cyborg: enabled: true min_ready_seconds: 0 max_unavailable: 1 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: true api: requests: memory: "128Mi" limits: memory: "1024Mi" conductor: requests: memory: "128Mi" limits: memory: "1024Mi" agent: requests: memory: "128Mi" limits: memory: "1024Mi" jobs: db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conf: paste: pipeline:main: pipeline: cors request_id authtoken api_v2 app:api_v2: paste.app_factory: cyborg.api.app:app_factory filter:authtoken: acl_public_routes: /, /v2 paste.filter_factory: cyborg.api.middleware.auth_token:AuthTokenMiddleware.factory filter:osprofiler: paste.filter_factory: cyborg.common.profiler:WsgiMiddleware.factory filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: cyborg policy: {} cyborg: DEFAULT: use_syslog: false state_path: /var/lib/cyborg debug: true api: host_ip: 0.0.0.0 api_workers: 3 database: # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" service_catalog: auth_type: password oslo_messaging_rabbit: rabbit_ha_queues: true amqp_durable_queues: true oslo_concurrency: lock_path: /var/lock placement: auth_type: password nova: auth_type: password keystone_authtoken: auth_type: password endpoint_type: internal www_authenticate_uri: null service_type: accelerator agent: enabled_drivers: - nvidia_gpu_driver gpu_devices: enabled_vgpu_types: [] cyborg_sys_admin: helper_command: /var/lib/openstack/bin/privsep-helper rabbitmq: policies: - vhost: "cyborg" name: "ha_ttl_cyborg" definition: ha-mode: "all" ha-sync-mode: "automatic" message-ttl: 70000 priority: 0 apply-to: all pattern: '^(?!(amq\.|reply_)).*' network: api: port: 6666 istio: public: true ingress: public: false classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30666 manifests: certificates: false configmap_bin: true configmap_etc: true daemonset_agent: true deployment_api: true deployment_conductor: true ingress_api: true job_db_drop: false job_db_init: true job_db_sync: true job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pdb_api: true network_policy: false secret_db: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_ingress_api: false service_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: designate/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Designate name: designate version: 2025.2.0 home: https://docs.openstack.org/designate/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Designate/OpenStack_Project_Designate_vertical.jpg sources: - https://opendev.org/openstack/designate - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: designate/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: designate/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex designate-manage database sync ================================================ FILE: designate/templates/bin/_designate-api.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/designate/designate-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: designate/templates/bin/_designate-central.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex COMMAND="${@:-start}" function start () { exec designate-central \ --config-file /etc/designate/designate.conf \ --config-dir /etc/designate/designate.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: designate/templates/bin/_designate-mdns.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex COMMAND="${@:-start}" function start () { designate-mdns \ --config-file /etc/designate/designate.conf \ --config-dir /etc/designate/designate.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: designate/templates/bin/_designate-producer.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex COMMAND="${@:-start}" function start () { designate-producer \ --config-file /etc/designate/designate.conf \ --config-dir /etc/designate/designate.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: designate/templates/bin/_designate-service-cleaner.sh.tpl ================================================ #!/bin/bash # Copyright (c) 2025 VEXXHOST, Inc. # SPDX-License-Identifier: Apache-2.0 set -ex designate-manage \ --config-file /etc/designate/designate.conf \ --config-dir /etc/designate/designate.conf.d \ service clean ================================================ FILE: designate/templates/bin/_designate-sink.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex COMMAND="${@:-start}" exec designate-sink \ --config-file /etc/designate/designate.conf \ --config-dir /etc/designate/designate.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: designate/templates/bin/_designate-worker.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex COMMAND="${@:-start}" function start () { designate-worker \ --config-file /etc/designate/designate.conf \ --config-dir /etc/designate/designate.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: designate/templates/configmap-bin.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: designate-bin data: {{- if .Values.bootstrap.enabled }} bootstrap.sh: |+ {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ks-service.sh: |+ {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: |+ {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: |+ {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} designate-api.sh: | {{ tuple "bin/_designate-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} designate-central.sh: | {{ tuple "bin/_designate-central.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} designate-mdns.sh: | {{ tuple "bin/_designate-mdns.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} designate-worker.sh: | {{ tuple "bin/_designate-worker.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} designate-producer.sh: | {{ tuple "bin/_designate-producer.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} designate-sink.sh: | {{ tuple "bin/_designate-sink.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} designate-service-cleaner.sh: | {{ tuple "bin/_designate-service-cleaner.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: designate/templates/configmap-etc.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.designate.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.designate.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.designate.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.designate.keystone_authtoken "region_name" .Values.endpoints.identity.auth.designate.region_name -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.designate.keystone_authtoken "project_name" .Values.endpoints.identity.auth.designate.project_name -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.designate.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.designate.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.designate.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.designate.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.username -}} {{- $_ := set .Values.conf.designate.keystone_authtoken "username" .Values.endpoints.identity.auth.designate.username -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.password -}} {{- $_ := set .Values.conf.designate.keystone_authtoken "password" .Values.endpoints.identity.auth.designate.password -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.designate.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.designate.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.designate.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" (index .Values.conf.designate "storage:sqlalchemy").connection)) (empty (index .Values.conf.designate "storage:sqlalchemy").connection) -}} {{- $_ := tuple "oslo_db" "internal" "designate" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set (index .Values.conf.designate "storage:sqlalchemy") "connection" -}} {{- $_ := tuple "oslo_db" "internal" "designate" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set .Values.conf.designate.database "connection" -}} {{- end -}} {{- if empty .Values.conf.designate.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "designate" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.designate.DEFAULT "transport_url" -}} {{- end -}} {{- if empty (index .Values.conf.designate "service:api").api_base_uri -}} {{- $_ := tuple "dns" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set (index .Values.conf.designate "service:api") "api_base_uri" -}} {{- end -}} {{- if empty .Values.conf.designate_api_uwsgi.uwsgi.processes -}} {{- $_ := set .Values.conf.designate_api_uwsgi.uwsgi "processes" (index .Values.conf.designate "service:api").workers -}} {{- end -}} {{- if empty (index .Values.conf.designate_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "dns" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.designate_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: designate-etc type: Opaque data: designate.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.designate | b64enc }} designate-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.designate_api_uwsgi | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.pools "key" "pools.yaml" "format" "Secret" ) | indent 2 }} {{- end }} ================================================ FILE: designate/templates/cron-job-service.cleaner.yaml ================================================ # Copyright (c) 2025 VEXXHOST, Inc. # SPDX-License-Identifier: Apache-2.0 {{- if .Values.manifests.cron_job_service_cleaner }} {{- $envAll := . }} {{- $mounts_designate_service_cleaner := .Values.pod.mounts.designate_service_cleaner.designate_service_cleaner }} {{- $mounts_designate_service_cleaner_init := .Values.pod.mounts.designate_service_cleaner.init_container }} {{- $etcSources := .Values.pod.etcSources.designate_service_cleaner }} {{- $serviceAccountName := "designate-service-cleaner" }} {{ tuple $envAll "service_cleaner" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: designate-service-cleaner annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.service_cleaner.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.service_cleaner.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.service_cleaner.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "designate" "service-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "designate-service-cleaner" "containerNames" (list "init" "designate-service-cleaner" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "designate" "service-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 12 }} {{ dict "envAll" $envAll "podName" "designate-service-cleaner" "containerNames" (list "init" "designate-service-cleaner" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "designate_service_cleaner" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "designate_service_cleaner" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.service_cleaner.node_selector_key }}: {{ .Values.labels.service_cleaner.node_selector_value }} initContainers: {{ tuple $envAll "service_cleaner" $mounts_designate_service_cleaner_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: designate-service-cleaner {{ tuple $envAll "designate_service_cleaner" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.service_cleaner | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} command: - /tmp/designate-service-cleaner.sh volumeMounts: - name: designate-bin mountPath: /tmp/designate-service-cleaner.sh subPath: designate-service-cleaner.sh readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: pod-var-cache-designate mountPath: /var/cache/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true - name: designate-etc-snippets mountPath: /etc/designate/designate.conf.d/ readOnly: true - name: designate-etc mountPath: /etc/designate/api-paste.ini subPath: api-paste.ini readOnly: true - name: designate-etc mountPath: /etc/designate/policy.yaml subPath: policy.yaml readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_service_cleaner.volumeMounts }}{{ toYaml $mounts_designate_service_cleaner.volumeMounts | indent 16 }}{{ end }} volumes: - name: pod-etc-designate emptyDir: {} - name: pod-var-cache-designate emptyDir: {} - name: designate-bin configMap: name: designate-bin defaultMode: 0555 - name: designate-etc secret: secretName: designate-etc defaultMode: 0444 - name: service-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_designate_service_cleaner.volumes }}{{ toYaml $mounts_designate_service_cleaner.volumes | indent 12 }}{{ end }} {{- end }} ================================================ FILE: designate/templates/deployment-api.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_designate_api := .Values.pod.mounts.designate_api.designate_api }} {{- $mounts_designate_api_init := .Values.pod.mounts.designate_api.init_container }} {{- $etcSources := .Values.pod.etcSources.designate_api }} {{- $serviceAccountName := "designate-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: designate-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "designate" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "designate" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "designate" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "designate_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ tuple "designate_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "designate_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "designate" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "designate" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_designate_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: designate-api {{ tuple $envAll "designate_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "designate" "container" "designate_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/designate-api.sh lifecycle: preStop: exec: command: - /tmp/designate-api.sh - stop ports: - name: dns-api containerPort: {{ tuple "dns" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: {{ tuple "dns" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "dns" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: oslo-lock-path mountPath: {{ .Values.conf.designate.oslo_concurrency.lock_path }} - name: designate-bin mountPath: /tmp/designate-api.sh subPath: designate-api.sh readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: pod-var-cache-designate mountPath: /var/cache/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true - name: designate-etc-snippets mountPath: /etc/designate/designate.conf.d/ readOnly: true - name: designate-etc mountPath: /etc/designate/api-paste.ini subPath: api-paste.ini readOnly: true - name: designate-etc mountPath: /etc/designate/policy.yaml subPath: policy.yaml readOnly: true - name: designate-etc mountPath: /etc/designate/designate-api-uwsgi.ini subPath: designate-api-uwsgi.ini readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_api.volumeMounts }}{{ toYaml $mounts_designate_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: oslo-lock-path emptyDir: {} - name: pod-etc-designate emptyDir: {} - name: pod-var-cache-designate emptyDir: {} - name: designate-bin configMap: name: designate-bin defaultMode: 0555 - name: designate-etc secret: secretName: designate-etc defaultMode: 0444 - name: designate-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_designate_api.volumes }}{{ toYaml $mounts_designate_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: designate/templates/deployment-central.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.deployment_central }} {{- $envAll := . }} {{- $mounts_designate_central := .Values.pod.mounts.designate_central.designate_central }} {{- $mounts_designate_central_init := .Values.pod.mounts.designate_central.init_container }} {{- $etcSources := .Values.pod.etcSources.designate_central }} {{- $serviceAccountName := "designate-central" }} {{ tuple $envAll "central" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: designate-central annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "designate" "central" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.central }} selector: matchLabels: {{ tuple $envAll "designate" "central" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "designate" "central" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "designate_central" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ tuple "designate_central" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "designate_central" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "designate" "central" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.central.node_selector_key }}: {{ .Values.labels.central.node_selector_value }} initContainers: {{ tuple $envAll "central" $mounts_designate_central_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: designate-central {{ tuple $envAll "designate_central" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.central | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "designate" "container" "designate_central" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - bash - /tmp/designate-central.sh volumeMounts: - name: oslo-lock-path mountPath: {{ .Values.conf.designate.oslo_concurrency.lock_path }} - name: designate-bin mountPath: /tmp/designate-central.sh subPath: designate-central.sh readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: pod-var-cache-designate mountPath: /var/cache/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true - name: designate-etc-snippets mountPath: /etc/designate/designate.conf.d/ readOnly: true - name: designate-etc mountPath: /etc/designate/api-paste.ini subPath: api-paste.ini readOnly: true - name: designate-etc mountPath: /etc/designate/policy.yaml subPath: policy.yaml readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_central.volumeMounts }}{{ toYaml $mounts_designate_central.volumeMounts | indent 12 }}{{ end }} volumes: - name: oslo-lock-path emptyDir: {} - name: pod-etc-designate emptyDir: {} - name: pod-var-cache-designate emptyDir: {} - name: designate-bin configMap: name: designate-bin defaultMode: 0555 - name: designate-etc secret: secretName: designate-etc defaultMode: 0444 - name: designate-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_designate_central.volumes }}{{ toYaml $mounts_designate_central.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: designate/templates/deployment-mdns.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.deployment_mdns }} {{- $envAll := . }} {{- $mounts_designate_mdns := .Values.pod.mounts.designate_mdns.designate_mdns }} {{- $mounts_designate_mdns_init := .Values.pod.mounts.designate_mdns.init_container }} {{- $etcSources := .Values.pod.etcSources.designate_mdns }} {{- $serviceAccountName := "designate-mdns" }} {{ tuple $envAll "mdns" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: designate-mdns annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "designate" "mdns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.mdns }} selector: matchLabels: {{ tuple $envAll "designate" "mdns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "designate" "mdns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "designate_mdns" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ tuple "designate_mdns" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "designate_mdns" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "designate" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "designate" "mdns" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.mdns.node_selector_key }}: {{ .Values.labels.mdns.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.mdns.timeout | default "30" }} initContainers: {{ tuple $envAll "mdns" $mounts_designate_mdns_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: designate-mdns {{ tuple $envAll "designate_mdns" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.mdns | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "designate" "container" "designate_mdns" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} ports: - name: d-mdns containerPort: {{ tuple "mdns" "internal" "ipc" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: d-mdns-udp containerPort: {{ tuple "mdns" "internal" "ipc" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: UDP readinessProbe: tcpSocket: port: {{ tuple "mdns" "internal" "ipc" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} command: - bash - /tmp/designate-mdns.sh volumeMounts: - name: oslo-lock-path mountPath: {{ .Values.conf.designate.oslo_concurrency.lock_path }} - name: designate-bin mountPath: /tmp/designate-mdns.sh subPath: designate-mdns.sh readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: pod-var-cache-designate mountPath: /var/cache/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true - name: designate-etc-snippets mountPath: /etc/designate/designate.conf.d/ readOnly: true - name: designate-etc mountPath: /etc/designate/api-paste.ini subPath: api-paste.ini readOnly: true - name: designate-etc mountPath: /etc/designate/policy.yaml subPath: policy.yaml readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_mdns.volumeMounts }}{{ toYaml $mounts_designate_mdns.volumeMounts | indent 12 }}{{ end }} volumes: - name: oslo-lock-path emptyDir: {} - name: pod-etc-designate emptyDir: {} - name: pod-var-cache-designate emptyDir: {} - name: designate-bin configMap: name: designate-bin defaultMode: 0555 - name: designate-etc secret: secretName: designate-etc defaultMode: 0444 - name: designate-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_designate_mdns.volumes }}{{ toYaml $mounts_designate_mdns.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: designate/templates/deployment-producer.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.deployment_producer }} {{- $envAll := . }} {{- $mounts_designate_producer := .Values.pod.mounts.designate_producer.designate_producer }} {{- $mounts_designate_producer_init := .Values.pod.mounts.designate_producer.init_container }} {{- $etcSources := .Values.pod.etcSources.designate_producer }} {{- $serviceAccountName := "designate-producer" }} {{ tuple $envAll "producer" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: designate-producer annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "designate" "producer" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.producer }} selector: matchLabels: {{ tuple $envAll "designate" "producer" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "designate" "producer" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "designate_producer" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ tuple "designate_producer" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "designate_producer" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "designate" "producer" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.producer.node_selector_key }}: {{ .Values.labels.producer.node_selector_value }} initContainers: {{ tuple $envAll "producer" $mounts_designate_producer_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: designate-producer {{ tuple $envAll "designate_producer" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.producer | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "designate" "container" "designate_producer" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - bash - /tmp/designate-producer.sh volumeMounts: - name: oslo-lock-path mountPath: {{ .Values.conf.designate.oslo_concurrency.lock_path }} - name: designate-bin mountPath: /tmp/designate-producer.sh subPath: designate-producer.sh readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: pod-var-cache-designate mountPath: /var/cache/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true - name: designate-etc-snippets mountPath: /etc/designate/designate.conf.d/ readOnly: true - name: designate-etc mountPath: /etc/designate/api-paste.ini subPath: api-paste.ini readOnly: true - name: designate-etc mountPath: /etc/designate/policy.yaml subPath: policy.yaml readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_producer.volumeMounts }}{{ toYaml $mounts_designate_producer.volumeMounts | indent 12 }}{{ end }} volumes: - name: oslo-lock-path emptyDir: {} - name: pod-etc-designate emptyDir: {} - name: pod-var-cache-designate emptyDir: {} - name: designate-bin configMap: name: designate-bin defaultMode: 0555 - name: designate-etc secret: secretName: designate-etc defaultMode: 0444 - name: designate-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_designate_producer.volumes }}{{ toYaml $mounts_designate_producer.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: designate/templates/deployment-sink.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.deployment_sink }} {{- $envAll := . }} {{- $mounts_designate_sink := .Values.pod.mounts.designate_sink.designate_sink }} {{- $mounts_designate_sink_init := .Values.pod.mounts.designate_sink.init_container }} {{- $etcSources := .Values.pod.etcSources.designate_sink }} {{- $serviceAccountName := "designate-sink" }} {{ tuple $envAll "sink" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: designate-sink annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "designate" "sink" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.sink }} selector: matchLabels: {{ tuple $envAll "designate" "sink" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "designate" "sink" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "designate_sink" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ tuple "designate_sink" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "designate_sink" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "designate" "sink" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.sink.node_selector_key }}: {{ .Values.labels.sink.node_selector_value }} initContainers: {{ tuple $envAll "sink" $mounts_designate_sink_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: designate-sink {{ tuple $envAll "designate_sink" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.sink | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "designate" "container" "designate_sink" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - bash - /tmp/designate-sink.sh volumeMounts: - name: oslo-lock-path mountPath: {{ .Values.conf.designate.oslo_concurrency.lock_path }} - name: designate-bin mountPath: /tmp/designate-sink.sh subPath: designate-sink.sh readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: pod-var-cache-designate mountPath: /var/cache/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true - name: designate-etc-snippets mountPath: /etc/designate/designate.conf.d/ readOnly: true - name: designate-etc mountPath: /etc/designate/policy.yaml subPath: policy.yaml readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_sink.volumeMounts }}{{ toYaml $mounts_designate_sink.volumeMounts | indent 12 }}{{ end }} volumes: - name: oslo-lock-path emptyDir: {} - name: pod-etc-designate emptyDir: {} - name: pod-var-cache-designate emptyDir: {} - name: designate-bin configMap: name: designate-bin defaultMode: 0555 - name: designate-etc secret: secretName: designate-etc defaultMode: 0444 - name: designate-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_designate_sink.volumes }}{{ toYaml $mounts_designate_sink.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: designate/templates/deployment-worker.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.deployment_worker }} {{- $envAll := . }} {{- $mounts_designate_worker := .Values.pod.mounts.designate_worker.designate_worker }} {{- $mounts_designate_worker_init := .Values.pod.mounts.designate_worker.init_container }} {{- $etcSources := .Values.pod.etcSources.designate_worker }} {{- $serviceAccountName := "designate-worker" }} {{ tuple $envAll "worker" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: designate-worker annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "designate" "worker" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.worker }} selector: matchLabels: {{ tuple $envAll "designate" "worker" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "designate" "worker" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "designate_worker" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ tuple "designate_worker" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "designate_worker" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "designate" "worker" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.worker.node_selector_key }}: {{ .Values.labels.worker.node_selector_value }} initContainers: {{ tuple $envAll "worker" $mounts_designate_worker_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: designate-worker-init {{ tuple $envAll "designate_worker" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.worker | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - bash - -c - 'eval "echo \"$(cat /tmp/designate_pools.template)\"" > /etc/designate/pools.yaml && designate-manage pool update' volumeMounts: - name: designate-etc mountPath: /tmp/designate_pools.template subPath: pools.yaml readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_worker.volumeMounts }}{{ toYaml $mounts_designate_worker.volumeMounts | indent 12 }}{{ end }} containers: - name: designate-worker {{ tuple $envAll "designate_worker" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.worker | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "designate" "container" "designate_worker" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - bash - /tmp/designate-worker.sh volumeMounts: - name: oslo-lock-path mountPath: {{ .Values.conf.designate.oslo_concurrency.lock_path }} - name: designate-bin mountPath: /tmp/designate-worker.sh subPath: designate-worker.sh readOnly: true - name: pod-etc-designate mountPath: /etc/designate - name: pod-var-cache-designate mountPath: /var/cache/designate - name: designate-etc mountPath: /etc/designate/designate.conf subPath: designate.conf readOnly: true - name: designate-etc-snippets mountPath: /etc/designate/designate.conf.d/ readOnly: true - name: designate-etc mountPath: /etc/designate/api-paste.ini subPath: api-paste.ini readOnly: true - name: designate-etc mountPath: /etc/designate/policy.yaml subPath: policy.yaml readOnly: true {{- if .Values.conf.designate.DEFAULT.log_config_append }} - name: designate-etc mountPath: {{ .Values.conf.designate.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.designate.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_designate_worker.volumeMounts }}{{ toYaml $mounts_designate_worker.volumeMounts | indent 12 }}{{ end }} volumes: - name: oslo-lock-path emptyDir: {} - name: pod-etc-designate emptyDir: {} - name: pod-var-cache-designate emptyDir: {} - name: designate-bin configMap: name: designate-bin defaultMode: 0555 - name: designate-etc secret: secretName: designate-etc defaultMode: 0444 - name: designate-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_designate_worker.volumes }}{{ toYaml $mounts_designate_worker.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: designate/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: designate/templates/ingress-api.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.ingress_api }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "dns" "backendPort" "dns-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: designate/templates/job-bootstrap.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.job_bootstrap }} {{- $envAll := . }} {{- if .Values.bootstrap.enabled }} {{- $mounts_designate_bootstrap := .Values.pod.mounts.designate_bootstrap.designate_bootstrap }} {{- $mounts_designate_bootstrap_init := .Values.pod.mounts.designate_bootstrap.init_container }} --- apiVersion: batch/v1 kind: Job metadata: name: designate-bootstrap spec: template: metadata: labels: {{ tuple $envAll "designate" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "bootstrap" $mounts_designate_bootstrap_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: designate-bootstrap image: {{ .Values.images.tags.bootstrap }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/bootstrap.sh volumeMounts: - name: designate-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true {{ if $mounts_designate_bootstrap.volumeMounts }}{{ toYaml $mounts_designate_bootstrap.volumeMounts | indent 10 }}{{ end }} volumes: - name: designate-bin configMap: name: designate-bin defaultMode: 0555 {{ if $mounts_designate_bootstrap.volumes }}{{ toYaml $mounts_designate_bootstrap.volumes | indent 6 }}{{ end }} {{- end }} {{- end }} ================================================ FILE: designate/templates/job-db-init.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "designate" "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: designate/templates/job-db-sync.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "designate" "podVolMounts" .Values.pod.mounts.designate_db_sync.designate_db_sync.volumeMounts "podVols" .Values.pod.mounts.designate_db_sync.designate_db_sync.volumes "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: designate/templates/job-ks-endpoints.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "designate" "serviceTypes" ( tuple "dns" ) "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: designate/templates/job-ks-service.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "designate" "serviceTypes" ( tuple "dns" ) "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: designate/templates/job-ks-user.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # $% What does following represent? {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "designate" "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: designate/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "designate" "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: designate/templates/pdb-api.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: designate-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: app: designate-api {{ tuple $envAll "designate" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: designate/templates/pdb-central.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.pdb_central }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: designate-central spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.central.min_available }} selector: matchLabels: app: designate-central {{- end }} ================================================ FILE: designate/templates/pdb-mdns.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.pdb_mdns }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: designate-mdns spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.mdns.min_available }} selector: matchLabels: app: designate-mdns {{- end }} ================================================ FILE: designate/templates/pdb-producer.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.pdb_producer }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: designate-producer spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.producer.min_available }} selector: matchLabels: app: designate-producer {{- end }} ================================================ FILE: designate/templates/pdb-sink.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.pdb_sink }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: designate-sink spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.sink.min_available }} selector: matchLabels: app: designate-sink {{- end }} ================================================ FILE: designate/templates/pdb-worker.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.pdb_worker }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: designate-worker spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.worker.min_available }} selector: matchLabels: app: designate-worker {{- end }} ================================================ FILE: designate/templates/secret-db.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "designate" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: DB_CONNECTION: {{ tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc -}} {{- end }} {{- end }} ================================================ FILE: designate/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "dns" ) }} {{- end }} ================================================ FILE: designate/templates/secret-keystone.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "designate" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: designate/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "designate" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: designate/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: designate/templates/service-api.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "dns" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: dns-api port: {{ tuple "dns" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "designate" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: designate/templates/service-ingress-api.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.service_ingress_api }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "dns" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: designate/templates/service-mdns.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.service_mdns }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "mdns" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: d-mdns port: {{ tuple "mdns" "internal" "ipc" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: d-mdns-udp port: {{ tuple "mdns" "internal" "ipc" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: UDP selector: {{ tuple $envAll "designate" "mdns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.mdns.node_port.enabled }} type: NodePort {{ if .Values.network.mdns.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: designate/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for designate. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled central: node_selector_key: openstack-control-plane node_selector_value: enabled producer: node_selector_key: openstack-control-plane node_selector_value: enabled worker: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled mdns: node_selector_key: openstack-control-plane node_selector_value: enabled service_cleaner: node_selector_key: openstack-control-plane node_selector_value: enabled sink: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy designate_db_sync: quay.io/airshipit/designate:2025.1-ubuntu_noble designate_api: quay.io/airshipit/designate:2025.1-ubuntu_noble designate_central: quay.io/airshipit/designate:2025.1-ubuntu_noble designate_mdns: quay.io/airshipit/designate:2025.1-ubuntu_noble designate_worker: quay.io/airshipit/designate:2025.1-ubuntu_noble designate_producer: quay.io/airshipit/designate:2025.1-ubuntu_noble designate_sink: quay.io/airshipit/designate:2025.1-ubuntu_noble designate_service_cleaner: quay.io/airshipit/designate:2025.1-ubuntu_noble pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname mounts: designate_api: init_container: null designate_api: volumeMounts: volumes: designate_central: init_container: null designate_central: volumeMounts: volumes: designate_mdns: init_container: null designate_mdns: volumeMounts: volumes: designate_worker: init_container: null designate_worker: volumeMounts: volumes: designate_producer: init_container: null designate_producer: volumeMounts: volumes: designate_service_cleaner: init_container: null designate_service_cleaner: volumeMounts: volumes: designate_sink: init_container: null designate_sink: volumeMounts: volumes: designate_db_sync: designate_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/designate/designate.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: designate_api: [] designate_central: [] designate_mdns: [] designate_worker: [] designate_producer: [] designate_sink: [] designate_service_cleaner: [] designate_db_sync: [] replicas: api: 1 central: 1 mdns: 1 producer: 1 sink: 1 worker: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 central: min_available: 0 mdns: min_available: 0 worker: min_available: 0 producer: min_available: 0 sink: min_available: 0 termination_grace_period: api: timeout: 30 mdns: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" service_cleaner: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 9001 mdns: name: "designate-mdns" proto: "http" external_policy_local: false node_port: enabled: true port: 5354 bootstrap: enabled: false script: | openstack token issue dependencies: dynamic: common: local_image_registry: jobs: - designate-image-repo-sync services: - endpoint: node service: local_image_registry job_rabbit_init: api: jobs: - designate-rabbit-init sink: jobs: - designate-rabbit-init central: jobs: - designate-rabbit-init worker: jobs: - designate-rabbit-init static: db_init: services: - service: oslo_db endpoint: internal db_sync: jobs: - designate-db-init services: - service: oslo_db endpoint: internal ks_user: services: - service: identity endpoint: internal ks_service: services: - service: identity endpoint: internal ks_endpoints: jobs: - designate-ks-service services: - service: identity endpoint: internal rabbit_init: services: - service: oslo_messaging endpoint: internal api: jobs: - designate-db-sync - designate-ks-user - designate-ks-endpoints service: - service: oslo_db endpoint: internal - service: identity endpoint: internal - service: oslo_messaging endpoint: internal central: jobs: - designate-db-sync - designate-ks-user - designate-ks-endpoints service: - service: oslo_db endpoint: internal - service: identity endpoint: internal - service: oslo_messaging endpoint: internal worker: jobs: - designate-db-sync - designate-ks-user - designate-ks-endpoints services: - service: oslo_db endpoint: internal - service: identity endpoint: internal - service: mdns endpoint: internal mdns: jobs: - designate-db-sync - designate-ks-user - designate-ks-endpoints services: - service: oslo_db endpoint: internal - service: identity endpoint: internal producer: jobs: - designate-db-sync - designate-ks-user - designate-ks-endpoints services: - service: oslo_db endpoint: internal - service: identity endpoint: internal sink: jobs: - designate-db-sync - designate-ks-user - designate-ks-endpoints services: - service: oslo_db endpoint: internal - service: identity endpoint: internal conf: pools: | - name: default # The name is immutable. There will be no option to change the name after # creation and the only way will to change it will be to delete it # (and all zones associated with it) and recreate it. description: Default Pool attributes: {} # List out the NS records for zones hosted within this pool # This should be a record that is created outside of designate, that # points to the public IP of the controller node. ns_records: - hostname: {{ printf "ns.%s.svc.%s." .Release.Namespace .Values.endpoints.cluster_domain_suffix }} priority: 1 # List out the nameservers for this pool. These are the actual DNS servers. # We use these to verify changes have propagated to all nameservers. nameservers: - host: ${POWERDNS_SERVICE_HOST} port: {{ tuple "powerdns" "internal" "powerdns" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} # List out the targets for this pool. For BIND there will be one # entry for each BIND server, as we have to run rndc command on each server targets: - type: pdns4 description: PowerDNS Server # List out the designate-mdns servers from which PowerDNS servers should # request zone transfers (AXFRs) from. # This should be the IP of the controller node. # If you have multiple controllers you can add multiple masters # by running designate-mdns on them, and adding them here. masters: - host: ${MINIDNS_SERVICE_HOST} port: {{ tuple "mdns" "internal" "ipc" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} # PowerDNS Configuration options options: host: ${POWERDNS_SERVICE_HOST} port: {{ tuple "powerdns" "internal" "powerdns" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} api_endpoint: http://${POWERDNS_SERVICE_HOST}:{{ tuple "powerdns" "internal" "powerdns_api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} api_token: {{ tuple "powerdns" "service" . | include "helm-toolkit.endpoints.endpoint_token_lookup" }} paste: composite:osapi_dns: use: egg:Paste#urlmap /: osapi_dns_versions /v2: osapi_dns_v2 /admin: osapi_dns_admin composite:osapi_dns_versions: use: call:designate.api.middleware:auth_pipeline_factory noauth: http_proxy_to_wsgi cors maintenance faultwrapper osapi_dns_app_versions keystone: http_proxy_to_wsgi cors maintenance faultwrapper osapi_dns_app_versions app:osapi_dns_app_versions: paste.app_factory: designate.api.versions:factory composite:osapi_dns_v2: use: call:designate.api.middleware:auth_pipeline_factory noauth: http_proxy_to_wsgi cors request_id faultwrapper validation_API_v2 noauthcontext maintenance normalizeuri osapi_dns_app_v2 keystone: http_proxy_to_wsgi cors request_id faultwrapper validation_API_v2 authtoken keystonecontext maintenance normalizeuri osapi_dns_app_v2 app:osapi_dns_app_v2: paste.app_factory: designate.api.v2:factory composite:osapi_dns_admin: use: call:designate.api.middleware:auth_pipeline_factory noauth: http_proxy_to_wsgi cors request_id faultwrapper noauthcontext maintenance normalizeuri osapi_dns_app_admin keystone: http_proxy_to_wsgi cors request_id faultwrapper authtoken keystonecontext maintenance normalizeuri osapi_dns_app_admin app:osapi_dns_app_admin: paste.app_factory: designate.api.admin:factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: designate filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware:HTTPProxyToWSGI.factory filter:noauthcontext: paste.filter_factory: designate.api.middleware:NoAuthContextMiddleware.factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:keystonecontext: paste.filter_factory: designate.api.middleware:KeystoneContextMiddleware.factory filter:maintenance: paste.filter_factory: designate.api.middleware:MaintenanceMiddleware.factory filter:normalizeuri: paste.filter_factory: designate.api.middleware:NormalizeURIMiddleware.factory filter:faultwrapper: paste.filter_factory: designate.api.middleware:FaultWrapperMiddleware.factory filter:validation_API_v2: paste.filter_factory: designate.api.middleware:APIv2ValidationErrorMiddleware.factory policy: {} designate: DEFAULT: debug: false log_config_append: /etc/designate/logging.conf service:api: auth_strategy: keystone enable_api_v2: true enable_api_admin: true enabled_extensions_v2: quotas,reports workers: 2 service:worker: enabled: true notify: false oslo_middleware: enable_proxy_headers_parsing: true oslo_policy: policy_file: /etc/designate/policy.yaml oslo_concurrency: lock_path: /var/lock database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" storage:sqlalchemy: max_retries: -1 # -- Storage backend connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: auth_version: v3 auth_type: password memcache_security_strategy: ENCRYPT service_type: dns logging: loggers: keys: - root - designate handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_designate: level: INFO handlers: - stdout qualname: designate logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" designate_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "designate-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/designate-api-wsgi stats: 0.0.0.0:1717 stats-http: true # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: designate-keystone-admin designate: designate-keystone-user test: designate-keystone-test oslo_db: admin: designate-db-admin designate: designate-db-user oslo_messaging: admin: designate-rabbitmq-admin designate: designate-rabbitmq-user tls: dns: api: public: designate-tls-public oci_image_registry: designate: designate-oci-image-registry endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false designate: username: designate password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default designate: role: admin region_name: RegionOne username: designate password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: designate-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 dns: name: designate hosts: default: designate-api public: designate host_fqdn_override: default: null path: default: / scheme: default: 'http' port: api: default: 9001 public: 80 mdns: name: minidns hosts: default: minidns public: designate-mdns host_fqdn_override: default: null path: default: null scheme: default: 'tcp' port: ipc: default: 5354 oslo_db: auth: admin: username: root password: password designate: username: designate password: password hosts: default: mariadb host_fqdn_override: default: null path: /designate scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 auth: # NOTE: this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null oslo_messaging: auth: admin: username: rabbitmq password: password designate: username: designate password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /designate scheme: rabbit port: amqp: default: 5672 http: default: 15672 powerdns: auth: service: token: chiave_segreta hosts: default: powerdns host_fqdn_override: default: null port: powerdns_api: default: 8081 powerdns: default: 53 jobs: service_cleaner: cron: "*/10 * * * *" history: success: 3 failed: 1 manifests: configmap_bin: true configmap_etc: true cron_job_service_cleaner: true deployment_api: true deployment_central: true deployment_worker: true deployment_producer: true deployment_mdns: true deployment_sink: false ingress_api: true job_bootstrap: true job_db_init: true job_db_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pdb_api: true pdb_producer: true pdb_central: true pdb_worker: true pdb_mdns: true pdb_sink: false secret_db: true secret_ingress_tls: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_api: true service_mdns: true service_ingress_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: doc/helm-docs.rst.gotmpl ================================================ {{- define "chart.valueDefaultColumnRender" }} {{- $defaultValue := (default .Default .AutoDefault) -}} {{- $notationType := .NotationType }} {{- if (and (hasPrefix "```" $defaultValue) (hasSuffix "```" $defaultValue) ) -}} {{- $defaultValue = (toPrettyJson (fromJson (trimAll "```" (default .Default .AutoDefault) ) ) ) -}} {{- $notationType = "json" }} {{- end -}} {{- if contains "\\n" $defaultValue }} {{- $notationType = "default" }} {{- end }} {{- if eq $notationType "" -}} {{ $defaultValue }} {{- else -}} .. code-block:: {{ $notationType }} {{ (trimAll "`" $defaultValue | trimAll "\"" | replace "\\n" "\n") | indent 10 }} {{- end }} {{- end }} {{ title .Name }} {{ repeat (len .Name) "=" }} There are various customizations you can do to tailor the deployment of OpenStack {{ title .Name }}. You can find those below. ================== General Parameters ================== {{- define "chart.generalParamsvaluesTable" }} {{- range .Values }} * {{ .Key }} * Type: {{ .Type }} * Description: {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} * {{ template "chart.valueDefaultColumnRender" . }} {{- end }} {{- end }} {{ template "chart.generalParamsvaluesTable" . }} ================================================ FILE: doc/requirements.txt ================================================ # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. sphinx>=2.0.0,!=2.1.0 # BSD openstackdocstheme>=2.2.1 # Apache-2.0 reno>=3.1.0 # Apache-2.0 ================================================ FILE: doc/source/_exts/helm_docs.py ================================================ # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from pathlib import Path import subprocess from sphinx.application import Sphinx from sphinx.util import logging from sphinx.util.typing import ExtensionMetadata PREFIX = "[helm_docs] " VERSION = "0.1" # the main template we use for all charts HELMDOCSTMPL = "helm-docs.rst.gotmpl" LOCALHELMDOCSTMPL = "README.rst.gotmpl" logger = logging.getLogger(__name__) def _run_helm_docs( helmdocsbin: Path, rootdir: Path, outfile: Path, chart: str, helmdocstmpl: Path, charttmpl: Path | None, ): tmpls = [str(p) for p in [helmdocstmpl, charttmpl] if p is not None] cmd = [ str(helmdocsbin), "--output-file", str(outfile), "--template-files", ",".join(tmpls), "--chart-search-root", chart, ] subprocess.run(cmd, cwd=str(rootdir), check=True) def setup(app: Sphinx) -> ExtensionMetadata: logger.info(PREFIX + "plugin %s", VERSION) # calculate our repo root level rootdir = (Path(app.srcdir) / ".." / "..").resolve() # our helm-docs binary helmdocsbin = rootdir / "tools" / "helm-docs" # this is where we will be writing our docs which # must be a relative path from a chart directory outdir = Path("..") / "doc" / "source" / "chart" # where our main helm template is which must be # relative to a chart directory helmdocstmpl = Path("..") / "doc" / HELMDOCSTMPL # find each chart for chartyaml in rootdir.rglob("Chart.yaml"): # the directory to the chart chartdir = chartyaml.parent # name of our chart chart = chartyaml.parent.name logger.info(PREFIX + "found %s", chart) # does the chart have a local template to include localtmpl = ( LOCALHELMDOCSTMPL if (chartdir / "README.rst.gotmpl").exists() else None ) outfile = outdir / f"{chart}.rst" _run_helm_docs(helmdocsbin, rootdir, outfile, chart, helmdocstmpl, localtmpl) return { "version": VERSION, "parallel_read_safe": True, "parallel_write_safe": True, } ================================================ FILE: doc/source/_static/.placeholder ================================================ ================================================ FILE: doc/source/chart/index.rst ================================================ Chart Options ============= Here are the charts with their documented values.yaml's for OpenStack Helm: .. toctree:: :maxdepth: 2 openstack_charts infra_charts ================================================ FILE: doc/source/chart/infra_charts.rst ================================================ Infra charts options -------------------- .. toctree:: :maxdepth: 2 ca-clusterissuer ca-issuer ceph-adapter-rook ceph-client ceph-mon ceph-osd ceph-provisioners ceph-rgw cert-rotation elastic-apm-server elastic-filebeat elastic-metricbeat elastic-packetbeat elasticsearch etcd fluentbit fluentd gnocchi grafana helm-toolkit kibana kube-dns kubernetes-keystone-webhook kubernetes-node-problem-detector ldap libvirt local-storage local-volume-provisioner mariadb mariadb-backup mariadb-cluster memcached nagios namespace-config nfs-provisioner openvswitch ovn postgresql powerdns prometheus prometheus-alertmanager prometheus-blackbox-exporter prometheus-kube-state-metrics prometheus-mysql-exporter prometheus-node-exporter prometheus-openstack-exporter prometheus-process-exporter rabbitmq redis registry ================================================ FILE: doc/source/chart/openstack_charts.rst ================================================ OpenStack charts options ------------------------ .. toctree:: :maxdepth: 2 aodh barbican blazar ceilometer cinder cyborg cloudkitty designate freezer glance heat horizon ironic keystone magnum manila masakari mistral neutron nova octavia placement rally skyline swift tacker tempest trove watcher zaqar ================================================ FILE: doc/source/conf.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.insert(0, os.path.join(os.path.abspath('.'), '_exts')) sys.path.insert(0, os.path.abspath('../..')) # -- General configuration ---------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'openstackdocstheme', 'helm_docs', ] # openstackdocstheme options openstackdocs_repo_name = 'openstack/openstack-helm' openstackdocs_auto_name = False openstackdocs_use_storyboard = True openstackdocs_pdf_link = True # autodoc generation is a bit aggressive and a nuisance when doing heavy # text edit cycles. # execute "export SPHINX_DEBUG=1" in your terminal to disable # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = 'openstack-helm' copyright = '2016-2023, OpenStack Foundation' # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. show_authors = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # -- Options for HTML output -------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # html_last_updated_fmt = '%Y-%m-%d %H:%M' # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. # html_theme_path = ["."] # html_theme = '_theme' # html_static_path = ['static'] # Output file base name for HTML help builder. htmlhelp_basename = '%sdoc' % project # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass # [howto/manual]). latex_documents = [ ('index', 'doc-%s.tex' % project, '%s Documentation' % project, 'OpenStack Foundation', 'manual'), ] # Example configuration for intersphinx: refer to the Python standard library. # intersphinx_mapping = {'http://docs.python.org/': None} ================================================ FILE: doc/source/devref/endpoints.rst ================================================ Endpoints --------- The project's goal is to provide a consistent mechanism for endpoints. OpenStack is a highly interconnected application, with various components requiring connectivity details to numerous services, including other OpenStack components and infrastructure elements such as databases, queues, and memcached infrastructure. The project's goal is to ensure that it can provide a consistent mechanism for defining these "endpoints" across all charts and provide the macros necessary to convert those definitions into usable endpoints. The charts should consistently default to building endpoints that assume the operator is leveraging all charts to build their OpenStack cloud. Endpoints should be configurable if an operator would like a chart to work with their existing infrastructure or run elements in different namespaces. For instance, in the Neutron chart ``values.yaml`` the following endpoints are defined: :: # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: image: hosts: default: glance-api type: image path: null scheme: 'http' port: api: 9292 compute: hosts: default: nova-api path: "/v2/%(tenant_id)s" type: compute scheme: 'http' port: api: 8774 metadata: 8775 novncproxy: 6080 identity: hosts: default: keystone-api path: /v3 type: identity scheme: 'http' port: admin: 35357 public: 5000 network: hosts: default: neutron-server path: null type: network scheme: 'http' port: api: 9696 These values define all the endpoints that the Neutron chart may need in order to build full URL compatible endpoints to various services. Long-term, these will also include database, memcached, and rabbitmq elements in one place. Essentially, all external connectivity can be defined centrally. The macros that help translate these into the actual URLs necessary are defined in the ``helm-toolkit`` chart. For instance, the cinder chart defines a ``glance_api_servers`` definition in the ``cinder.conf`` template: :: {{- if empty .Values.conf.cinder.DEFAULT.glance_api_servers -}} {{- $_ := tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.cinder.DEFAULT "glance_api_servers" -}} {{- end -}} As an example, this line uses the ``endpoints.keystone_endpoint_uri_lookup`` macro in the ``helm-toolkit`` chart (since it is used by all charts). Note that there is a second convention here. All ``{{ define }}`` macros in charts should be pre-fixed with the chart that is defining them. This allows developers to easily identify the source of a Helm macro and also avoid namespace collisions. In the example above, the macro ``endpoints.keystone_endpoint_uri_lookup`` is defined in the ``helm-toolkit`` chart. This macro is passing three parameters (aided by the ``tuple`` method built into the go/sprig templating library used by Helm): - image: This is the OpenStack service that the endpoint is being built for. This will be mapped to ``glance`` which is the image service for OpenStack. - internal: This is the OpenStack endpoint type we are looking for - valid values would be ``internal``, ``admin``, and ``public`` - api: This is the port to map to for the service. Charts should not use hard coded values such as ``http://keystone-api:5000`` because these are not compatible with operator overrides and do not support spreading components out over various namespaces. By default, each endpoint is located in the same namespace as the current service's helm chart. To connect to a service which is running in a different Kubernetes namespace, a ``namespace`` can be provided for each individual endpoint. ================================================ FILE: doc/source/devref/fluent-logging.rst ================================================ Logging Mechanism ================= Logging Requirements -------------------- OpenStack-Helm defines a centralized logging mechanism to provide insight into the state of the OpenStack services and infrastructure components as well as underlying Kubernetes platform. Among the requirements for a logging platform, where log data can come from and where log data need to be delivered are very variable. To support various logging scenarios, OpenStack-Helm should provide a flexible mechanism to meet with certain operation needs. EFK (Elasticsearch, Fluent-bit & Fluentd, Kibana) based Logging Mechanism ------------------------------------------------------------------------- OpenStack-Helm provides fast and lightweight log forwarder and full featured log aggregator complementing each other providing a flexible and reliable solution. Especially, Fluent-bit is used as a log forwarder and Fluentd is used as a main log aggregator and processor. Fluent-bit, Fluentd meet OpenStack-Helm's logging requirements for gathering, aggregating, and delivering of logged events. Fluent-bit runs as a daemonset on each node and mounts the ``/var/lib/docker/containers`` directory. The Docker container runtime engine directs events posted to stdout and stderr to this directory on the host. Fluent-bit then forward the contents of that directory to Fluentd. Fluentd runs as deployment at the designated nodes and expose service for Fluent-bit to forward logs. Fluentd should then apply the Logstash format to the logs. Fluentd can also write kubernetes and OpenStack metadata to the logs. Fluentd will then forward the results to Elasticsearch and to optionally Kafka. Elasticsearch indexes the logs in a logstash-* index by default. Kafka stores the logs in a ``logs`` topic by default. Any external tool can then consume the ``logs`` topic. The resulting logs can then be queried directly through Elasticsearch, or they can be viewed via Kibana. Kibana offers a dashboard that can create custom views on logged events, and Kibana integrates well with Elasticsearch by default. ================================================ FILE: doc/source/devref/images.rst ================================================ .. _images documentation: Images ------ The project's core philosophy regarding images is that the toolsets required to enable the OpenStack services should be applied by Kubernetes itself. This requires OpenStack-Helm to develop common and simple scripts with minimal dependencies that can be overlaid on any image that meets the OpenStack core library requirements. The advantage of this is that the project can be image agnostic, allowing operators to use Stackanetes, Kolla, LOCI, or any image flavor and format they choose and they will all function the same. A long-term goal, besides being image agnostic, is to also be able to support any of the container runtimes that Kubernetes supports, even those that might not use Docker's own packaging format. This will allow the project to continue to offer maximum flexibility with regard to operator choice. To that end, all charts provide an ``images:`` section that allows operators to override images. Also, all default image references should be fully spelled out, even those hosted by Docker or Quay. Further, no default image reference should use ``:latest`` but rather should be pinned to a specific version to ensure consistent behavior for deployments over time. Today, the ``images:`` section has several common conventions. Most OpenStack services require a database initialization function, a database synchronization function, and a series of steps for Keystone registration and integration. Each component may also have a specific image that composes an OpenStack service. The images may or may not differ, but regardless, should all be defined in ``images``. The following standards are in use today, in addition to any components defined by the service itself: - dep\_check: The image that will perform dependency checking in an init-container. - db\_init: The image that will perform database creation operations for the OpenStack service. - db\_sync: The image that will perform database sync (schema initialization and migration) for the OpenStack service. - db\_drop: The image that will perform database deletion operations for the OpenStack service. - ks\_user: The image that will perform keystone user creation for the service. - ks\_service: The image that will perform keystone service registration for the service. - ks\_endpoints: The image that will perform keystone endpoint registration for the service. - pull\_policy: The image pull policy, one of "Always", "IfNotPresent", and "Never" which will be used by all containers in the chart. An illustrative example of an ``images:`` section taken from the heat chart: :: images: tags: bootstrap: docker.io/openstackhelm/heat:ocata db_init: docker.io/openstackhelm/heat:ocata db_sync: docker.io/kolla/ubuntu-source-heat-api:ocata db_drop: docker.io/openstackhelm/heat:ocata ks_user: docker.io/openstackhelm/heat:ocata ks_service: docker.io/openstackhelm/heat:ocata ks_endpoints: docker.io/openstackhelm/heat:ocata api: docker.io/kolla/ubuntu-source-heat-api:ocata cfn: docker.io/kolla/ubuntu-source-heat-api:ocata engine: docker.io/openstackhelm/heat:ocata dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal pull_policy: "IfNotPresent" The OpenStack-Helm project today uses a mix of Docker images from Stackanetes and Kolla, but will likely standardize on a default set of images for all charts without any reliance on image-specific utilities. ================================================ FILE: doc/source/devref/index.rst ================================================ Developer References ==================== Contents: .. toctree:: :maxdepth: 2 endpoints images networking oslo-config pod-disruption-budgets upgrades fluent-logging node-and-label-specific-configurations ================================================ FILE: doc/source/devref/networking.rst ================================================ ========== Networking ========== Currently OpenStack-Helm supports OpenVSwitch and LinuxBridge as a network virtualization engines. In order to support many possible backends (SDNs), modular architecture of Neutron chart was developed. OpenStack-Helm can support every SDN solution that has Neutron plugin, either core_plugin or mechanism_driver. The Neutron reference architecture provides mechanism_drivers :code:`OpenVSwitch` (OVS) and :code:`linuxbridge` (LB) with ML2 :code:`core_plugin` framework. Other networking services provided by Neutron are: #. L3 routing - creation of routers #. DHCP - auto-assign IP address and DNS info #. Metadata - Provide proxy for Nova metadata service Introducing a new SDN solution should consider how the above services are provided. It maybe required to disable built-in Neutron functionality. Neutron architecture -------------------- Neutron chart includes the following services: neutron-server ~~~~~~~~~~~~~~ neutron-server is serving the networking REST API for operator and other OpenStack services usage. The internals of Neutron are highly flexible, providing plugin mechanisms for all networking services exposed. The consistent API is exposed to the user, but the internal implementation is up to the chosen SDN. Typical networking API request is an operation of create/update/delete: * network * subnet * port Neutron-server service is scheduled on nodes with ``openstack-control-plane=enabled`` label. neutron-rpc-server ~~~~~~~~~~~~~~~~~~ neutron-rpc-server is serving the networking PRC backend for neutron API services. The internals of Neutron are highly flexible, providing plugin mechanisms for all networking services exposed. The consistent API is exposed to the user, but the internal implementation is up to the chosen SDN. Typical networking API request is an operation of create/update/delete: * network * subnet * port To use other Neutron reference architecture types of SDN, these options should be configured in :code:`neutron.conf`: .. code-block:: ini [DEFAULT] ... # core_plugin - plugin responsible for L2 connectivity and IP address # assignments. # ML2 (Modular Layer 2) is the core plugin provided by Neutron ref arch # If other SDN implements its own logic for L2, it should replace the # ml2 here core_plugin = ml2 # service_plugins - a list of extra services exposed by Neutron API. # Example: router, qos, trunk, metering. # If other SDN implement L3 or other services, it should be configured # here service_plugins = router All of the above configs are endpoints or path to the specific class implementing the interface. You can see the endpoints to class mapping in `setup.cfg `_. If the SDN of your choice is using the ML2 core plugin, then the extra options in ``neutron/ml2/plugins/ml2_conf.ini`` should be configured: .. code-block:: ini [ml2] # type_drivers - layer 2 technologies that ML2 plugin supports. # Those are local,flat,vlan,gre,vxlan,geneve type_drivers = flat,vlan,vxlan # mech_drivers - implementation of above L2 technologies. This option is # pointing to the engines like linux bridge or OpenVSwitch in ref arch. # This is the place where SDN implementing ML2 driver should be configured mech_drivers = openvswitch, l2population SDNs implementing ML2 driver can add extra/plugin-specific configuration options in ``neutron/ml2/plugins/ml2_conf.ini``. Or define its own ``ml2_conf_.ini`` file where configs specific to the SDN would be placed. The above configuration options are handled by ``neutron/values.yaml``: .. code-block:: yaml conf: neutron: DEFAULT: ... # core_plugin can be: ml2, calico core_plugin: ml2 # service_plugin can be: router, empty for calico, # networking_ovn.l3.l3_ovn.OVNL3RouterPlugin for OVN service_plugins: router plugins: ml2_conf: ml2: # mechnism_drivers can be: openvswitch, linuxbridge, ovn mechanism_drivers: openvswitch,l2population type_drivers: flat,vlan,vxlan Neutron-rpc-server service is scheduled on nodes with ``openstack-control-plane=enabled`` label. neutron-dhcp-agent ~~~~~~~~~~~~~~~~~~ DHCP agent is running dnsmasq process which is serving the IP assignment and DNS info. DHCP agent is dependent on the L2 agent wiring the interface. So one should be aware that when changing the L2 agent, it also needs to be changed in the DHCP agent. The configuration of the DHCP agent includes option ``interface_driver``, which will instruct how the tap interface created for serving the request should be wired. .. code-block:: yaml conf: dhcp_agent: DEFAULT: # we can define here, which driver we are using: # openvswitch or linuxbridge interface_driver: openvswitch Another place where the DHCP agent is dependent on L2 agent is the dependency for the L2 agent daemonset: .. code-block:: yaml dependencies: dynamic: targeted: openvswitch: dhcp: pod: # this should be set to corresponding neutron L2 agent - requireSameNode: true labels: application: neutron component: neutron-ovs-agent There is also a need for DHCP agent to pass ovs agent config file (in :code:`neutron/templates/bin/_neutron-dhcp-agent.sh.tpl`): .. code-block:: bash exec neutron-dhcp-agent \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/dhcp_agent.ini \ --config-file /etc/neutron/metadata_agent.ini \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini {{- if ( has "openvswitch" .Values.network.backend ) }} \ --config-file /etc/neutron/plugins/ml2/openvswitch_agent.ini {{- end }} This requirement is OVS specific, the ``ovsdb_connection`` string is defined in ``openvswitch_agent.ini`` file, specifying how DHCP agent can connect to ovs. When using other SDNs, running the DHCP agent may not be required. When the SDN solution is addressing the IP assignments in another way, neutron's DHCP agent should be disabled. neutron-dhcp-agent service is scheduled to run on nodes with the label ``openstack-control-plane=enabled``. neutron-l3-agent ~~~~~~~~~~~~~~~~ L3 agent is serving the routing capabilities for Neutron networks. It is also dependent on the L2 agent wiring the tap interface for the routers. All dependencies described in neutron-dhcp-agent are valid here. If the SDN implements its own version of L3 networking, neutron-l3-agent should not be started. neutron-l3-agent service is scheduled to run on nodes with the label ``openstack-control-plane=enabled``. neutron-metadata-agent ~~~~~~~~~~~~~~~~~~~~~~ Metadata-agent is a proxy to nova-metadata service. This one provides information about public IP, hostname, ssh keys, and any tenant specific information. The same dependencies apply for metadata as it is for DHCP and L3 agents. Other SDNs may require to force the config driver in nova, since the metadata service is not exposed by it. neutron-metadata-agent service is scheduled to run on nodes with the label ``openstack-control-plane=enabled``. Configuring network plugin -------------------------- To be able to configure multiple networking plugins inside of OpenStack-Helm, a new configuration option is added: .. code-block:: yaml network: # provide what type of network wiring will be used # possible options: openvswitch, linuxbridge, sriov backend: - openvswitch This option will allow to configure the Neutron services in proper way, by checking what is the actual backed set in :code:`neutron/values.yaml`. In order to meet modularity criteria of Neutron chart, section ``manifests`` in :code:`neutron/values.yaml` contains boolean values describing which Neutron's Kubernetes resources should be deployed: .. code-block:: yaml manifests: configmap_bin: true configmap_etc: true daemonset_dhcp_agent: true daemonset_l3_agent: true daemonset_lb_agent: false daemonset_metadata_agent: true daemonset_ovs_agent: true daemonset_sriov_agent: true deployment_server: true deployment_rpc_server: true ingress_server: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pdb_server: true pod_rally_test: true secret_db: true secret_keystone: true secret_rabbitmq: true service_ingress_server: true service_server: true If :code:`.Values.manifests.daemonset_ovs_agent` will be set to false, neutron ovs agent would not be launched. In that matter, other type of L2 or L3 agent on compute node can be run. To enable new SDN solution, there should be separate chart created, which would handle the deployment of service, setting up the database and any related networking functionality that SDN is providing. OpenVSwitch ~~~~~~~~~~~ The ovs set of daemonsets are running on the node labeled ``openvswitch=enabled``. This includes the compute and controller/network nodes. For more flexibility, OpenVSwitch as a tool was split out of Neutron chart, and put in separate chart dedicated OpenVSwitch. Neutron OVS agent remains in Neutron chart. Splitting out the OpenVSwitch creates possibilities to use it with different SDNs, adjusting the configuration accordingly. neutron-ovs-agent +++++++++++++++++ As part of Neutron chart, this daemonset is running Neutron OVS agent. It is dependent on having :code:`openvswitch-db` and :code:`openvswitch-vswitchd` deployed and ready. Since its the default choice of the networking backend, all configuration is in place in ``neutron/values.yaml``. :code:`neutron-ovs-agent` should not be deployed when another SDN is used in ``network.backend``. Script in :code:`neutron/templates/bin/_neutron-openvswitch-agent-init.sh.tpl` is responsible for determining the tunnel interface and its IP for later usage by :code:`neutron-ovs-agent`. The IP is set in init container and shared between init container and main container with :code:`neutron-ovs-agent` via file :code:`/tmp/pod-shared/ml2-local-ip.ini`. Configuration of OVS bridges can be done via ``neutron/templates/bin/_neutron-openvswitch-agent-init.sh.tpl``. The script is configuring the external network bridge and sets up any bridge mappings defined in :code:`conf.auto_bridge_add`. These values should align with :code:`conf.plugins.openvswitch_agent.ovs.bridge_mappings`. openvswitch-db and openvswitch-vswitchd +++++++++++++++++++++++++++++++++++++++ This runs the OVS tool and database. OpenVSwitch chart is not Neutron specific, it may be used with other technologies that are leveraging the OVS technology, such as OVN. A detail worth mentioning is that ovs is configured to use sockets, rather than the default loopback mechanism. .. code-block:: bash exec /usr/sbin/ovs-vswitchd unix:${OVS_SOCKET} \ -vconsole:emer \ -vconsole:err \ -vconsole:info \ --pidfile=${OVS_PID} \ --mlockall Linuxbridge ~~~~~~~~~~~ Linuxbridge is the second type of Neutron reference architecture L2 agent. It is running on nodes labeled ``linuxbridge=enabled``. As mentioned before, all nodes that are requiring the L2 services need to be labeled with linuxbridge. This includes both the compute and controller/network nodes. It is not possible to label the same node with both openvswitch and linuxbridge (or any other network virtualization technology) at the same time. neutron-lb-agent ++++++++++++++++ This daemonset includes the linuxbridge Neutron agent with bridge-utils and ebtables utilities installed. This is all that is needed, since linuxbridge uses native kernel libraries. :code:`neutron/templates/bin/_neutron-linuxbridge-agent-init.sh.tpl` is configuring the tunnel IP, external bridge and all bridge mappings defined in config. It is done in init container, and the IP for tunneling is shared using file :code:`/tmp/pod-shared/ml2-local-ip.ini` with main linuxbridge container. In order to use linuxbridge in your OpenStack-Helm deployment, you need to label the compute and controller/network nodes with ``linuxbridge=enabled`` and use this ``neutron/values.yaml`` override: .. code-block:: yaml network: backend: linuxbridge dependencies: dynamic: targeted: linuxbridge: dhcp: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent l3: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent metadata: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent lb_agent: pod: null conf: neutron: DEFAULT interface_driver: linuxbridge dhcp_agent: DEFAULT: interface_driver: linuxbridge l3_agent: DEFAULT: interface_driver: linuxbridge Other SDNs ~~~~~~~~~~ In order to add support for more SDNs, these steps need to be performed: #. Configure neutron-server with SDN specific core_plugin/mechanism_drivers. #. If required, add new networking agent label type. #. Specify if new SDN would like to use existing services from Neutron: L3, DHCP, metadata. #. Create separate chart with new SDN deployment method. Nova config dependency ~~~~~~~~~~~~~~~~~~~~~~ Whenever we change the L2 agent, it should be reflected in ``nova/values.yaml`` in dependency resolution for nova-compute. ================================================ FILE: doc/source/devref/node-and-label-specific-configurations.rst ================================================ Node and node label specific daemonset configurations ===================================================== A typical Helm daemonset may leverage a secret to store configuration data. However, there are cases where the same secret document can't be used for the entire daemonset, because there are node-specific differences. To address this use-case, the ``helm-toolkit.utils.daemonset_overrides`` template was added in helm-toolkit. This was created with the intention that it should be straightforward to convert (wrap) a pre-existing daemonset with the functionality to override secret parameters on a per-node or per-nodelabel basis. Adapting your daemonset to support node/nodelabel overrides ----------------------------------------------------------- Consider the following (simplified) secret and daemonset pairing example: .. code-block:: yaml # Simplified secret definition # =============================== --- apiVersion: v1 kind: Secret # Note ref to $secretName for dynamically generated secrets metadata: name: mychart-etc data: myConf: {{ include "helm-toolkit.utils.template" | b64enc }} # Simplified daemonset definition # =============================== --- apiVersion: apps/v1 kind: DaemonSet metadata: name: mychart-name spec: template: spec: containers: - name: my-container volumes: - name: mychart-etc secret: name: mychart-etc defaultMode: 0444 Assume the chart name is ``mychart``. Now we can wrap the existing YAML to make it support node and nodelabel overrides, with minimal changes to the existing YAML (note where $secretName has been substituted): .. code-block:: yaml # Simplified secret definition needed for node/nodelabel overrides # ------------------------------------------------------------------- # Wrap secret definition {{- define "mychart.secret.etc" }} {{- $secretName := index . 0 }} {{- $envAll := index . 1 }} # Set to the same env context as was available to the caller, so we can # access any env data needed to build the template (e.g., envAll.Values...) {{- with $envAll }} --- apiVersion: v1 kind: Secret # Note ref to $secretName for dynamically generated secrets metadata: name: {{ $secretName }} data: myConf: {{ include "helm-toolkit.utils.template" | b64enc }} {{- end }} {{- end }} # Simplified daemonset definition needed for node/nodelabel overrides # ------------------------------------------------------------------- # Wrap daemonset definition {{- define "mychart.daemonset" }} {{- $daemonset := index . 0 }} {{- $secretName := index . 1 }} {{- $envAll := index . 2 }} # Set to the same env context as was available to the caller, so we can # access any env data needed to build the template (e.g., envAll.Values...) {{- with $envAll }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: {{ $daemonset }} spec: template: spec: containers: - name: {{ $daemonset }} volumes: # Note refs to $secretName for dynamically generated secrets - name: {{ $secretName }} secret: name: {{ $secretName }} defaultMode: 0444 {{- end }} {{- end }} # Desired daemonset name/prefix that helm will register with kubernetes # Note that this needs to be a valid dns-1123 name for a k8s resource {{- $daemonset := "mydaemonset" }} # Desired secret name/prefix that helm will register with kubernetes # Note that this needs to be a valid dns-1123 name for a k8s resource {{- $secretName := "mychart-etc" }} # Generate the daemonset YAML with a matching/consistent secretName (so # daemonset_overrides knows which volumes to dynamically substitute with the # auto-generated secrets). You may include in this list any other vars # which you need to reference or substitute into the daemonset YAML above. {{- $daemonset_yaml := list $secretName . | include "mychart.daemonset" | toString | fromYaml }} # Namespace to the secret definition which will be used/manipulated {{- $secret_include := "mychart.secret.etc" }} # Pass all these elements to daemonset_overrides to generate secret/daemonset # pairings for each set of overrides (plus one with no overrides) {{- list $daemonset $daemonset_yaml $secret_include $secretName . | include "helm-toolkit.utils.daemonset_overrides" }} Your daemonset should now support node and nodelabl level overrides. (Note that you will also need your chart to have helm-toolkit listed as a dependency.) Implementation details of node/nodelabel overrides -------------------------------------------------- Instead of having one daemonset with one monolithic secret, this helm-toolkit feature permits a common daemonset and secret template, from which daemonset and secret pairings are auto-generated. It supports establishing value overrides for nodes with specific label value pairs and for targeting nodes with specific hostnames and hostlabels. The overridden configuration is merged with the normal config data, with the override data taking precedence. The chart will then generate one daemonset for each host and label override, in addition to a default daemonset for which no overrides are applied. Each daemonset generated will also exclude from its scheduling criteria all other hosts and labels defined in other overrides for the same daemonset, to ensure that there is no overlap of daemonsets (i.e., one and only one daemonset of a given type for each node). For example, if you have some special conf setting that should be applied to ``host1.fqdn``, and another special conf setting that should be applied to nodes labeled with ``someNodeLabel``, then three secret/daemonset pairs will be generated and registered with kubernetes: one for ``host1.fqdn``, one for ``someNodeLabel``, and one for ``default``. The order of precedence for matches is FQDN, node label, and then default. If a node matches both a FQDN and a nodelabel, then only the FQDN override is applied. Pay special attention to adding FQDN overrides for nodes that match a nodelabel override, as you would need to duplicate the nodelabel overrides for that node in the FQDN overrides for them to still apply. If there is no matching FQDN and no matching nodelabel, then the default daemonset/secret (with no overrides applied) is used. If a node matches more than one nodelabel, only the last matching nodelabel will apply (last in terms of the order the overrides are defined in the YAML). Exercising node/nodelabel overrides ----------------------------------- The following example demonstrates how to exercise the node/nodelabel overrides: .. code-block:: yaml data: values: conf: mychart: foo: 1 # "overrides" keyword to invoke override behavior overrides: # To match these overrides to the right daemonset, the following key # needs to follow the pattern: # Chart.Name + '_' + $daemonset # where $daemonset is the value set for $daemonset in the daemonset # config above. mychart_mydaemonset: # labels dict contains a list of labels which overrides apply to. Dict may be excluded # if there are no labels to override. # Note - if a host satisfies more than one label in this list, then whichever matching # label is furtherest down on the list will be the one applied to the node. E.g., if # a host matched both label criteria below, then the overrides for "another_label" # would be applied. labels: # node label key and values to match against to apply these config overrides. # The values are ORed, so the daemonset will spawn to all nodes to node_type # set to "foo" and to all nodes with node_type set to "bar". - label: key: node_type values: - "foo" - "bar" # The setting overrides that will be applied for hosts with this host label conf: mychart: foo: 2 # another label/key to match against to apply different overrides - label: key: another_label values: - "another_value" # The setting overrides that will be applied for hosts with this host label conf: mychart: foo: 3 # hosts dict contains a list of hosts which overrides apply to. Dict may be excluded # if there are no hosts to override. hosts: # FQDN of the host to override settings on - name: superhost # The setting overrides that will be applied for this host conf: mychart: foo: 4 # FQDN of another host to override settings on - name: superhost2 # The setting overrides that will be applied for this host conf: mychart: foo: 5 Nova vcpu example ------------------ Some nodes may have a different vcpu_pin_set in nova.conf due to differences in CPU hardware. To address this, we can specify overrides in the values fed to the chart. Ex: .. code-block:: yaml conf: nova: DEFAULT: vcpu_pin_set: "0-31" cpu_allocation_ratio: 3.0 overrides: nova_compute: labels: - label: key: compute-type values: - "dpdk" - "sriov" conf: nova: DEFAULT: vcpu_pin_set: "0-15" - label: key: another-label values: - "another-value" conf: nova: DEFAULT: vcpu_pin_set: "16-31" hosts: - name: host1.fqdn conf: nova: DEFAULT: vcpu_pin_set: "8-15" - name: host2.fqdn conf: nova: DEFAULT: vcpu_pin_set: "16-23" Note that only one set of overrides is applied per node, such that: 1. Host overrides supercede label overrides 2. The farther down the list the label appears, the greater precedence it has. e.g., "another-label" overrides will apply to a node containing both labels. Also note that other non-overridden values are inherited by hosts and labels with overrides. The following shows a set of example hosts and the values fed into each: 1. ``host1.fqdn`` with labels ``compute-type: dpdk, sriov`` and ``another-label: another-value``: .. code-block:: yaml conf: nova: DEFAULT: vcpu_pin_set: "8-15" cpu_allocation_ratio: 3.0 2. ``host2.fqdn`` with labels ``compute-type: dpdk, sriov`` and ``another-label: another-value``: .. code-block:: yaml conf: nova: DEFAULT: vcpu_pin_set: "16-23" cpu_allocation_ratio: 3.0 3. ``host3.fqdn`` with labels ``compute-type: dpdk, sriov`` and ``another-label: another-value``: .. code-block:: yaml conf: nova: DEFAULT: vcpu_pin_set: "16-31" cpu_allocation_ratio: 3.0 4. ``host4.fqdn`` with labels ``compute-type: dpdk, sriov``: .. code-block:: yaml conf: nova: DEFAULT: vcpu_pin_set: "0-15" cpu_allocation_ratio: 3.0 5. ``host5.fqdn`` with no labels: .. code-block:: yaml conf: nova: DEFAULT: vcpu_pin_set: "0-31" cpu_allocation_ratio: 3.0 ================================================ FILE: doc/source/devref/oslo-config.rst ================================================ OSLO-Config Values ------------------ OpenStack-Helm generates oslo-config compatible formatted configuration files for services dynamically from values specified in a yaml tree. This allows operators to control any and all aspects of an OpenStack services configuration. An example snippet for an imaginary Keystone configuration is described here: :: conf: keystone: DEFAULT: # Keys at this level are used for section headings max_token_size: 255 token: provider: fernet fernet_tokens: key_repository: /etc/keystone/fernet-keys/ credential: key_repository: /etc/keystone/credential-keys/ database: max_retries: -1 cache: enabled: true backend: dogpile.cache.memcached oslo_messaging_notifications: driver: # An example of a multistring option's syntax type: multistring values: - messagingv2 - log security_compliance: password_expires_ignore_user_ids: # Values in a list will be converted to a comma separated key - "123" - "456" This will be consumed by the templated ``configmap-etc.yaml`` manifest to produce the following config file: :: --- # Source: keystone/templates/configmap-etc.yaml apiVersion: v1 kind: ConfigMap metadata: name: keystone-etc data: keystone.conf: | [DEFAULT] max_token_size = 255 transport_url = rabbit://keystone:password@rabbitmq.default.svc.cluster.local:5672/openstack [cache] backend = dogpile.cache.memcached enabled = true memcache_servers = memcached.default.svc.cluster.local:11211 [credential] key_repository = /etc/keystone/credential-keys/ [database] connection = mysql+pymysql://keystone:password@mariadb.default.svc.cluster.local:3306/keystone max_retries = -1 [fernet_tokens] key_repository = /etc/keystone/fernet-keys/ [oslo_messaging_notifications] driver = messagingv2 driver = log [security_compliance] password_expires_ignore_user_ids = 123,456 [token] provider = fernet Note that some additional values have been injected into the config file, this is performed via statements in the configmap template, which also calls the ``helm-toolkit.utils.to_oslo_conf`` to convert the yaml to the required layout: :: {{- if empty .Values.conf.keystone.database.connection -}} {{- $_ := tuple "oslo_db" "internal" "user" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set .Values.conf.keystone.database "connection" -}} {{- end -}} {{- if empty .Values.conf.keystone.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "user" "amqp" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set .Values.conf.keystone.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.keystone.cache.memcache_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.keystone.cache "memcache_servers" -}} {{- end -}} --- apiVersion: v1 kind: ConfigMap metadata: name: keystone-etc data: keystone.conf: | {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.keystone | indent 4 }} {{- end }} ================================================ FILE: doc/source/devref/pod-disruption-budgets.rst ================================================ Pod Disruption Budgets ---------------------- OpenStack-Helm leverages PodDisruptionBudgets to enforce quotas that ensure that a certain number of replicas of a pod are available at any given time. This is particularly important in the case when a Kubernetes node needs to be drained. These quotas are configurable by modifying the ``minAvailable`` field within each PodDisruptionBudget manifest, which is conveniently mapped to a templated variable inside the ``values.yaml`` file. The ``min_available`` within each service's ``values.yaml`` file can be represented by either a whole number, such as ``1``, or a percentage, such as ``80%``. For example, when deploying 5 replicas of a pod (such as keystone-api), using ``min_available: 3`` would enforce policy to ensure at least 3 replicas were running, whereas using ``min_available: 80%`` would ensure that 4 replicas of that pod are running. **Note:** The values defined in a PodDisruptionBudget may conflict with other values that have been provided if an operator chooses to leverage Rolling Updates for deployments. In the case where an operator defines a ``maxUnavailable`` and ``maxSurge`` within an update strategy that is higher than a ``minAvailable`` within a pod disruption budget, a scenario may occur where pods fail to be evicted from a deployment. ================================================ FILE: doc/source/devref/upgrades.rst ================================================ Upgrades and Reconfiguration ---------------------------- The OpenStack-Helm project assumes all upgrades will be done through Helm. This includes handling several different resource types. First, changes to the Helm chart templates themselves are handled. Second, all of the resources layered on top of the container image, such as ``ConfigMaps`` which includes both scripts and configuration files, are updated during an upgrade. Finally, any image references will result in rolling updates of containers, replacing them with the updating image. As Helm stands today, several issues exist when you update images within charts that might have been used by jobs that already ran to completion or are still in flight. An example of where this behavior would be desirable is when an updated db\_sync image has updated to point from one openstack release to another. In this case, the operator will likely want a db\_sync job, which was already run and completed during site installation, to run again with the updated image to bring the schema inline with the Newton release. The OpenStack-Helm project also implements annotations across all chart configmaps so that changing resources inside containers, such as configuration files, triggers a Kubernetes rolling update. This means that those resources can be updated without deleting and redeploying the service and can be treated like any other upgrade, such as a container image change. Note: Rolling update values can conflict with values defined in each service's PodDisruptionBudget. See `here `_ for more information. This is accomplished with the following annotation: :: ... annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} The ``hash`` function defined in the ``helm-toolkit`` chart ensures that any change to any file referenced by configmap-bin.yaml or configmap-etc.yaml results in a new hash, which will then trigger a rolling update. All ``Deployment`` chart components are outfitted by default with rolling update strategies: :: # Source: keystone/templates/deployment-api.yaml spec: replicas: {{ .Values.pod.replicas.api }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 } In ``values.yaml`` in each chart, the same defaults are supplied in every chart, which allows the operator to override at upgrade or deployment time. :: pod: lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 ================================================ FILE: doc/source/index.rst ================================================ Welcome to OpenStack-Helm's documentation! ========================================== Contents: .. toctree:: :maxdepth: 2 readme install/index chart/index devref/index testing/index monitoring/index logging/index upgrade/index troubleshooting/index specs/index Indices and Tables ================== * :ref:`genindex` * :ref:`search` ================================================ FILE: doc/source/install/before_starting.rst ================================================ Before starting =============== The OpenStack-Helm charts are published in the `openstack-helm`_ helm repository. Let's enable it: .. code-block:: bash helm repo add openstack-helm https://tarballs.opendev.org/openstack/openstack-helm The OpenStack-Helm `plugin`_ provides some helper commands used later on. So, let's install it: .. code-block:: bash helm plugin install https://opendev.org/openstack/openstack-helm-plugin .. _openstack-helm: https://tarballs.opendev.org/openstack/openstack-helm .. _plugin: https://opendev.org/openstack/openstack-helm-plugin.git ================================================ FILE: doc/source/install/index.rst ================================================ Installation ============ Here are sections that describe how to install OpenStack using OpenStack-Helm: .. toctree:: :maxdepth: 2 before_starting kubernetes prerequisites openstack ================================================ FILE: doc/source/install/kubernetes.rst ================================================ Kubernetes ========== OpenStack-Helm provides charts that can be deployed on any Kubernetes cluster if it meets the version :doc:`requirements `. However, deploying the Kubernetes cluster itself is beyond the scope of OpenStack-Helm. You can use any Kubernetes deployment tool for this purpose. In this guide, we detail how to set up a Kubernetes cluster using Kubeadm and Ansible. While not production-ready, this cluster is ideal as a starting point for lab or proof-of-concept environments. All OpenStack projects test their code through an infrastructure managed by the CI tool, Zuul, which executes Ansible playbooks on one or more test nodes. Therefore, we employ Ansible roles/playbooks to install required packages, deploy Kubernetes, and then execute tests on it. To establish a test environment, the Ansible role `deploy-env`_ is employed. This role deploys a basic single/multi-node Kubernetes cluster, used to prove the functionality of commonly used deployment configurations. The role is compatible with Ubuntu Focal and Ubuntu Jammy distributions. .. note:: The role `deploy-env`_ is not idempotent and assumed to be applied to a clean environment. Clone roles git repositories ---------------------------- Before proceeding with the steps outlined in the following sections, it is imperative that you clone the git repositories containing the required Ansible roles. .. code-block:: bash mkdir ~/osh cd ~/osh git clone https://opendev.org/openstack/openstack-helm.git git clone https://opendev.org/zuul/zuul-jobs.git Install Ansible --------------- .. code-block:: bash pip install ansible Set roles lookup path --------------------- Now let's set the environment variable ``ANSIBLE_ROLES_PATH`` which specifies where Ansible will lookup roles .. code-block:: bash export ANSIBLE_ROLES_PATH=~/osh/openstack-helm/roles:~/osh/zuul-jobs/roles To avoid setting it every time when you start a new terminal instance you can define this in the Ansible configuration file. Please see the Ansible documentation. Prepare inventory ----------------- The example below assumes that there are four nodes which must be available via SSH using the public key authentication and a ssh user (let say ``ubuntu``) must have passwordless sudo on the nodes. .. code-block:: bash cat > ~/osh/inventory.yaml < ~/osh/deploy-env.yaml < tee ${OVERRIDES_DIR}/neutron/neutron_simple.yaml << EOF conf: neutron: DEFAULT: l3_ha: False max_l3_agents_per_router: 1 # will be attached to the br-ex bridge. # The IP assigned to the interface will be moved to the bridge. auto_bridge_add: br-ex: ${PROVIDER_INTERFACE} plugins: ml2_conf: ml2_type_flat: flat_networks: public openvswitch_agent: ovs: bridge_mappings: public:br-ex EOF helm upgrade --install neutron openstack-helm/neutron \ --namespace=openstack \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c neutron neutron_simple ${FEATURES}) helm osh wait-for-pods openstack Horizon ~~~~~~~ OpenStack Horizon is the web application that is intended to provide a graphic user interface to Openstack services. Let's deploy it: .. code-block:: bash helm upgrade --install horizon openstack-helm/horizon \ --namespace=openstack \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c horizon ${FEATURES}) helm osh wait-for-pods openstack OpenStack client ---------------- Installing the OpenStack client on the developer's machine is a vital step. The easiest way to install the OpenStack client is to create a Python virtual environment and install the client using ``pip``. .. code-block:: bash python3 -m venv ~/openstack-client source ~/openstack-client/bin/activate pip install python-openstackclient Now let's prepare the OpenStack client configuration file: .. code-block:: bash mkdir -p ~/.config/openstack tee ~/.config/openstack/clouds.yaml << EOF clouds: openstack_helm: region_name: RegionOne identity_api_version: 3 auth: username: 'admin' password: 'password' project_name: 'admin' project_domain_name: 'default' user_domain_name: 'default' auth_url: 'http://keystone.openstack.svc.cluster.local/v3' That is it! Now you can use the OpenStack client. Try to run this: .. code-block:: bash openstack --os-cloud openstack_helm endpoint list .. note:: In some cases it is more convenient to use the OpenStack client inside a Docker container. OpenStack-Helm provides the `quay.io/airshipit/openstack-client`_ image. The below is an example of how to use it. .. code-block:: bash docker run -it --rm --network host \ -v ~/.config/openstack/clouds.yaml:/etc/openstack/clouds.yaml \ -e OS_CLOUD=openstack_helm \ quay.io/airshipit/openstack-client:${OPENSTACK_RELEASE}-ubuntu_jammy \ openstack endpoint list Remember that the container file system is ephemeral and is destroyed when you stop the container. So if you would like to use the Openstack client capabilities interfacing with the file system then you have to mount a directory from the host file system where necessary files are located. For example, this is useful when you create a key pair and save the private key in a file which is then used for ssh access to VMs. Or it could be Heat templates which you prepare in advance and then use with Openstack client. For convenience, you can create an executable entry point that runs the Openstack client in a Docker container. See for example `setup-client.sh`_. .. _setup-client.sh: https://opendev.org/openstack/openstack-helm/src/branch/master/tools/deployment/common/setup-client.sh .. _quay.io/airshipit/openstack-client: https://quay.io/repository/airshipit/openstack-client?tab=tags&tag=latest Other Openstack components (optional) ------------------------------------- Barbican ~~~~~~~~ OpenStack Barbican is a component within the OpenStack ecosystem that provides secure storage, provisioning, and management of secrets, such as encryption keys, certificates, and passwords. If you want other OpenStack services to use Barbican for secret management, you'll need to reconfigure those services to integrate with Barbican. Each OpenStack service has its own configuration settings that need to be updated. .. code-block:: bash helm upgrade --install barbican openstack-helm/barbican \ --namespace=openstack \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c barbican ${FEATURES}) helm osh wait-for-pods openstack Tacker ~~~~~~ Tacker is an OpenStack service for NFV Orchestration with a general purpose VNF Manager to deploy and operate Virtual Network Functions (VNFs) and Network Services on an NFV Platform. It is based on ETSI MANO Architectural Framework and provides OpenStack's NFV Orchestration API. .. note:: Barbican must be installed before Tacker, as it is a necessary component for Tacker's installation. To deploy the OpenStack Tacker, use the following: .. code-block:: bash helm upgrade --install tacker openstack-helm/tacker \ --namespace=openstack \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c tacker ${FEATURES}) helm osh wait-for-pods openstack For comprehensive instructions on installing Tacker using Openstack Helm, please refer `Install Tacker via Openstack Helm`_. .. _Install Tacker via Openstack Helm: https://docs.openstack.org/tacker/latest/install/openstack_helm.html Trove ~~~~~ OpenStack Trove is the Database as a Service (DBaaS) component of the OpenStack cloud computing platform. It provides scalable and reliable cloud database services, allowing users to provision and manage database instances without the complexity of handling database administration tasks. Trove supports multiple database engines including MySQL, PostgreSQL, MongoDB, and others. To deploy the OpenStack Trove use the following .. code-block:: bash helm upgrade --install trove openstack-helm/trove \ --namespace=openstack \ --timeout=600s \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c trove ${FEATURES}) helm osh wait-for-pods openstack Blazar ~~~~~~ Blazar is the resource reservation service for OpenStack. It provides a way to reserve resources such as compute hosts, servers and floating IPs for future use. To deploy the Blazar service run the following: .. code-block:: bash helm upgrade --install blazar openstack-helm/blazar \ --namespace=openstack \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c blazar ${FEATURES}) helm osh wait-for-pods openstack Freezer ~~~~~~~ Freezer is a disaster recovery and backup-as-a-service component for OpenStack. It provides a way to back up various resources, such as virtual machine instances, databases, and file systems. It allows users to schedule backups, restore data, and manage the lifecycle of their backups to ensure data protection and business continuity within an OpenStack cloud. To deploy the OpenStack Freezer, use the following: .. code-block:: bash helm upgrade --install freezer openstack-helm/freezer \ --namespace=openstack \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c freezer ${FEATURES}) Zaqar ~~~~~ Zaqar is the messaging service for OpenStack. It provides a multi-tenant, RESTful and WebSocket-based message queue service that allows applications and services to communicate asynchronously. To deploy the Zaqar service use the following: .. code-block:: bash helm upgrade --install zaqar openstack-helm/zaqar \ --namespace=openstack \ $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c zaqar ${FEATURES}) helm osh wait-for-pods openstack ================================================ FILE: doc/source/install/prerequisites.rst ================================================ Kubernetes prerequisites ======================== Gateway API ----------- The `Kubernetes Gateway API`_ is the recommended way to expose OpenStack services externally. It provides an expressive and extensible routing model. We recommend using `Envoy Gateway`_ as the Gateway API implementation. Below we describe how we deploy the Gateway API and Envoy Gateway in the cluster on test clusters. First, install the Gateway API CRDs and `Envoy Gateway`_: .. code-block:: bash helm install eg oci://docker.io/envoyproxy/gateway-helm \ --version v1.7.0 \ --namespace envoy-gateway-system \ --create-namespace Next, create the ``EnvoyProxy`` custom resource, the ``Gateway``. The ``EnvoyProxy`` tells Envoy Gateway how to configure the data-plane pods and the ``LoadBalancer`` service (backed by MetalLB, see below). The ``Gateway`` defines the listener that accepts traffic. The gateway controller will automatically create a ``LoadBalancer`` service. .. code-block:: bash GATEWAY_IP= tee > /tmp/gatewayapi_envoy_default.yaml < /tmp/metallb_system_namespace.yaml < /tmp/metallb_ipaddresspool.yaml < /tmp/metallb_l2advertisement.yaml < /tmp/openstack_endpoint_service.yaml <.172-24-128-100.sslip.io`` Here is an example of how to set the ``host_fqdn_override`` for the Keystone chart: .. code-block:: yaml endpoints: identity: host_fqdn_override: public: host: "keystone.172-24-128-100.sslip.io" .. note:: In production environments you probably choose to use a different DNS domain for public OpenStack endpoints. This is easy to achieve by setting the necessary chart values. All Openstack-Helm charts values have the ``endpoints`` section where you can specify the ``host_fqdn_override``. In this case a chart will create additional ``Ingress`` resources to handle the external domain name and also the Keystone endpoint catalog will be updated. .. _sslip.io: https://sslip.io/ Ceph ---- Ceph is a highly scalable and fault-tolerant distributed storage system. It offers object storage, block storage, and file storage capabilities, making it a versatile solution for various storage needs. Kubernetes CSI (Container Storage Interface) allows storage providers like Ceph to implement their drivers, so that Kubernetes can use the CSI driver to provision and manage volumes which can be used by stateful applications deployed on top of Kubernetes to store their data. In the context of OpenStack running in Kubernetes, the Ceph is used as a storage backend for services like MariaDB, RabbitMQ and other services that require persistent storage. By default OpenStack-Helm stateful sets expect to find a storage class named **general**. At the same time, Ceph provides the RBD API, which applications can utilize directly to create and mount block devices distributed across the Ceph cluster. For example the OpenStack Cinder utilizes this Ceph capability to offer persistent block devices to virtual machines managed by the OpenStack Nova. The recommended way to manage Ceph on top of Kubernetes is by means of the `Rook`_ operator. The Rook project provides the Helm chart to deploy the Rook operator which extends the Kubernetes API adding CRDs that enable managing Ceph clusters via Kuberntes custom objects. There is also another Helm chart that facilitates deploying Ceph clusters using Rook custom resources. For details please refer to the `Rook`_ documentation and the `charts`_. .. note:: The following script `ceph-rook.sh`_ (recommended for testing only) can be used as an example of how to deploy the Rook Ceph operator and a Ceph cluster using the Rook `charts`_. Please note that the script places Ceph OSDs on loopback devices which is **not recommended** for production. The loopback devices must exist before using this script. Once the Ceph cluster is deployed, the next step is to enable using it for services depoyed by OpenStack-Helm charts. The ``ceph-adapter-rook`` chart provides the necessary functionality to do this. The chart will prepare Kubernetes secret resources containing Ceph client keys/configs that are later used to interface with the Ceph cluster. Here we assume the Ceph cluster is deployed in the ``ceph`` namespace. .. code-block:: bash helm upgrade --install ceph-adapter-rook openstack-helm/ceph-adapter-rook \ --namespace=openstack helm osh wait-for-pods openstack .. _Rook: https://rook.io/ .. _charts: https://rook.io/docs/rook/latest-release/Helm-Charts/helm-charts/ .. _ceph-rook.sh: https://opendev.org/openstack/openstack-helm/src/branch/master/tools/deployment/ceph/ceph-rook.sh Node labels ----------- Openstack-Helm charts rely on Kubernetes node labels to determine which nodes are suitable for running specific OpenStack components. The following sets labels on all the Kubernetes nodes in the cluster including control plane nodes but you can choose to label only a subset of nodes where you want to run OpenStack: .. code-block:: kubectl label --overwrite nodes --all openstack-control-plane=enabled kubectl label --overwrite nodes --all openstack-compute-node=enabled kubectl label --overwrite nodes --all openvswitch=enabled kubectl label --overwrite nodes --all linuxbridge=enabled .. note:: The control plane nodes are tainted by default to prevent scheduling of pods on them. You can untaint the control plane nodes using the following command: .. code-block:: bash kubectl taint nodes -l 'node-role.kubernetes.io/control-plane' node-role.kubernetes.io/control-plane- ================================================ FILE: doc/source/logging/elasticsearch.rst ================================================ Elasticsearch ============= The Elasticsearch chart in openstack-helm provides a distributed data store to index and analyze logs generated from the OpenStack-Helm services. The chart contains templates for: - Elasticsearch client nodes - Elasticsearch data nodes - Elasticsearch master nodes - An Elasticsearch exporter for providing cluster metrics to Prometheus - A cronjob for Elastic Curator to manage data indices Authentication -------------- The Elasticsearch deployment includes a sidecar container that runs an Apache reverse proxy to add authentication capabilities for Elasticsearch. The username and password are configured under the Elasticsearch entry in the endpoints section of the chart's values.yaml. The configuration for Apache can be found under the conf.httpd key, and uses a helm-toolkit function that allows for including gotpl entries in the template directly. This allows the use of other templates, like the endpoint lookup function templates, directly in the configuration for Apache. Elasticsearch Service Configuration ----------------------------------- The Elasticsearch service configuration file can be modified with a combination of pod environment variables and entries in the values.yaml file. Elasticsearch does not require much configuration out of the box, and the default values for these configuration settings are meant to provide a highly available cluster by default. The vital entries in this configuration file are: - path.data: The path at which to store the indexed data - path.repo: The location of any snapshot repositories to backup indexes - bootstrap.memory_lock: Ensures none of the JVM is swapped to disk - discovery.zen.minimum_master_nodes: Minimum required masters for the cluster The bootstrap.memory_lock entry ensures none of the JVM will be swapped to disk during execution, and setting this value to false will negatively affect the health of your Elasticsearch nodes. The discovery.zen.minimum_master_nodes flag registers the minimum number of masters required for your Elasticsearch cluster to register as healthy and functional. To read more about Elasticsearch's configuration file, please see the official documentation_. .. _documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/important-settings.html Elastic Curator --------------- The Elasticsearch chart contains a cronjob to run Elastic Curator at specified intervals to manage the lifecycle of your indices. Curator can perform: - Take and send a snapshot of your indexes to a specified snapshot repository - Delete indexes older than a specified length of time - Restore indexes with previous index snapshots - Reindex an index into a new or preexisting index The full list of supported Curator actions can be found in the actions_ section of the official Curator documentation. The list of options available for those actions can be found in the options_ section of the Curator documentation. .. _actions: https://www.elastic.co/guide/en/elasticsearch/client/curator/current/actions.html .. _options: https://www.elastic.co/guide/en/elasticsearch/client/curator/current/options.html Curator's configuration is handled via entries in Elasticsearch's values.yaml file and must be overridden to achieve your index lifecycle management needs. Please note that any unused field should be left blank, as an entry of "None" will result in an exception, as Curator will read it as a Python NoneType insead of a value of None. The section for Curator's service configuration can be found at: :: conf: curator: config: client: hosts: - elasticsearch-logging port: 9200 url_prefix: use_ssl: False certificate: client_cert: client_key: ssl_no_validate: False http_auth: timeout: 30 master_only: False logging: loglevel: INFO logfile: logformat: default blacklist: ['elasticsearch', 'urllib3'] Curator's actions are configured in the following section: :: conf: curator: action_file: actions: 1: action: delete_indices description: "Clean up ES by deleting old indices" options: timeout_override: continue_if_exception: False ignore_empty_list: True disable_action: True filters: - filtertype: age source: name direction: older timestring: '%Y.%m.%d' unit: days unit_count: 30 field: stats_result: epoch: exclude: False The Elasticsearch chart contains commented example actions for deleting and snapshotting indexes older 30 days. Please note these actions are provided as a reference and are disabled by default to avoid any unexpected behavior against your indexes. Elasticsearch Exporter ---------------------- The Elasticsearch chart contains templates for an exporter to provide metrics for Prometheus. These metrics provide insight into the performance and overall health of your Elasticsearch cluster. Please note monitoring for Elasticsearch is disabled by default, and must be enabled with the following override: :: monitoring: prometheus: enabled: true The Elasticsearch exporter uses the same service annotations as the other exporters, and no additional configuration is required for Prometheus to target the Elasticsearch exporter for scraping. The Elasticsearch exporter is configured with command line flags, and the flags' default values can be found under the following key in the values.yaml file: :: conf: prometheus_elasticsearch_exporter: es: all: true timeout: 20s The configuration keys configure the following behaviors: - es.all: Gather information from all nodes, not just the connecting node - es.timeout: Timeout for metrics queries More information about the Elasticsearch exporter can be found on the exporter's GitHub_ page. .. _GitHub: https://github.com/prometheus-community/elasticsearch_exporter Snapshot Repositories --------------------- Before Curator can store snapshots in a specified repository, Elasticsearch must register the configured repository. To achieve this, the Elasticsearch chart contains a job for registering an s3 snapshot repository backed by radosgateway. This job is disabled by default as the curator actions for snapshots are disabled by default. To enable the snapshot job, the conf.elasticsearch.snapshots.enabled flag must be set to true. The following configuration keys are relevant: - conf.elasticsearch.snapshots.enabled: Enable snapshot repositories - conf.elasticsearch.snapshots.bucket: Name of the RGW s3 bucket to use - conf.elasticsearch.snapshots.repositories: Name of repositories to create More information about Elasticsearch repositories can be found in the official Elasticsearch snapshot_ documentation: .. _snapshot: https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html#_repositories ================================================ FILE: doc/source/logging/fluent-logging.rst ================================================ Fluent-logging =============== The fluent-logging chart in openstack-helm provides the base for a centralized logging platform for OpenStack-Helm. The chart combines two services, Fluentbit and Fluentd, to gather logs generated by the services, filter on or add metadata to logged events, then forward them to Elasticsearch for indexing. Fluentbit --------- Fluentbit runs as a log-collecting component on each host in the cluster, and can be configured to target specific log locations on the host. The Fluentbit_ configuration schema can be found on the official Fluentbit website. .. _Fluentbit: http://fluentbit.io/documentation/0.12/configuration/schema.html Fluentbit provides a set of plug-ins for ingesting and filtering various log types. These plug-ins include: - Tail: Tails a defined file for logged events - Kube: Adds Kubernetes metadata to a logged event - Systemd: Provides ability to collect logs from the journald daemon - Syslog: Provides the ability to collect logs from a Unix socket (TCP or UDP) The complete list of plugins can be found in the configuration_ section of the Fluentbit documentation. .. _configuration: http://fluentbit.io/documentation/current/configuration/ Fluentbit uses parsers to turn unstructured log entries into structured entries to make processing and filtering events easier. The two formats supported are JSON maps and regular expressions. More information about Fluentbit's parsing abilities can be found in the parsers_ section of Fluentbit's documentation. .. _parsers: http://fluentbit.io/documentation/current/parser/ Fluentbit's service and parser configurations are defined via the values.yaml file, which allows for custom definitions of inputs, filters and outputs for your logging needs. Fluentbit's configuration can be found under the following key: :: conf: fluentbit: - service: header: service Flush: 1 Daemon: Off Log_Level: info Parsers_File: parsers.conf - containers_tail: header: input Name: tail Tag: kube.* Path: /var/log/containers/*.log Parser: docker DB: /var/log/flb_kube.db Mem_Buf_Limit: 5MB - kube_filter: header: filter Name: kubernetes Match: kube.* Merge_JSON_Log: On - fluentd_output: header: output Name: forward Match: "*" Host: ${FLUENTD_HOST} Port: ${FLUENTD_PORT} Fluentbit is configured by default to capture logs at the info log level. To change this, override the Log_Level key with the appropriate levels, which are documented in Fluentbit's configuration_. Fluentbit's parser configuration can be found under the following key: :: conf: parsers: - docker: header: parser Name: docker Format: json Time_Key: time Time_Format: "%Y-%m-%dT%H:%M:%S.%L" Time_Keep: On The values for the fluentbit and parsers keys are consumed by a fluent-logging helper template that produces the appropriate configurations for the relevant sections. Each list item (keys prefixed with a '-') represents a section in the configuration files, and the arbitrary name of the list item should represent a logical description of the section defined. The header key represents the type of definition (filter, input, output, service or parser), and the remaining entries will be rendered as space delimited configuration keys and values. For example, the definitions above would result in the following: :: [SERVICE] Daemon false Flush 1 Log_Level info Parsers_File parsers.conf [INPUT] DB /var/log/flb_kube.db Mem_Buf_Limit 5MB Name tail Parser docker Path /var/log/containers/*.log Tag kube.* [FILTER] Match kube.* Merge_JSON_Log true Name kubernetes [OUTPUT] Host ${FLUENTD_HOST} Match * Name forward Port ${FLUENTD_PORT} [PARSER] Format json Name docker Time_Format %Y-%m-%dT%H:%M:%S.%L Time_Keep true Time_Key time Fluentd ------- Fluentd runs as a forwarding service that receives event entries from Fluentbit and routes them to the appropriate destination. By default, Fluentd will route all entries received from Fluentbit to Elasticsearch for indexing. The Fluentd_ configuration schema can be found at the official Fluentd website. .. _Fluentd: https://docs.fluentd.org/v0.12/articles/config-file Fluentd's configuration is handled in the values.yaml file in fluent-logging. Similar to Fluentbit, configuration overrides provide flexibility in defining custom routes for tagged log events. The configuration can be found under the following key: :: conf: fluentd: - fluentbit_forward: header: source type: forward port: "#{ENV['FLUENTD_PORT']}" bind: 0.0.0.0 - elasticsearch: header: match type: elasticsearch expression: "**" include_tag_key: true host: "#{ENV['ELASTICSEARCH_HOST']}" port: "#{ENV['ELASTICSEARCH_PORT']}" logstash_format: true buffer_chunk_limit: 10M buffer_queue_limit: 32 flush_interval: "20" max_retry_wait: 300 disable_retry_limit: "" The values for the fluentd keys are consumed by a fluent-logging helper template that produces appropriate configurations for each directive desired. The list items (keys prefixed with a '-') represent sections in the configuration file, and the name of each list item should represent a logical description of the section defined. The header key represents the type of definition (name of the fluentd plug-in used), and the expression key is used when the plug-in requires a pattern to match against (example: matches on certain input patterns). The remaining entries will be rendered as space delimited configuration keys and values. For example, the definition above would result in the following: :: bind 0.0.0.0 port "#{ENV['FLUENTD_PORT']}" @type forward buffer_chunk_limit 10M buffer_queue_limit 32 disable_retry_limit flush_interval 20s host "#{ENV['ELASTICSEARCH_HOST']}" include_tag_key true logstash_format true max_retry_wait 300 port "#{ENV['ELASTICSEARCH_PORT']}" @type elasticsearch Some fluentd plug-ins require nested definitions. The fluentd helper template can handle these definitions with the following structure: :: conf: td_agent: - fluentbit_forward: header: source type: forward port: "#{ENV['FLUENTD_PORT']}" bind: 0.0.0.0 - log_transformer: header: filter type: record_transformer expression: "foo.bar" inner_def: - record_transformer: header: record hostname: my_host tag: my_tag In this example, the my_transformer list will generate a nested configuration entry in the log_transformer section. The nested definitions are handled by supplying a list as the value for an arbitrary key, and the list value will indicate the entry should be handled as a nested definition. The helper template will render the above example key/value pairs as the following: :: bind 0.0.0.0 port "#{ENV['FLUENTD_PORT']}" @type forward hostname my_host tag my_tag @type record_transformer Fluentd Exporter ---------------------- The fluent-logging chart contains templates for an exporter to provide metrics for Fluentd. These metrics provide insight into Fluentd's performance. Please note monitoring for Fluentd is disabled by default, and must be enabled with the following override: :: monitoring: prometheus: enabled: true The Fluentd exporter uses the same service annotations as the other exporters, and no additional configuration is required for Prometheus to target the Fluentd exporter for scraping. The Fluentd exporter is configured with command line flags, and the flags' default values can be found under the following key in the values.yaml file: :: conf: fluentd_exporter: log: format: "logger:stdout?json=true" level: "info" The configuration keys configure the following behaviors: - log.format: Define the logger used and format of the output - log.level: Log level for the exporter to use More information about the Fluentd exporter can be found on the exporter's GitHub_ page. .. _GitHub: https://github.com/V3ckt0r/fluentd_exporter ================================================ FILE: doc/source/logging/index.rst ================================================ OpenStack-Helm Logging ====================== Contents: .. toctree:: :maxdepth: 2 elasticsearch fluent-logging kibana ================================================ FILE: doc/source/logging/kibana.rst ================================================ Kibana ====== The Kibana chart in OpenStack-Helm Infra provides visualization for logs indexed into Elasticsearch. These visualizations provide the means to view logs captured from services deployed in cluster and targeted for collection by Fluentbit. Authentication -------------- The Kibana deployment includes a sidecar container that runs an Apache reverse proxy to add authentication capabilities for Kibana. The username and password are configured under the Kibana entry in the endpoints section of the chart's values.yaml. The configuration for Apache can be found under the conf.httpd key, and uses a helm-toolkit function that allows for including gotpl entries in the template directly. This allows the use of other templates, like the endpoint lookup function templates, directly in the configuration for Apache. Configuration ------------- Kibana's configuration is driven by the chart's values.yaml file. The configuration options are found under the following keys: :: conf: elasticsearch: pingTimeout: 1500 preserveHost: true requestTimeout: 30000 shardTimeout: 0 startupTimeout: 5000 i18n: defaultLocale: en kibana: defaultAppId: discover index: .kibana logging: quiet: false silent: false verbose: false ops: interval: 5000 server: host: localhost maxPayloadBytes: 1048576 port: 5601 ssl: enabled: false The case of the sub-keys is important as these values are injected into Kibana's configuration configmap with the toYaml function. More information on the configuration options and available settings can be found in the official Kibana documentation_. .. _documentation: https://www.elastic.co/guide/en/kibana/current/settings.html Installation ------------ .. code_block: bash helm install --namespace= local/kibana --name=kibana Setting Time Field ------------------ For Kibana to successfully read the logs from Elasticsearch's indexes, the time field will need to be manually set after Kibana has successfully deployed. Upon visiting the Kibana dashboard for the first time, a prompt will appear to choose the time field with a drop down menu. The default time field for Elasticsearch indexes is '@timestamp'. Once this field is selected, the default view for querying log entries can be found by selecting the "Discover" ================================================ FILE: doc/source/monitoring/grafana.rst ================================================ Grafana ======= The Grafana chart in OpenStack-Helm Infra provides default dashboards for the metrics gathered with Prometheus. The default dashboards include visualizations for metrics on: Ceph, Kubernetes, nodes, containers, MySQL, RabbitMQ, and OpenStack. Configuration ------------- Grafana ~~~~~~~ Grafana's configuration is driven with the chart's values.YAML file, and the relevant configuration entries are under the following key: :: conf: grafana: paths: server: database: session: security: users: log: log.console: dashboards.json: grafana_net: These keys correspond to sections in the grafana.ini configuration file, and the to_ini helm-toolkit function will render these values into the appropriate format in grafana.ini. The list of options for these keys can be found in the official Grafana configuration_ documentation. .. _configuration: https://grafana.com/docs/installation/configuration/ Prometheus Data Source ~~~~~~~~~~~~~~~~~~~~~~ Grafana requires configured data sources for gathering metrics for display in its dashboards. The configuration options for datasources are found under the following key in Grafana's values.YAML file: :: conf: provisioning: datasources; monitoring: name: prometheus type: prometheus access: proxy orgId: 1 editable: true basicAuth: true The Grafana chart will use the keys under each entry beneath .conf.provisioning.datasources as inputs to a helper template that will render the appropriate configuration for the data source. The key for each data source (monitoring in the above example) should map to an entry in the endpoints section in the chart's values.yaml, as the data source's URL and authentication credentials will be populated by the values defined in the defined endpoint. .. _sources: https://grafana.com/docs/features/datasources/ Dashboards ~~~~~~~~~~ Grafana adds dashboards during installation with dashboards defined in YAML under the following key: :: conf: dashboards: These YAML definitions are transformed to JSON are added to Grafana's configuration configmap and mounted to the Grafana pods dynamically, allowing for flexibility in defining and adding custom dashboards to Grafana. Dashboards can be added by inserting a new key along with a YAML dashboard definition as the value. Additional dashboards can be found by searching on Grafana's dashboards_ page or you can define your own. A json-to-YAML tool, such as json2yaml_ , will help transform any custom or new dashboards from JSON to YAML. .. _json2yaml: https://www.json2yaml.com/ ================================================ FILE: doc/source/monitoring/index.rst ================================================ OpenStack-Helm Monitoring ========================= Contents: .. toctree:: :maxdepth: 2 grafana prometheus nagios ================================================ FILE: doc/source/monitoring/nagios.rst ================================================ Nagios ====== The Nagios chart in openstack-helm can be used to provide an alarming service that's tightly coupled to an OpenStack-Helm deployment. The Nagios chart uses a custom Nagios core image that includes plugins developed to query Prometheus directly for scraped metrics and triggered alarms, query the Ceph manager endpoints directly to determine the health of a Ceph cluster, and to query Elasticsearch for logged events that meet certain criteria (experimental). Authentication -------------- The Nagios deployment includes a sidecar container that runs an Apache reverse proxy to add authentication capabilities for Nagios. The username and password are configured under the nagios entry in the endpoints section of the chart's values.yaml. The configuration for Apache can be found under the conf.httpd key, and uses a helm-toolkit function that allows for including gotpl entries in the template directly. This allows the use of other templates, like the endpoint lookup function templates, directly in the configuration for Apache. Image Plugins ------------- The Nagios image used contains custom plugins that can be used for the defined service check commands. These plugins include: - check_prometheus_metric.py: Query Prometheus for a specific metric and value - check_exporter_health_metric.sh: Nagios plugin to query prometheus exporter - check_rest_get_api.py: Check REST API status - check_update_prometheus_hosts.py: Queries Prometheus, updates Nagios config - query_prometheus_alerts.py: Nagios plugin to query prometheus ALERTS metric More information about the Nagios image and plugins can be found here_. .. _here: https://github.com/att-comdev/nagios Nagios Service Configuration ---------------------------- The Nagios service is configured via the following section in the chart's values file: :: conf: nagios: nagios: log_file: /opt/nagios/var/log/nagios.log cfg_file: - /opt/nagios/etc/nagios_objects.cfg - /opt/nagios/etc/objects/commands.cfg - /opt/nagios/etc/objects/contacts.cfg - /opt/nagios/etc/objects/timeperiods.cfg - /opt/nagios/etc/objects/templates.cfg - /opt/nagios/etc/objects/prometheus_discovery_objects.cfg object_cache_file: /opt/nagios/var/objects.cache precached_object_file: /opt/nagios/var/objects.precache resource_file: /opt/nagios/etc/resource.cfg status_file: /opt/nagios/var/status.dat status_update_interval: 10 nagios_user: nagios nagios_group: nagios check_external_commands: 1 command_file: /opt/nagios/var/rw/nagios.cmd lock_file: /var/run/nagios.lock temp_file: /opt/nagios/var/nagios.tmp temp_path: /tmp event_broker_options: -1 log_rotation_method: d log_archive_path: /opt/nagios/var/log/archives use_syslog: 1 log_service_retries: 1 log_host_retries: 1 log_event_handlers: 1 log_initial_states: 0 log_current_states: 1 log_external_commands: 1 log_passive_checks: 1 service_inter_check_delay_method: s max_service_check_spread: 30 service_interleave_factor: s host_inter_check_delay_method: s max_host_check_spread: 30 max_concurrent_checks: 60 check_result_reaper_frequency: 10 max_check_result_reaper_time: 30 check_result_path: /opt/nagios/var/spool/checkresults max_check_result_file_age: 3600 cached_host_check_horizon: 15 cached_service_check_horizon: 15 enable_predictive_host_dependency_checks: 1 enable_predictive_service_dependency_checks: 1 soft_state_dependencies: 0 auto_reschedule_checks: 0 auto_rescheduling_interval: 30 auto_rescheduling_window: 180 service_check_timeout: 60 host_check_timeout: 60 event_handler_timeout: 60 notification_timeout: 60 ocsp_timeout: 5 perfdata_timeout: 5 retain_state_information: 1 state_retention_file: /opt/nagios/var/retention.dat retention_update_interval: 60 use_retained_program_state: 1 use_retained_scheduling_info: 1 retained_host_attribute_mask: 0 retained_service_attribute_mask: 0 retained_process_host_attribute_mask: 0 retained_process_service_attribute_mask: 0 retained_contact_host_attribute_mask: 0 retained_contact_service_attribute_mask: 0 interval_length: 1 check_workers: 4 check_for_updates: 1 bare_update_check: 0 use_aggressive_host_checking: 0 execute_service_checks: 1 accept_passive_service_checks: 1 execute_host_checks: 1 accept_passive_host_checks: 1 enable_notifications: 1 enable_event_handlers: 1 process_performance_data: 0 obsess_over_services: 0 obsess_over_hosts: 0 translate_passive_host_checks: 0 passive_host_checks_are_soft: 0 check_for_orphaned_services: 1 check_for_orphaned_hosts: 1 check_service_freshness: 1 service_freshness_check_interval: 60 check_host_freshness: 0 host_freshness_check_interval: 60 additional_freshness_latency: 15 enable_flap_detection: 1 low_service_flap_threshold: 5.0 high_service_flap_threshold: 20.0 low_host_flap_threshold: 5.0 high_host_flap_threshold: 20.0 date_format: us use_regexp_matching: 1 use_true_regexp_matching: 0 daemon_dumps_core: 0 use_large_installation_tweaks: 0 enable_environment_macros: 0 debug_level: 0 debug_verbosity: 1 debug_file: /opt/nagios/var/nagios.debug max_debug_file_size: 1000000 allow_empty_hostgroup_assignment: 1 illegal_macro_output_chars: "`~$&|'<>\"" Nagios CGI Configuration ------------------------ The Nagios CGI configuration is defined via the following section in the chart's values file: :: conf: nagios: cgi: main_config_file: /opt/nagios/etc/nagios.cfg physical_html_path: /opt/nagios/share url_html_path: /nagios show_context_help: 0 use_pending_states: 1 use_authentication: 0 use_ssl_authentication: 0 authorized_for_system_information: "*" authorized_for_configuration_information: "*" authorized_for_system_commands: nagiosadmin authorized_for_all_services: "*" authorized_for_all_hosts: "*" authorized_for_all_service_commands: "*" authorized_for_all_host_commands: "*" default_statuswrl_layout: 4 ping_syntax: /bin/ping -n -U -c 5 $HOSTADDRESS$ refresh_rate: 90 result_limit: 100 escape_html_tags: 1 action_url_target: _blank notes_url_target: _blank lock_author_names: 1 navbar_search_for_addresses: 1 navbar_search_for_aliases: 1 Nagios Host Configuration ------------------------- The Nagios chart includes a single host definition for the Prometheus instance queried for metrics. The host definition can be found under the following values key: :: conf: nagios: hosts: - prometheus: use: linux-server host_name: prometheus alias: "Prometheus Monitoring" address: 127.0.0.1 hostgroups: prometheus-hosts check_command: check-prometheus-host-alive The address for the Prometheus host is defined by the PROMETHEUS_SERVICE environment variable in the deployment template, which is determined by the monitoring entry in the Nagios chart's endpoints section. The endpoint is then available as a macro for Nagios to use in all Prometheus based queries. For example: :: - check_prometheus_host_alive: command_name: check-prometheus-host-alive command_line: "$USER1$/check_rest_get_api.py --url $USER2$ --warning_response_seconds 5 --critical_response_seconds 10" The $USER2$ macro above corresponds to the Prometheus endpoint defined in the PROMETHEUS_SERVICE environment variable. All checks that use the prometheus-hosts hostgroup will map back to the Prometheus host defined by this endpoint. Nagios HostGroup Configuration ------------------------------ The Nagios chart includes configuration values for defined host groups under the following values key: :: conf: nagios: host_groups: - prometheus-hosts: hostgroup_name: prometheus-hosts alias: "Prometheus Virtual Host" - base-os: hostgroup_name: base-os alias: "base-os" These hostgroups are used to define which group of hosts should be targeted by a particular nagios check. An example of a check that targets Prometheus for a specific metric query would be: :: - check_ceph_monitor_quorum: use: notifying_service hostgroup_name: prometheus-hosts service_description: "CEPH_quorum" check_command: check_prom_alert!ceph_monitor_quorum_low!CRITICAL- ceph monitor quorum does not exist!OK- ceph monitor quorum exists check_interval: 60 An example of a check that targets all hosts for a base-os type check (memory usage, latency, etc) would be: :: - check_memory_usage: use: notifying_service service_description: Memory_usage check_command: check_memory_usage hostgroup_name: base-os These two host groups allow for a wide range of targeted checks for determining the status of all components of an OpenStack-Helm deployment. Nagios Command Configuration ---------------------------- The Nagios chart includes configuration values for the command definitions Nagios will use when executing service checks. These values are found under the following key: :: conf: nagios: commands: - send_service_snmp_trap: command_name: send_service_snmp_trap command_line: "$USER1$/send_service_trap.sh '$USER8$' '$HOSTNAME$' '$SERVICEDESC$' $SERVICESTATEID$ '$SERVICEOUTPUT$' '$USER4$' '$USER5$'" - send_host_snmp_trap: command_name: send_host_snmp_trap command_line: "$USER1$/send_host_trap.sh '$USER8$' '$HOSTNAME$' $HOSTSTATEID$ '$HOSTOUTPUT$' '$USER4$' '$USER5$'" - send_service_http_post: command_name: send_service_http_post command_line: "$USER1$/send_http_post_event.py --type service --hostname '$HOSTNAME$' --servicedesc '$SERVICEDESC$' --state_id $SERVICESTATEID$ --output '$SERVICEOUTPUT$' --monitoring_hostname '$HOSTNAME$' --primary_url '$USER6$' --secondary_url '$USER7$'" - send_host_http_post: command_name: send_host_http_post command_line: "$USER1$/send_http_post_event.py --type host --hostname '$HOSTNAME$' --state_id $HOSTSTATEID$ --output '$HOSTOUTPUT$' --monitoring_hostname '$HOSTNAME$' --primary_url '$USER6$' --secondary_url '$USER7$'" - check_prometheus_host_alive: command_name: check-prometheus-host-alive command_line: "$USER1$/check_rest_get_api.py --url $USER2$ --warning_response_seconds 5 --critical_response_seconds 10" The list of defined commands can be modified with configuration overrides, which allows for the ability define commands specific to an infrastructure deployment. These commands can include querying Prometheus for metrics on dependencies for a service to determine whether an alert should be raised, executing checks on each host to determine network latency or file system usage, or checking each node for issues with ntp clock skew. Note: Since the conf.nagios.commands key contains a list of the defined commands, the entire contents of conf.nagios.commands will need to be overridden if additional commands are desired (due to the immutable nature of lists). Nagios Service Check Configuration ---------------------------------- The Nagios chart includes configuration values for the service checks Nagios will execute. These service check commands can be found under the following key: :: conf: nagios: services: - notifying_service: name: notifying_service use: generic-service flap_detection_enabled: 0 process_perf_data: 0 contact_groups: snmp_and_http_notifying_contact_group check_interval: 60 notification_interval: 120 retry_interval: 30 register: 0 - check_ceph_health: use: notifying_service hostgroup_name: base-os service_description: "CEPH_health" check_command: check_ceph_health check_interval: 300 - check_hosts_health: use: generic-service hostgroup_name: prometheus-hosts service_description: "Nodes_health" check_command: check_prom_alert!K8SNodesNotReady!CRITICAL- One or more nodes are not ready. check_interval: 60 - check_prometheus_replicas: use: notifying_service hostgroup_name: prometheus-hosts service_description: "Prometheus_replica-count" check_command: check_prom_alert_with_labels!replicas_unavailable_statefulset!statefulset="prometheus"!statefulset {statefulset} has lesser than configured replicas check_interval: 60 The Nagios service configurations define the checks Nagios will perform. These checks contain keys for defining: the service type to use, the host group to target, the description of the service check, the command the check should use, and the interval at which to trigger the service check. These services can also be extended to provide additional insight into the overall status of a particular service. These services also allow the ability to define advanced checks for determining the overall health and liveness of a service. For example, a service check could trigger an alarm for the OpenStack services when Nagios detects that the relevant database and message queue has become unresponsive. ================================================ FILE: doc/source/monitoring/prometheus.rst ================================================ Prometheus ========== The Prometheus chart in openstack-helm provides a time series database and a strong querying language for monitoring various components of OpenStack-Helm. Prometheus gathers metrics by scraping defined service endpoints or pods at specified intervals and indexing them in the underlying time series database. Authentication -------------- The Prometheus deployment includes a sidecar container that runs an Apache reverse proxy to add authentication capabilities for Prometheus. The username and password are configured under the monitoring entry in the endpoints section of the chart's values.yaml. The configuration for Apache can be found under the conf.httpd key, and uses a helm-toolkit function that allows for including gotpl entries in the template directly. This allows the use of other templates, like the endpoint lookup function templates, directly in the configuration for Apache. Prometheus Service configuration -------------------------------- The Prometheus service is configured via command line flags set during runtime. These flags include: setting the configuration file, setting log levels, setting characteristics of the time series database, and enabling the web admin API for snapshot support. These settings can be configured via the values tree at: :: conf: prometheus: command_line_flags: log.level: info query.max_concurrency: 20 query.timeout: 2m storage.tsdb.path: /var/lib/prometheus/data storage.tsdb.retention: 7d web.enable_admin_api: false web.enable_lifecycle: false The Prometheus configuration file contains the definitions for scrape targets and the location of the rules files for triggering alerts on scraped metrics. The configuration file is defined in the values file, and can be found at: :: conf: prometheus: scrape_configs: | By defining the configuration via the values file, an operator can override all configuration components of the Prometheus deployment at runtime. Kubernetes Endpoint Configuration --------------------------------- The Prometheus chart in openstack-helm uses the built-in service discovery mechanisms for Kubernetes endpoints and pods to automatically configure scrape targets. Functions added to helm-toolkit allows configuration of these targets via annotations that can be applied to any service or pod that exposes metrics for Prometheus, whether a service for an application-specific exporter or an application that provides a metrics endpoint via its service. The values in these functions correspond to entries in the monitoring tree under the prometheus key in a chart's values.yaml file. The functions definitions are below: :: {{- define "helm-toolkit.snippets.prometheus_service_annotations" -}} {{- $config := index . 0 -}} {{- if $config.scrape }} prometheus.io/scrape: {{ $config.scrape | quote }} {{- end }} {{- if $config.scheme }} prometheus.io/scheme: {{ $config.scheme | quote }} {{- end }} {{- if $config.path }} prometheus.io/path: {{ $config.path | quote }} {{- end }} {{- if $config.port }} prometheus.io/port: {{ $config.port | quote }} {{- end }} {{- end -}} :: {{- define "helm-toolkit.snippets.prometheus_pod_annotations" -}} {{- $config := index . 0 -}} {{- if $config.scrape }} prometheus.io/scrape: {{ $config.scrape | quote }} {{- end }} {{- if $config.path }} prometheus.io/path: {{ $config.path | quote }} {{- end }} {{- if $config.port }} prometheus.io/port: {{ $config.port | quote }} {{- end }} {{- end -}} These functions render the following annotations: - prometheus.io/scrape: Must be set to true for Prometheus to scrape target - prometheus.io/scheme: Overrides scheme used to scrape target if not http - prometheus.io/path: Overrides path used to scrape target metrics if not /metrics - prometheus.io/port: Overrides port to scrape metrics on if not service's default port Each chart that can be targeted for monitoring by Prometheus has a prometheus section under a monitoring tree in the chart's values.yaml, and Prometheus monitoring is disabled by default for those services. Example values for the required entries can be found in the following monitoring configuration for the prometheus-node-exporter chart: :: monitoring: prometheus: enabled: false node_exporter: scrape: true If the prometheus.enabled key is set to true, the annotations are set on the targeted service or pod as the condition for applying the annotations evaluates to true. For example: :: {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.node_exporter }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "node_metrics" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "node_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} Kubelet, API Server, and cAdvisor --------------------------------- The Prometheus chart includes scrape target configurations for the kubelet, the Kubernetes API servers, and cAdvisor. These targets are configured based on a kubeadm deployed Kubernetes cluster, as OpenStack-Helm uses kubeadm to deploy Kubernetes in the gates. These configurations may need to change based on your chosen method of deployment. Please note the cAdvisor metrics will not be captured if the kubelet was started with the following flag: :: --cadvisor-port=0 To enable the gathering of the kubelet's custom metrics, the following flag must be set: :: --enable-custom-metrics Installation ------------ The Prometheus chart can be installed with the following command: .. code-block:: bash helm install --namespace=openstack local/prometheus --name=prometheus The above command results in a Prometheus deployment configured to automatically discover services with the necessary annotations for scraping, configured to gather metrics on the kubelet, the Kubernetes API servers, and cAdvisor. Extending Prometheus -------------------- Prometheus can target various exporters to gather metrics related to specific applications to extend visibility into an OpenStack-Helm deployment. Currently, openstack-helm contains charts for: - prometheus-kube-state-metrics: Provides additional Kubernetes metrics - prometheus-node-exporter: Provides metrics for nodes and linux kernels - prometheus-openstack-metrics-exporter: Provides metrics for OpenStack services Kube-State-Metrics ~~~~~~~~~~~~~~~~~~ The prometheus-kube-state-metrics chart provides metrics for Kubernetes objects as well as metrics for kube-scheduler and kube-controller-manager. Information on the specific metrics available via the kube-state-metrics service can be found in the kube-state-metrics_ documentation. The prometheus-kube-state-metrics chart can be installed with the following: .. code-block:: bash helm install --namespace=kube-system local/prometheus-kube-state-metrics --name=prometheus-kube-state-metrics .. _kube-state-metrics: https://github.com/kubernetes/kube-state-metrics/tree/master/Documentation Node Exporter ~~~~~~~~~~~~~ The prometheus-node-exporter chart provides hardware and operating system metrics exposed via Linux kernels. Information on the specific metrics available via the Node exporter can be found on the Node_exporter_ GitHub page. The prometheus-node-exporter chart can be installed with the following: .. code-block:: bash helm install --namespace=kube-system local/prometheus-node-exporter --name=prometheus-node-exporter .. _Node_exporter: https://github.com/prometheus/node_exporter OpenStack Exporter ~~~~~~~~~~~~~~~~~~ The prometheus-openstack-exporter chart provides metrics specific to the OpenStack services. The exporter's source code can be found here_. While the metrics provided are by no means comprehensive, they will be expanded upon. Please note the OpenStack exporter requires the creation of a Keystone user to successfully gather metrics. To create the required user, the chart uses the same keystone user management job the OpenStack service charts use. The prometheus-openstack-exporter chart can be installed with the following: .. code-block:: bash helm install --namespace=openstack local/prometheus-openstack-exporter --name=prometheus-openstack-exporter .. _here: https://github.com/att-comdev/openstack-metrics-collector Other exporters ~~~~~~~~~~~~~~~ Certain charts in OpenStack-Helm include templates for application-specific Prometheus exporters, which keeps the monitoring of those services tightly coupled to the chart. The templates for these exporters can be found in the monitoring subdirectory in the chart. These exporters are disabled by default, and can be enabled by setting the appropriate flag in the monitoring.prometheus key of the chart's values.yaml file. The charts containing exporters include: - Elasticsearch_ - RabbitMQ_ - MariaDB_ - Memcached_ - Fluentd_ - Postgres_ .. _Elasticsearch: https://github.com/prometheus-community/elasticsearch_exporter .. _RabbitMQ: https://github.com/kbudde/rabbitmq_exporter .. _MariaDB: https://github.com/prometheus/mysqld_exporter .. _Memcached: https://github.com/prometheus/memcached_exporter .. _Fluentd: https://github.com/V3ckt0r/fluentd_exporter .. _Postgres: https://github.com/wrouesnel/postgres_exporter Ceph ~~~~ Starting with Luminous, Ceph can export metrics with ceph-mgr prometheus module. This module can be enabled in Ceph's values.yaml under the ceph_mgr_enabled_plugins key by appending prometheus to the list of enabled modules. After enabling the prometheus module, metrics can be scraped on the ceph-mgr service endpoint. This relies on the Prometheus annotations attached to the ceph-mgr service template, and these annotations can be modified in the endpoints section of Ceph's values.yaml file. Information on the specific metrics available via the prometheus module can be found in the Ceph prometheus_ module documentation. .. _prometheus: http://docs.ceph.com/docs/master/mgr/prometheus/ Prometheus Dashboard -------------------- Prometheus includes a dashboard that can be accessed via the accessible Prometheus endpoint (NodePort or otherwise). This dashboard will give you a view of your scrape targets' state, the configuration values for Prometheus's scrape jobs and command line flags, a view of any alerts triggered based on the defined rules, and a means for using PromQL to query scraped metrics. The Prometheus dashboard is a useful tool for verifying Prometheus is configured appropriately and to verify the status of any services targeted for scraping via the Prometheus service discovery annotations. Rules Configuration ------------------- Prometheus provides a querying language that can operate on defined rules which allow for the generation of alerts on specific metrics. The Prometheus chart in openstack-helm defines these rules via the values.yaml file. By defining these in the values file, it allows operators flexibility to provide specific rules via overrides at installation. The following rules keys are provided: :: values: conf: rules: alertmanager: etcd3: kube_apiserver: kube_controller_manager: kubelet: kubernetes: rabbitmq: mysql: ceph: openstack: custom: These provided keys provide recording and alert rules for all infrastructure components of an OpenStack-Helm deployment. If you wish to exclude rules for a component, leave the tree empty in an overrides file. To read more about Prometheus recording and alert rules definitions, please see the official Prometheus recording_ and alert_ rules documentation. .. _recording: https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/ .. _alert: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ Note: Prometheus releases prior to 2.0 used gotpl to define rules. Prometheus 2.0 changed the rules format to YAML, making them much easier to read. The Prometheus chart in openstack-helm uses Prometheus 2.0 by default to take advantage of changes to the underlying storage layer and the handling of stale data. The chart will not support overrides for Prometheus versions below 2.0, as the command line flags for the service changed between versions. The wide range of exporters included in OpenStack-Helm coupled with the ability to define rules with configuration overrides allows for the addition of custom alerting and recording rules to fit an operator's monitoring needs. Adding new rules or modifying existing rules require overrides for either an existing key under conf.rules or the addition of a new key under conf.rules. The addition of custom rules can be used to define complex checks that can be extended for determining the liveliness or health of infrastructure components. ================================================ FILE: doc/source/readme.rst ================================================ .. include:: ../../README.rst ================================================ FILE: doc/source/specs/2025.1/chart_versioning.rst ================================================ ================= Charts versioning ================= Problem Description =================== There are issues: * All Openstack-Helm charts depend on the helm-toolkit subchart, but the helm-toolkit version is not pinned. When helm-toolkit is updated, we don't bump the version of the charts that depend on it and re-publish them. This can change the behavior of the charts while the version of the chart tarball remains unchanged. * We use `chart-testing`_ to lint the charts. The chart-testing tool requires that the chart version is bumped every time any file in the chart directory is changed. In every chart, we have a ``values_overrides`` directory where we store the version-specific overrides as well as example overrides for some specific configurations. These overrides are not part of the chart tarball, but when they are changed, we bump the chart version. * We use ``apiVersion: v1`` in ``Chart.yaml``, and dependencies are stored in a separate ``requirements.yaml`` file. However, ``apiVersion: v2`` allows defining dependencies directly in the ``Chart.yaml`` file. * We track the release notes in a separate directory and we don't have a CHANGELOG.md file in chart tarballs. * Chart maintainers are assumed to update the same release notes file when they change the same chart in two separate commits. This leads to merge conflicts that are now resolved manually which is inconvenient. This is because we are misusing the Reno tool which is designed to avoid merge conflicts in the release notes. * All the chart versions are independent of each other and do not follow the Openstack release versioning which makes it difficult for users to understand which version of the chart corresponds to which Openstack release. Proposed Change =============== We propose to do the following: * Move values overrides to a separate directory. * Use ``apiVersion: v2`` in ``Chart.yaml``. * Move release notes to the CHANGELOG.md files. * Once the Openstack is released we will bump the version of all charts to this new release, for example ``2025.1.0``. Semver assumes the following: * MAJOR version when you make incompatible API changes * MINOR version when you add functionality in a backward compatible manner * PATCH version when you make backward compatible bug fixes However, we will not strictly follow these assumptions. We will still follow the policy that the last version of any chart must be compatible with all currently maintained versions of Openstack (usually 3 most recent versions). All the changes between Openstack releases will be backward compatible. We will not bump the chart version in the git repo when we update chart. Instead, we will increment the PATCH automatically when building the tarball. The PATCH will be calculated as the number of commits related to a given chart after the latest git tag. So for example if the latest tag is ``2024.2.0`` and we have 3 commits in the nova chart after this tag, the version of the nova tarball will be ``2024.2.3``. All the tarballs will be published with the build metadata showing the commit SHA sum with which the tarball is built. The tarball version will look like ``2025.1.X+_``. Implementation ============== Assignee(s) ----------- Primary assignees: kozhukalov (Vladimir Kozhukalov ) Work Items ---------- The following work items need to be completed for this specification to be implemented. Values overrides ~~~~~~~~~~~~~~~~ Move values_overrides from all charts to a separate directory ``values`` with the hierarchy ``values_overrides//_.yaml``. The Openstack-Helm plugin is able to lookup the overrides in an arbitrary directory, but the directory structure must be as described above. Update the version of all charts to ``2024.2.0`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ All the charts must be updated to the version ``2024.2.0`` in a single commit. While developing the charts we will not change the version of the charts in their Chart.yaml files in the git repo. So, in the git repos the versions of all charts will be the same, e.g. ``2024.2.0``. It will be changed twice a year when the Openstack is released and the version update commit will be tagged appropriately. However when we build a chart the tarball version will be updated every time. The tarball version will be calculated automatically ``2024.2.X+_`` where ``X`` is the number of commits related to the chart after the latest tag. .. code-block:: bash $ PATCH=$(git log --oneline .. | wc -l) $ OSH_COMMIT_SHA=$(cd ${SRC}/openstack-helm; git rev-parse --short HEAD) $ OSH_INFRA_COMMIT_SHA=$(cd ${SRC}/openstack-helm-infra; git rev-parse --short HEAD) $ helm package --version 2024.2.${PATCH}+${OSH_COMMIT_SHA}_${OSH_INFRA_COMMIT_SHA} .. note:: When the chart itself is not changed but is re-built with the new version of the helm-toolkit, the PATCH will not be changed and the tarball will be published with the same version but with the new build metadata (``${OSH_INFRA_COMMIT_SHA}``). Set git tag for the Openstack-Helm repositories ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We will set the git tag ``2024.2.0`` for all the Openstack-Helm repositories. These tags are set by means of submitting a patch to the openstack/releases repository. Since that we will set such tag twice a year when the Openstack is released. Update ``apiVersion`` in ``Chart.yaml`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Update ``apiVersion`` to ``v2`` in all ``Chart.yaml`` files and migrate the dependecies (helm-toolkit) from ``requirements.yaml`` to ``Chart.yaml``. Reorganize the process of managing release notes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The Reno tool (a Python package used for managing release notes) can be used in a way that allows to avoid merge conflicts for PRs that update the same chart. It generates the release notes report using the git history. We suggest the following workflow: * When a chart is updated, the maintainer runs the ``reno new `` command to create a new release note file ``releasenotes/notes/-.yaml``. * The maintainer fills in the new release note file with the necessary information. * The maintainer commits the release note file. * While building the tarball we will use ``reno report`` command with a custom script to generate the release notes report and automatically prepare the ``/CHANGELOG.md`` file. Since we are not going to bump the chart version when we update it, all the release notes will be bound to some git commits and we be put under the headers that correspond to git tags. The format of the ``CHANGELOG.md`` file: .. code-block:: markdown ## X.Y.Z- - Some new update ## X.Y.Z - Some update - Previous update Where ``X.Y.Z`` is the tag in the git repository and the ``X.Y.Z`` section contains all the release notes made before the tag was set. The ``X.Y.Z-`` section contains all the release notes made after the tag was set. At this point we have the only tag ``0.1.0``. So, when we set the ``2024.2.0`` tag almost all the release notes will go to this tag and the ``CHANGELOG.md`` file. So it will look like: .. code-block:: markdown ## 2024.2.0- - Some new update ## 2024.2.0 - Some update - Previous update Update the versioning policy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * When the helm-toolkit chart is updated and tested with all other charts, we will re-build it and publish with the new version according to how it is described above. All other charts also will be re-built with this new version of helm-toolkit (inside) and published with the new build metadata (new ``$OSH_INFRA_COMMIT_SHA``). Helm-toolkit version will not be pinned in the charts. * When a particular chart is changed, we will re-build and publish only this chart. So all charts will be built and published independently of each other. All the test jobs must be able to use updated chart from the PR with other charts taken from the public helm repository (tarballs). Alternatively, we could pin the helm-toolkit version in the charts, but this would make the maintenance of the charts more complicated. Documentation Impact ==================== The user documentation must be updated and it must be emphasized that the chart version is not equal to the Openstack release version and that the Openstack version is defined by the images used with the charts. Also it must be explained that a particular version like ``2024.2.X`` is compatible with those Openstack releases that were maintained at the time ``2024.2.X`` was built and published (i.e ``2023.1``, ``2023.2``, ``2024.1``, ``2024.2``). .. _chart-testing: https://github.com/helm/chart-testing.git ================================================ FILE: doc/source/specs/2025.2/own_service_accounts.rst ================================================ ==================== Own Service Accounts ==================== Problem Description =================== Currently when an OpenStack-Helm chart deploys a OpenStack service, it creates a service account that is used by other Openstack services to interact with the service's API. For example, the Nova chart creates a service account called ``nova`` and other charts like Cinder and Neutron configure Cinder and Neutron services to use the ``nova`` service account to interact with the Nova API. However, there might be scenarios where multiple Nova accounts are necessary. For instance, if Neutron requires more permissive access to the Nova API than Cinder, it might be desirable to create two separate accounts with tailored permissions. Also the current approach assumes service accounts are owned by the chart that creates them and it requires other charts to be deployed with the credentials of the service account owner chart. I.e. the service account credentials must be synced between charts. Proposed Change =============== The spec proposes to modify the `Keystone user manifest`_ so it is able to create multiple Keystone users. The job will be deployed with multiple containers, each container will create a separate Keystone user. All other Openstack charts use the `Keystone user manifest`_ for managing service accounts. So every Openstack chart will be able to create a bunch of service accounts according to their needs. E.g. the Neutron chart will create the following service accounts: * neutron (used by Neutron to communicate with the Keystone API to check auth tokens and other services can use it to get access to the Neutron API) * neutron_nova (used by Neutron to get access to the Nova API instead of using ``nova`` service account created by the Nova chart) * neutron_placement (used by Neutron to get access to the Placement API instead of using ``placement`` service account managed by the Placement chart) The proposed change is going to be backward compatible because the Neutron chart will still be able to use the ``neutron`` and ``placement`` service accounts managed by the Nova and Placement charts. Also the ``neutron`` service account can still be used by other charts to communicate with the Neutron API. Implementation ============== Assignee(s) ----------- Primary assignee: kozhukalov (Vladimir Kozhukalov ) Values ------ Service accounts credentials are defined in the ``values.yaml`` files in the ``.Values.endpoints.identity.auth`` section. The section contains a bunch of dicts defining credentials for every service account. Currently those dicts which correspond to service accounts managed by other charts must be aligned with those charts values. For example, the Neutron values must define the ``nova`` service account the same way as the Nova chart does. The following is the example of how the ``.Values.endpoints.identity.auth`` section of a chart must be modified. The example is given for the Neutron chart: .. code-block:: yaml endpoints: identity: auth: # This serivce account is managed by Keystone chart # and created during Keystone database sync. # We should not modify it. admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default # Service account with the following username/password # will be created by the Keystone user job # and will be used for Neutron configuration. # For backward compatibility this dict must not be modified # to stay aligned with other charts that use this service account # to get access to the Neutron API. neutron: role: admin,service region_name: RegionOne username: neutron password: password project_name: service user_domain_name: service project_domain_name: service # Service account with the following username/password # will be created by the Keystone user job # and will be used for Neutron configuration. Also the # ``role`` field must be added to assign necessary roles # to the service account. nova: role: admin,service region_name: RegionOne project_name: service username: neutron_nova password: neutron_nova_password user_domain_name: service project_domain_name: service # Service account with the following username/password # will be created by the Keystone user job # and will be used for Neutron configuration. Also the # ``role`` field must be added to assign necessary roles # to the service account. placement: role: admin,service region_name: RegionOne project_name: service username: neutron_placement password: neutron_placement_password user_domain_name: service project_domain_name: service Secrets ------- The service account credentials are stored in K8s secrets which are used by the `Keystone user manifest`_ to create the service accounts. So the the template that deploys those secrets must be updated to create the secrets for all service accounts defined in the ``.Values.endpoints.identity.auth`` section. Also the ``.Values.secrets.identity`` section must be updated and secret names must be added for all service accounts defined in the ``.Values.endpoints.identity.auth`` section. Keystone user manifest ---------------------- The Helm-toolkit chart defines the ``Keystone user manifest``_ which is used by all Openstack charts to create service accounts. The manifest must be updated to be able to accept ``serviceUsers`` parameter which will be the list of service accounts to be created by the job. For backward compatibility if the ``serviceUsers`` parameter is not given then the manifest will use the ``serviceUser`` parameter or ``serviceName`` parameter to define the ``serviceUsers`` as a list with a single element. .. code-block:: {{- $serviceName := index . "serviceName" -}} {{- $singleServiceUser := index . "serviceUser" | default $serviceName -}} {{- $serviceUsers := index . "serviceUsers" | default (tuple $singleServiceUser) -}} Keystone user job ----------------- All Openstack charts deploy the job to create service accounts which uses the `Keystone user manifest`_. The modified manifest will be able to create multiple Keystone users and the job template must also be updated to pass the proper list of service accounts to the manifest. For example, the Neutron chart will be modified to create the following service accounts: .. code-block:: {{ dict "envAll" . "serviceName" "neutron" "serviceUsers" (tuple "neutron" "nova" "placement") | include "helm-toolkit.manifests.job_ks_user" }} Work Items ---------- * Modify the `Keystone user manifest`_ to make it possible to create multiple Keystone users in a single job. * Modify charts one by one as described above so they create their own service accounts to get access to the APIs of other OpenStack services. Alternatives ------------ A K8s operator can be used to manage service accounts. In this case charts will deploy the custom resources that will be handled by the operator. The operator could also be useful for more complex scenarios when users deploy Keystone federation and need more flexibility in managing service accounts. However, the proposed change is simpler to implement and it does not require any additional components while the change is backward compatible and does not break existing deployments. Documentation Impact ==================== The documentation must be updated to reflect the change. .. _Keystone user manifest: https://opendev.org/openstack/openstack-helm/src/branch/master/helm-toolkit/templates/manifests/_job-ks-user.yaml.tpl ================================================ FILE: doc/source/specs/COPYME ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. =============== Blueprint Title =============== Include the URL of your Storyboard RFE: https://storyboard.openstack.org/#!/story/1234567 Problem Description =================== A detailed description of the problem. Use cases --------- 1. TODO Proposed Change =============== How do you propose to solve this problem, and what's the scope? Security Impact --------------- How does this feature impact the securtiy of OpenStack-Helm? Performance Impact ------------------ Does this feature impact the performance of OpenStack-Helm? Alternatives ------------ Why is the proposed approach the best approach? Implementation ============== Assignee(s) ----------- Who is leading the implementation? Designate the primary author and contact. Primary assignee: Work Items ---------- Work items or tasks. These can be worked on by multiple contributors. Testing ======= What tests will verify this change is functional? Documentation Impact ==================== What documentation needs must be considered with this change? References ========== Place any external references here. ================================================ FILE: doc/source/specs/developer-environment.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. ===================== Developer Environment ===================== https://blueprints.launchpad.net/openstack-helm/+spec/developer-environment Problem Description =================== Developers require a simple way of instantiating a working environment for OpenStack-Helm, that allows them to quickly begin development of the project. This is more complex to achieve than many OpenStack Projects that can simply rely upon a devstack plugin to achieve this. This is as OpenStack-Helm is focused on the deployment of OpenStack (and associated) Projects, rather than the development of the projects themselves, and also requires additional supporting infrastructure, e.g. Kubernetes and a CNI. Use cases --------- 1. Development of OpenStack-Helm 2. PoC deployments of OpenStack-Helm Proposed Change =============== The OpenStack-Helm Zuulv2 gates were written to allow use outside of OpenStack-Infra, to quickly set up a Kubernetes cluster, with the adoption of Zuulv3 underway it is logical to extend this paradigm to the Zuulv3 Playbooks. This will be driven via a ``Makefile`` that will allow developers to perform the following actions: * Prepare Host(s) for OpenStack-Helm deployment * Deploy Kubernetes via KubeADM, with charts for CNI and DNS services At this point, curated scripts will be used to deploy OpenStack-Helm services on demand as desired, with documentation provided to allow a new developer to quickly set up either a single or multimode deployment of a reference `OpenStack Compute Kit `_ environment with the addition of: * Ceph backed Object Storage * Ceph backed Block Storage (cinder) * Orchestration (heat) * Web UI (horizon) A set of scripts will be provided to exercise the deployed environment that checks the basic functionality of the deployed cloud, driven where possible via OpenStack heat: * Create external network * Setup access to the external network from the development machine * Create tenant network * Create tenant router to link tenant network and external * Create SSH Key in nova * Create VM on tenant network * Assign Floating IP to VM * SSH into VM and check it can access the internet This deployment process will be gated, to ensure that the development the environment is consistently working against ``master`` for the OpenStack-Helm repositories. Security Impact --------------- There will be no security impact, as it will deploy the charts in OpenStack-Helm[-infra/-addons] upon a reference KubeADM administered cluster. Performance Impact ------------------ This feature will not affect the performance of OpenStack-Helm. Alternatives ------------ The alternative would be to continue supporting the current bash driven containerized KubeADM and Kubelet approach, though this has the following issues: * The containerized Kubelet cannot survive a restart, as it does not setup mounts correctly. * The bash scripts are largely undocumented and have grown to the point where they are very hard for a new developer to work on. * The move to Zuulv3 native operation of the OpenStack-Helm gates mean there would be no code reuse between the gate and developer environments, so supporting the existing code for Zuulv2 will incur significant tech-debt. Implementation ============== Assignee(s) ----------- Primary assignee: portdirect (Pete Birley) Work Items ---------- The following work items need to be completed for this Specification to be implemented. * Update of Developer Documentation * Update of Makefile for OpenStack-Helm-Infra to allow modular deployment of components * Develop scripts for bringing up OpenStack-Helm Charts and perform basic interactive tests * Add gate for developer environment Testing ======= A gate will be added to OpenStack-Helm that runs through the developer environment deployment process. Documentation Impact ==================== The developer documentation in OpenStack-Helm should be updated to match the gated developer deploy process. ================================================ FILE: doc/source/specs/fluentbit-fluentd-architecture.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. ====================================== fluentbit-fluentd logging architecture ====================================== Blueprints: 1. osh-logging-framework_ .. _osh-logging-framework: https://blueprints.launchpad.net/openstack-helm/+spec/osh-logging-framework Releated Specs: 1. OSH logging monitoring and alerting: https://review.openstack.org/#/c/482687/ Problem Description =================== OpenStack-Helm defines a centralized logging mechanism to provide insight into the state of the OpenStack services and infrastructure components as well as underlying Kubernetes platform. Among the requirements for a logging platform, where log data can come from and where log data need to be delivered are very variable. To support various logging scenarios, OpenStack-Helm should provide a flexible mechanism to meet with certain operation needs. This spec proposes fast and lightweight log forwarder and full featured log aggregator complementing each other providing a flexible and reliable solution. Especially, Fluentbit is proposed as a log forwarder and Fluentd is proposed as a main log aggregator and processor. Platform Requirements ===================== Logging Requirements -------------------- The requirements for a logging collector/aggregator include: 1. Log collection daemon runs on each node to forward logs to aggregator 2. Log collection daemon should have a minimal server footprint 3. Log aggregator deployment runs on a selected node as deployment 4. Ability to apply custom metadata and uniform format to logs 5. Log aggregator should have HA capability 6. Log aggregator should have a flexible output capability to choose from 7. Log aggregator is able to send data to Elasticsearch and Kafka 8. Log aggregator should be scalable Logical Diagram --------------- 1. diagram link: https://github.com/sktelecom-oslab/docs/blob/master/images/fluentbit-fluentd-diagram.png Use Cases ========= Logging Use Cases ----------------- Example uses for centralized logging with Fluentbit and Fluentd include: 1. Cover the following logging use cases https://review.openstack.org/#/c/482687/ 2. Collect logs from the node by Fluentbit 3. Every Fluentbit send logs to Fluentd with Kubernetes metadata attached 4. Fluentd then attaches Kubernetes and/or OpenStack metadata 5. Fluentd properly filters and categorizes logs 6. Fluentd send aggregated logs to Elasticsearch for the internal use cases 7. Aggregator also send aggregated logs to Kafka for external tools to consume Proposed Change =============== Logging ------- Fluentbit, Fluentd meet OpenStack-Helm's logging requirements for gathering, aggregating, and delivering of logged events. Fluntbit runs as a daemonset on each node and mounts the /var/lib/docker/containers directory. The Docker container runtime engine directs events posted to stdout and stderr to this directory on the host. Fluentbit then forward the contents of that directory to Fluentd. Fluentd runs as deployment at the designated nodes and expose service for Fluentbit to forward logs. Fluentd should then apply the Logstash format to the logs. Fluentd can also write Kubernetes and OpenStack metadata to the logs. Fluentd will then forward the results to Elasticsearch and to optionally Kafka. Elasticsearch indexes the logs in a logstash-* index by default. Kafka stores the logs in a 'logs' topic by default. Any external tool can then consume the 'logs' topic. The proposal includes the following: 1. Helm chart for Fluentbit-Fluentd Combination The above chart must include sensible configuration values to make the logging platform usable by default. These include: proper input configurations for both Fluentbit and Fluentd, proper output configurations for both Fluentbit and Fluentd, proper metadata and formats applied to the logs via Fluentd. Security Impact --------------- All services running within the platform should be subject to the security practices applied to the other OpenStack-Helm charts. Performance Impact ------------------ To minimize the performance impacts, the following should be considered: 1. Sane defaults for log retention and rotation policies Implementation ============== Assignee(s) ----------- Primary assignees: sungil (Sungil Im) jayahn (Jaesuk Ahn) Work Items ---------- 1. Fluentbit-Fluentd logging chart All charts should follow design approaches applied to all other OpenStack-Helm charts, including the use of helm-toolkit. All charts require valid and sensible default values to provide operational value out of the box. Testing ======= Testing should include Helm tests for each of the included charts as well as an integration test in the gate. Documentation Impact ==================== Documentation should be included for each of the included charts as well as documentation detailing the requirements for a usable monitoring platform, preferably with sane default values out of the box. ================================================ FILE: doc/source/specs/index.rst ================================================ Project Specifications ====================== Specifications in this repository represent a consensus on the topics covered within. They should be considered a mandate on the path forward with regards to the content on which they are drafted. Here is a list of the current specs: .. toctree:: :maxdepth: 1 :glob: 2025.1/* 2025.2/* * Specifications Purpose ---------------------- A specification should precede any broad-reaching technical changes or proposals to OpenStack-Helm. Examples of changes requiring a specification include: a standard format to the values.yaml files, multiple backend support for neutron, and the approach for logging and monitoring in OpenStack-Helm. Some additional features will not need an accompanying specification, but may be tied back to an existing specification. An example of this would be introducing a service in OpenStack-Helm that could be included under the scope of a specification already drafted and approved. Specifications Process ---------------------- Before drafting a specification, a blueprint should be filed in Storyboard_ along with any dependencies the blueprint requires. Once the blueprint has been registered, submit the specification as a patch set to the specs/ directory using the supplied template. More information about the blueprint + specification lifecycle can be found here_. .. _Storyboard: https://storyboard.openstack.org/#!/project_group/64 .. _here: https://wiki.openstack.org/wiki/Blueprints#Blueprints_and_Specs ================================================ FILE: doc/source/specs/multi-os.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. ================ Multi-OS Support ================ Include the URL of your Storyboard RFE: https://storyboard.openstack.org/#!/story/2005130 Problem Description =================== Our :ref:`images documentation` documentation claims to be independent of the image. However, some helm charts hard code paths of binaries, executables' runtime configurations, etc. Therefore, the image agnostic promise is broken. We need to adapt all the helm charts to remove the hard-coded bits, be image agnostic, to allow users to bring their own images. Use cases --------- Allow the usage of multiple base images in OSH. Proposed Change =============== Edit all helm charts to remove possible references to image specific elements, replacing them with values overrides or conditionals. It is important to notice that the helm charts can be split in two categories for now: #. Helm charts for which we use official upstream images. (Called further ``Category A`` helm charts) #. Helm charts for which we are building images in osh-images. (Called further ``Category B`` helm charts) For the ``Category B`` helm charts, an informal testing has been done in the past to ensure image independence. However, there is nothing exercising this independence in gates. Due to that, code of the helm charts might or might not require adapting. In all cases, we will need to provide different ``profiles`` (in other words, overrides), to test different image providers use cases in CI. The ``profiles`` yaml files (for example ``centos_7``, ``opensuse_15``) will be provided in each chart's ``example_values/`` directory. This folder will be masked to helm through a helmignore file. Its content is only for user consumption, not for inclusion in helm charts through the File directive. In other words, this is a user interface given for convenience merely using the abilities of the existing helm charts. The default ``values.yaml`` need to expose those abilities, by adding a new series of keys/values to add the necessary features. The existing schema for images is the following: .. code-block:: yaml images: tags: imagename1: imagelocation:version-distro imagename2: imagelocation:version-distro pull_policy: local_registry: For this spec, we assume ``imagename1`` and ``imagename2`` are similarly built. This means we do not require any override per image. Instead we require a generic kind of override, per application, usable by all charts. I propose to extend the conf schema with generic software information. For example, for apache2: .. code-block:: yaml conf: software: apache2: #the apache2 binary location binary: apache2 start_args: -DFOREGROUND stop_args: -k graceful-stop #directory where to drop the config files for apache vhosts conf_dir: /etc/apache2/conf-enabled sites_dir: /etc/apache2/sites-enabled When possible, ``values_overrides/`` will refer to existing ``helm-toolkit`` functions to avoid repeating ourselves. This approach: * Proposes a common approach to software configuration, describing the distro/image specific differences for applications. * Exposes security/configuration features of software, allowing deployers to configure software to their needs. * Allows different profiles of apache, should some charts require different args for example for the same kind of images, by using yaml dict merges features. Security Impact --------------- No direct impact, as there is no change in the current software/configuration location, merely a templating change. Performance Impact ------------------ No benchmark was done to evaluate: * the impact of exposing extra key/values in the helm chart ``values.yaml`` file (could possibly have a deployment speed/ram usage increase). * the impact of adding functionality in the ``helm-toolkit`` to deal with a common multi-distro aspect (could possibly increase helm chart rendering time) * the impact of adding extra conditionals in the helm charts, to deal with multi-distro aspect (if not using the approach above, or when using an alternative approach) The performance aspect of these point are restricted to deployment, and have no performance impact on operations. Alternatives ------------ * Not providing a support of multiple images. This leads to ease of maintainance and reduced gate impact, with the risk of having less contributors. For available overrides, users would have to provide many overrides themselves, while this spec proposes a common community approach. * Create conditionals in the helm charts. This is problematic, as the amount of conditionals will increase and will be harder to maintain. Overrides files are easy to sync between charts. * Only provide one way to configure software, and expect to always have the same versions. This is further away from the "image independent" contract, with extra burden: We will need to maintain a curated list of versions, deal with the differences of the defaults (selinux/apparmor profiles come to mind as path sensitive for example), and different expectations for operational teams ("The code is not where I expect it to be in the image"). Embracing difference could even allow deployers to have different expectations for images, for example: apache+mod_wsgi vs uwsgi standalone or uwsgi + nginx. Implementation ============== Assignee(s) ----------- Primary assignee: - evrardjp Work Items ---------- This spec will be worked helm chart by helm chart, starting with keystone. A few areas have been identified on changes required. Each of them will be a work item. #. Make webserver binary path/arguments templated using ``values.yaml``. As expressed above, this allows us to provide different overrides per image/distribution to automatically wire things. #. Dynamically alter webserver environment conditionally in the helm chart. For example, for apache, ensure the necessary modules to run openstack are available and loaded at helm chart deploy time. This will leverage the binaries listed in ``values.yaml``. These series of commands are distribution/image dependent, as commands to list modules to load might differ. However with a few parameters, we can get a very distro independent process which would allow us to load all the required apache modules. #. Alter webserver configuration per distro. Different distros have different expectations in terms of path (including a different series of files required), and it would make the operators' life easier by using their expected distro paths. Testing ======= No change in testing is required, *per se*. It is expected the new software configuration would be tested with the current practices. On top of that, the newly provided ``example_values/`` must aim for being tested **as soon as possible upon delivery**. Without tests, those examples will decrepit. The changes in CI pipelines for making use of ``example_values`` is outside the scope of this spec. Documentation Impact ==================== None more than this spec, as it should be relatively transparent for the user. However, extra documentation to explain the usage of ``value_overrides`` would be welcomed. References ========== None ================================================ FILE: doc/source/specs/neutron-multiple-sdns.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. ===================== Neutron multiple SDNs ===================== Blueprint: neutron-multiple-sdns_ .. _neutron-multiple-sdns: https://blueprints.launchpad.net/openstack-helm/+spec/neutron-multiple-sdns Problem Description =================== Currently OpenStack-Helm supports OpenVSwitch as a network virtualization engine. In order to support many possible backends (SDNs), changes are required in neutron chart and in deployment techniques. OpenStack-Helm can support every SDN solution that has Neutron plugin, either core_plugin or mechanism_driver. The Neutron reference architecture provides mechanism_drivers OpenVSwitch (OVS) and linuxbridge (LB) with ML2 core_plugin framework. Other networking services provided by Neutron are: #. L3 routing - creation of routers #. DHCP - auto-assign IP address and DNS info #. Metadata- Provide proxy for Nova metadata service Introducing a new SDN solution should consider how the above services are provided. It may be required to disable the built-in Neutron functionality. Proposed Change =============== To be able to install Neutron with multiple possible SDNs as networking plugin, Neutron chart should be modified to enable installation of base services with decomposable approach. This means that operator can define which components from base Neutron chart should be installed, and which should not. This plus proper configuration of Neutron chart would enable operator to flexibly provision OpenStack with chosen SDN. Every Kubernetes manifest inside Neutron chart can be enabled or disabled. That would provide flexibility to the operator, to choose which Neutron components are reusable with different type of SDNs. For example, neutron-server which is serving the API and configuring the database can be used with different types of SDN plugin, and provider of that SDN chart would not need to copy all logic from Neutron base chart to manage the API and database. The proposes change would be to add in :code:`neutron/values.yaml` new section with boolean values describing which Neutron's Kubernetes resources should be enabled: .. code-block:: yaml manifests: configmap_bin: true configmap_etc: true daemonset_dhcp_agent: true daemonset_l3_agent: true daemonset_metadata_agent: true daemonset_ovs_agent: true daemonset_ovs_db: true daemonset_ovs_vswitchd: true deployment_server: true deployment_rpc_server: true ingress_server: true job_db_init: true job_db_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true pdb_server: true secret_db: true secret_keystone: true service_ingress_server: true service_server: true Then, inside Kubernetes manifests, add global if statement, deciding if given manifest should be declared on Kubernetes API, for example :code:`neutron/templates/daemonset-ovs-agent.yaml`: .. code-block:: yaml {{- if .Values.manifests.daemonset_ovs_agent }} # Licensed under the Apache License, Version 2.0 (the "License"); ... - name: libmodules hostPath: path: /lib/modules - name: run hostPath: path: /run {{- end }} If :code:`.Values.manifests.daemonset_ovs_agent` will be set to false, neutron ovs agent would not be launched. In that matter, other type of L2 or L3 agent on compute node can be run. To enable new SDN solution, there should be separate chart created, which would handle the deployment of service, setting up the database and any related networking functionality that SDN is providing. Use case -------- Let's consider how new SDN can take advantage of disaggregated Neutron services architecture. First assumption is that neutron-server functionality would be common for all SDNs, as it provides networking API, database management and Keystone interaction. Required modifications are: #. Configuration in :code:`neutron.conf` and :code:`ml2_conf.ini` #. Providing the neutron plugin code. The code can be supplied as modified neutron server image, or plugin can be mounted to original image. The :code:`manifests` section in :code:`neutron/values.yaml` should be enabled for below components: .. code-block:: yaml manifests: # neutron-server components: configmap_bin: true configmap_etc: true deployment_server: true deployment_rpc_server: true ingress_server: true job_db_init: true job_db_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true pdb_server: true secret_db: true secret_keystone: true service_ingress_server: true service_server: true Next, Neutron services like L3 routing, DHCP and metadata serving should be considered. If SDN provides its own implementation, the Neutron's default one should be disabled: .. code-block:: yaml manifests: daemonset_dhcp_agent: false daemonset_l3_agent: false daemonset_metadata_agent: false Provision of those services should be included inside SDN chart. The last thing to be considered is VM network virtualization. What engine does SDN use? It is OpenVSwitch, Linux Bridges or l3 routing (no l2 connectivity). If SDN is using the OpenVSwitch, it can take advantage of existing OVS daemonsets. Any modification that would be required to OVS manifests can be included in base Neutron chart as a configurable option. In that way, the features of OVS can be shared between different SDNs. When using the OVS, default Neutron L2 agent should be disabled, but OVS-DB and OVS-vswitchd can be left enabled. .. code-block:: yaml manifests: # Neutron L2 agent: daemonset_ovs_agent: false # OVS tool: daemonset_ovs_db: true daemonset_ovs_vswitchd: true Security Impact --------------- No security impact. Performance Impact ------------------ VM networking performance would be dependent of SDN used. Alternatives ------------ Alternatives to decomposable Neutron chart would be to copy whole Neutron chart and create spin-offs with new SDN enabled. This approach has drawbacks of maintaining the whole neutron chart in many places, and copies of standard services may be out of sync with OSH improvements. This implies constant maintenance effort to up to date. Implementation ============== Assignee(s) ----------- Primary assignees: * korzen (Artur Korzeniewski) * portdirect (Pete Birley) Work Items ---------- #. Implement decomposable Neutron chart #. Add Linux Bridge as first alternative for OVS - separate spec needed. #. Add one SDN to see if proposed change is working OK - separate spec needed. Testing ======= First reasonable testing in gates would be to setup Linux Bridge and check if VM network connectivity is working. Documentation Impact ==================== Documentation of how new SDN can be enabled, how Neutron should be configured. Also, for each new SDN that would be incorporated, the architecture overview should be provided. References ========== ================================================ FILE: doc/source/specs/nginx-sidecar.rst ================================================ ============= Nginx Sidecar ============= Blueprint: https://blueprints.launchpad.net/openstack-helm/+spec/nginx-sidecar Problem Description =================== In a secured deployment, TLS certificates are used to protect the transports amongst the various components. In some cases, this requires additional mechanism to handle TLS offloading and to terminate the connection gracefully: * services do not handle TLS offloading and termination, * services whose native handling of TLS offloading and termination cause major performance impact, for example, eventlet. Proposed Change =============== This specification proposes to add a nginx sidecar container to the pod for service that requires the tls offloading. The nginx can be used to handle the TLS offoading and terminate the TLS connection, and routes the traffic to the service via localhost (127.0.0.1). Security Impact --------------- This enhances the system's security design by allowing pods with services that cannot natively manage TLS to secure the traffic to the service pod. Performance Impact ------------------ There is no significant performance impact as the traffic will be locally routed (via 127.0.0.1) and may potentially improve performance for services whose native TLS handling is inefficient. Alternatives ------------ * Instead of using nginx, haproxy can be used instead. Implementation ============== Assignee(s) ----------- Primary assignee: Pete Birley Work Items ---------- * Update ``helm toolkit`` to provide snippet to create the nginx sidecar container for the services that require it. * Update service charts to use the updated ``helm toolkit``. * Update relevant Documentation. Testing ======= The testing will be performed by the OpenStack-Helm gate to demonstrate the sidecar container correctly routes traffic to the correct services. Documentation Impact ==================== OpenStack-Helm documentation will be updated to indicate the usage of the nginx sidecar. ================================================ FILE: doc/source/specs/osh-1.0-requirements.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. =============================== OpenStack-Helm 1.0 Requirements =============================== Topic: osh-1.0-requirements_ .. _osh-1.0-requirements: https://review.openstack.org/#/q/topic:bp/osh-1.0-requirements Problem Description =================== OpenStack-Helm has undergone rapid development and maturation over its lifetime, and is nearing the point of real-world readiness. This spec details the functionality that must be implemented in OpenStack-Helm for it to be considered ready for a 1.0 release, as well as for general use. Use case --------- This spec describes a point-in-time readiness for OpenStack-Helm 1.0, after which it will be for historical reference only. Proposed Change =============== The proposed requirements for a 1.0 release are as follows: Gating ------ A foundational requirement of 1.0 readiness is the presence of robust gating that will ensure functionality, backward compatibility, and upgradeability. This will allow development to continue and for support for new versions of OpenStack to be added post-1.0. The following gating requirements must be met: **Helm test for all charts** Helm test is the building block for all gating. Each chart must integrate a helm-test script which validates proper functionality. This is already a merge criterion for new charts, but a handful of older charts still need for helm test functionality to be added. No additional charts will be merged prior to 1.0 unless they meet this requirement (and others in this document). **Resiliency across reboots** All services should survive node reboots, and their functionality validated following a reboot by a gate. **Upgrades** Gating must prove that upgrades from each supported OpenStack version to the next operate flawlessly, using the default image set (LOCI). Specifically, each OpenStack chart should be upgraded from one release to the next, and each infrastructure service from one minor version to the next. Both the container image and configuration must be modified as part of this upgrade. At minimum, Newton to Ocata upgrade must be validated for the 1.0 release. Code Completion and Refactoring ------------------------------- A number of in-progress and planned development efforts must be completed prior to 1.0, to ensure a stable OpenStack-Helm interface thereafter. **Charts in the appropriate project** All charts should migrate to their appropriate home project as follows: - OpenStack-Helm for OpenStack services - OpenStack-Helm-Infra for supporting services - OpenStack-Helm-Addons for ancillary services In particular, these charts must move to OpenStack-Helm-Infra: - ceph - etcd - ingress - ldap - libvirt - mariadb - memcached - mongodb - openvswitch - postgresql - rabbitmq **Combined helm-toolkit** Currently both OpenStack-Helm and OpenStack-Helm-Infra have their own parallel versions of the Helm-Toolkit library chart. They must be combined into a single chart in OpenStack-Helm-Infra prior to 1.0. **Standardization of manifests** Work is underway to refactor common manifest patterns into reusable snippets in Helm-Toolkit. The following manifests have yet to be combined: - Database drop Job - Prometheus exporters - API Deployments - Worker Deployments - StatefulSets - CronJobs - Etc ConfigMaps - Bin ConfigMaps **Standardization of values** OpenStack-Helm has developed a number of conventions around the format and ordering of charts' ``values.yaml`` file, in support of both reusable Helm-Toolkit functions and ease of developer ramp-up. For 1.0 readiness, OpenStack-Helm must cement these conventions within a spec, as well as the ordering of ``values.yaml`` keys. These conventions must then be gated to guarantee conformity. The spec in progress can be found here [1]_. **Inclusion of all core services** Charts for all core OpenStack services must be present to achieve 1.0 releasability. The only core service outstanding at this time is Swift. **Split Ceph chart** The monolithic Ceph chart does not allow for following Ceph upgrade best practices, namely to upgrade Mons, OSDs, and client services in that order. The Ceph chart must therefore be split into at least three charts (one for each of the above upgrade phases) prior to 1.0 to ensure smooth in-place upgradability. **Values-driven config files** In order to maximize flexibility for operators, and to help facilitate upgrades to newer versions of containerized software without editing the chart itself, all configuration files will be specified dynamically based on ``values.yaml`` and overrides. In most cases the config files will be generated based on the YAML values tree itself, and in some cases the config file content will be specified in ``values.yaml`` as a string literal. Documentation ------------- Comprehensive documentation is key to the ability for real-world operators to benefit from OpenStack-Helm, and so it is a requirement for 1.0 releasability. The following outstanding items must be completed from a documentation perspective: **Document version requirements** Version requirements for the following must be documented and maintained: - Kubernetes - Helm - Operating system - External charts (Calico) **Document Kubernetes requirements** OpenStack-Helm supports a "bring your own Kubernetes" paradigm. Any particular k8s configuration or feature requirements must be documented. - Hosts must use KubeDNS / CoreDNS for resolution - Kubernetes must enable mount propagation (until it is enabled by default) - Helm must be installed Examples of how to set up the above under KubeADM and KubeSpray-based clusters must be documented as well. **OpenStack-Helm release process** The OpenStack-Helm release process will be somewhat orthogonal to the OpenStack release process, and the differences and relationship between the two must be documented in a spec. This will help folks quickly understand why OpenStack-Helm is a Release-Independent project from an OpenStack perspective. **Release notes** Release notes for the 1.0 release must be prepared, following OpenStack best practices. The criteria for future changes that should be included in release notes in an ongoing fashion must be defined / documented as well. - ``values.yaml`` changes - New charts - Any other changes to the external interface of OpenStack-Helm **LMA Operations Guide** A basic Logging, Monitoring, and Alerting-oriented operations guide must be in place, illustrating for operators (and developers) how to set up and use an example LMA setup for OpenStack and supporting services. It will include instructions on how to perform basic configuration and how to access and use the user interfaces at a high level. It will also link out to more detailed documentation for the LMA tooling itself. Process and Tooling ------------------- To facilitate effective collaboration and communication across the OpenStack-Helm community team, work items for the enhancements above will be captured in Storyboard. Therefore, migration from Launchpad to Storyboard must be accomplished prior to the 1.0 release. Going forward, Storyboard will be leveraged as a tool to collaboratively define and communicate the OpenStack-Helm roadmap. Security Impact --------------- No impact Performance Impact ------------------ No impact Alternatives ------------ This spec lays out the criteria for a stable and reliable 1.0 release, which can serve as the basis for real-world use as well as ongoing development. The alternative approaches would be to either iterate indefinitely without defining a 1.0 release, which would fail to signal to operators the point at which the platform is ready for real-world use; or, to define a 1.0 release which fails to satisfy key features which real-world operators need. Implementation ============== This spec describes a wide variety of self-contained work efforts, which will be implemented individually by the whole OpenStack-Helm team. Assignee(s) ----------- Primary assignee: - mattmceuen (Matt McEuen ) for coordination - powerds (DaeSeong Kim ) for the ``values.yaml`` ordering spec [1]_ - portdirect (Pete Birley ) for the release management spec [2]_ - randeep.jalli (Randeep Jalli ) and renmak (Renis Makadia ) for splitting up the Ceph chart - rwellum (Rich Wellum ) for coordination of Storyboard adoption - Additional assignees TBD Work Items ---------- See above for the list of work items. Testing ======= See above for gating requirements. Documentation Impact ==================== See above for documentation requirements. References ========== .. [1] https://review.openstack.org/#/c/552485/ .. [2] TODO - release management spec ================================================ FILE: doc/source/specs/osh-lma-stack.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. ===================================== OSH Logging, Monitoring, and Alerting ===================================== Blueprints: 1. osh-monitoring_ 2. osh-logging-framework_ .. _osh-monitoring: https://blueprints.launchpad.net/openstack-helm/+spec/osh-monitoring .. _osh-logging-framework: https://blueprints.launchpad.net/openstack-helm/+spec/osh-logging-framework Problem Description =================== OpenStack-Helm currently lacks a centralized mechanism for providing insight into the performance of the OpenStack services and infrastructure components. The log formats of the different components in OpenStack-Helm vary, which makes identifying causes for issues difficult across services. To support operational readiness by default, OpenStack-Helm should include components for logging events in a common format, monitoring metrics at all levels, alerting and alarms for those metrics, and visualization tools for querying the logs and metrics in a single pane view. Platform Requirements ===================== Logging Requirements -------------------- The requirements for a logging platform include: 1. All services in OpenStack-Helm log to stdout and stderr by default 2. Log collection daemon runs on each node to forward logs to storage 3. Proper directories mounted to retrieve logs from the node 4. Ability to apply custom metadata and uniform format to logs 5. Time-series database for logs collected 6. Backed by highly available storage 7. Configurable log rotation mechanism 8. Ability to perform custom queries against stored logs 9. Single pane visualization capabilities Monitoring Requirements ----------------------- The requirements for a monitoring platform include: 1. Time-series database for collected metrics 2. Backed by highly available storage 3. Common method to configure all monitoring targets 4. Single pane visualization capabilities 5. Ability to perform custom queries against metrics collected 6. Alerting capabilities to notify operators when thresholds exceeded Use Cases ========= Logging Use Cases ----------------- Example uses for centralized logging include: 1. Record compute instance behavior across nodes and services 2. Record OpenStack service behavior and status 3. Find all backtraces for a tenant id's uuid 4. Identify issues with infrastructure components, such as RabbitMQ, mariadb, etc 5. Identify issues with Kubernetes components, such as: etcd, CNI, scheduler, etc 6. Organizational auditing needs 7. Visualize logged events to determine if an event is recurring or an outlier 8. Find all logged events that match a pattern (service, pod, behavior, etc) Monitoring Use Cases -------------------- Example OpenStack-Helm metrics requiring monitoring include: 1. Host utilization: memory usage, CPU usage, disk I/O, network I/O, etc 2. Kubernetes metrics: pod status, replica availability, job status, etc 3. Ceph metrics: total pool usage, latency, health, etc 4. OpenStack metrics: tenants, networks, flavors, floating IPs, quotas, etc 5. Proactive monitoring of stack traces across all deployed infrastructure Examples of how these metrics can be used include: 1. Add or remove nodes depending on utilization 2. Trigger alerts when desired replicas fall below required number 3. Trigger alerts when services become unavailable or unresponsive 4. Identify etcd performance that could lead to cluster instability 5. Visualize performance to identify trends in traffic or utilization over time Proposed Change =============== Logging ------- Fluentd, Elasticsearch, and Kibana meet OpenStack-Helm's logging requirements for capture, storage and visualization of logged events. Fluentd runs as a daemonset on each node and mounts the /var/lib/docker/containers directory. The Docker container runtime engine directs events posted to stdout and stderr to this directory on the host. Fluentd should then declare the contents of that directory as an input stream, and use the fluent-plugin-elasticsearch plugin to apply the Logstash format to the logs. Fluentd will also use the fluentd-plugin-kubernetes-metadata plugin to write Kubernetes metadata to the log record. Fluentd will then forward the results to Elasticsearch, which indexes the logs in a logstash-* index by default. The resulting logs can then be queried directly through Elasticsearch, or they can be viewed via Kibana. Kibana offers a dashboard that can create custom views on logged events, and Kibana integrates well with Elasticsearch by default. The proposal includes the following: 1. Helm chart for Fluentd 2. Helm chart for Elasticsearch 3. Helm chart for Kibana All three charts must include sensible configuration values to make the logging platform usable by default. These include: proper input configurations for Fluentd, proper metadata and formats applied to the logs via Fluentd, sensible indexes created for Elasticsearch, and proper configuration values for Kibana to query the Elasticsearch indexes previously created. Monitoring ---------- Prometheus and Grafana meet OpenStack-Helm's monitoring requirements. The Prometheus monitoring tool provides the ability to scrape targets for metrics over HTTP, and it stores these metrics in Prometheus's time-series database. The monitoring targets can be discovered via static configuration in Prometheus or through service discovery. Prometheus includes a querying language that provides meaningful queries against the metrics gathered and supports the creation of rules to measure these metrics against for alerting purposes. It also supports a wide range of Prometheus exporters for existing services, including Ceph and OpenStack. Grafana supports Prometheus as a data source, and provides the ability to view the metrics gathered by Prometheus in a single pane dashboard. Grafana can be bootstrapped with dashboards for each target scraped, or the dashboards can be added via Grafana's web interface directly. To meet OpenStack-Helm's alerting needs, Alertmanager can be used to interface with Prometheus and send alerts based on Prometheus rule evaluations. The proposal includes the following: 1. Helm chart for Prometheus 2. Helm chart for Alertmanager 3. Helm chart for Grafana 4. Helm charts for any appropriate Prometheus exporters All charts must include sensible configuration values to make the monitoring platform usable by default. These include: static Prometheus configurations for the included exporters, static dashboards for Grafana mounted via configMaps and configurations for Alertmanager out of the box. Security Impact --------------- All services running within the platform should be subject to the security practices applied to the other OpenStack-Helm charts. Performance Impact ------------------ To minimize the performance impacts, the following should be considered: 1. Sane defaults for log retention and rotation policies 2. Identify opportunities for improving Prometheus's operation over time 3. Elasticsearch configured to prevent memory swapping to disk 4. Elasticsearch configured in a highly available manner with sane defaults Implementation ============== Assignee(s) ----------- Primary assignees: srwilker (Steve Wilkerson) portdirect (Pete Birley) lr699s (Larry Rensing) Work Items ---------- 1. Fluentd chart 2. Elasticsearch chart 3. Kibana chart 4. Prometheus chart 5. Alertmanager chart 6. Grafana chart 7. Charts for exporters: kube-state-metrics, ceph-exporter, openstack-exporter? All charts should follow design approaches applied to all other OpenStack-Helm charts, including the use of helm-toolkit. All charts require valid and sensible default values to provide operational value out of the box. Testing ======= Testing should include Helm tests for each of the included charts as well as an integration test in the gate. Documentation Impact ==================== Documentation should be included for each of the included charts as well as documentation detailing the requirements for a usable monitoring platform, preferably with sane default values out of the box. ================================================ FILE: doc/source/specs/support-OCI-image-registry-with-authentication-turned-on.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. ======================================================== Support OCI image registry with authentication turned on ======================================================== Blueprint: support-oci-image-registry-with-authentication-turned-on_ .. _support-oci-image-registry-with-authentication-turned-on: https://blueprints.launchpad.net/openstack-helm/+spec/support-oci-image-registry-with-authentication-turned-on Problem Description =================== In the current openstack-helm, all charts provide an ``images:`` section in their ``values.yaml`` that have the container images references. By default, the container images are all downloaded from a registry hosted by Docker or Quay. However, the image references can be overridden by operators to download images from any OCI image registry. In the case that the OCI image registry has authentication turned on, kubelet would fail to download the images because the current Openstack-Helm does not provide a way to pass the OCI image registry credentials to kubernetes when pulling images. Use case ======== Operators should be able to use Openstack-Helm to deploy containerized openstack services with a docker registry has authentication turned on. Proposed Change =============== To be able to pull images from an OCI image registry which has the authentication turned on, kubernetes needs credentials. For each chart, a new ``endpoints:`` entry could be added in ``values.yaml`` to provide image credentials, a secret needs to be generated to hold the credentials and the ``imagePullSecrets:`` field should be added in each service account to specify which secret should be used to get the credentials from when pulling images by kubelet. The detailed proposes change are described as following: 1. For each chart, add a new entry ``oci_image_registry:`` under ``endpoints:`` in ``values.yaml``. The entry ``oci_image_registry:`` has the ``auth:`` section which provides the credentials for accessing registry images and an option ``enabled:`` to determine whether images authentication is required or not. The registry basic information would also be included for generating the registry URL by the endpoint lookup functions. Also add a new entry ``oci_image_registry:`` under ``secrets:`` to indicate the secret name. In order to create the secret that holds the provided credentials, add a new component ``secret_registry`` in ``manifests:`` section. For example: .. code-block:: yaml secrets: oci_image_registry: nova: nova-oci-image-registry-key endpoints: ... oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false nova: username: nova password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: 5000 manifests: secret_registry: true The option ``enabled:`` under ``auth:`` and the manifest ``secret_registry:`` provide the ability for operator to determine whether they would like to have secrets generated and passed to kubernetes for pulling images. The secret would not be created with the default option ``enabled: false`` and ``secret_registry: true``. To enable secret creation, operator should override ``enabled:`` to true. The above example shows the default credentials, operator should override the ``username:`` and ``password:`` under ``auth:`` section to provide their own credentials. Then, add manifest ``secret-registry.yaml`` in ``templates/`` to leverage the function that will be added in helm-toolkit to create the secret. For example: .. code-block:: yaml {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} 2. Add a helm-toolkit function ``helm-toolkit.manifests.secret_registry`` to create a manifest for secret generation. For example: .. code-block:: rst {{- define "helm-toolkit.manifests.secret_registry" -}} {{- $envAll := index . "envAll" }} {{- $registryUser := index . "registryUser" }} {{- $secretName := index $envAll.Values.secrets.oci_image_registry $registryUser }} {{- $registryHost := tuple "oci_image_registry" "internal" $envAll | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{- $registryPort := tuple "oci_image_registry" "internal" "registry" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $imageCredentials := index $envAll.Values.endpoints.oci_image_registry.auth $registryUser }} {{- $dockerAuthToken := printf "%s:%s" $imageCredentials.username $imageCredentials.password | b64enc }} {{- $dockerAuth := printf "{\"auths\": {\"%s:%s\": {\"auth\": \"%s\"}}}" $registryHost $registryPort $dockerAuthToken | b64enc }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: {{ $dockerAuth }} {{- end }} 3. Reference the created secret by adding the ``imagePullSecrets:`` field to ServiceAccount resource template [2]_ in ``helm-toolkit/snippets/_kubernetes_pod_rbac_serviceaccount.tpl``. To handle it as optional, the field is wrapped in a conditional. For example, .. code-block:: yaml --- apiVersion: v1 kind: ServiceAccount ... {{- if $envAll.Values.endpoints.oci_image_registry.auth.enabled }} imagePullSecrets: - name: {{ index $envAll.Values.secrets.oci_image_registry $envAll.Chart.Name }} {{- end }} If .Values.endpoints.oci_image_registry.auth.enabled will be set to true, then any containers created with the current service account will have the ``imagePullSecrets`` automatically added to their spec and the secret will be passed to kubelet to be used for pulling images. Security Impact --------------- The credentials for the registry could be exposed by running the kubectl command: kubectl get secret --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode Authentication should be enabled for normal users to access Kube API server via either kubectl command or kube REST API call. Performance Impact ------------------ No performance impact Alternatives ------------ Before using Openstack-Helm to deploy openstack services, 1. Put .docker/config.json in docker/kubelet root directory on all nodes 2. Pre-pulling images on all nodes But above alternatives have limitations and security impact. i.e...require root access to configure on all nodes, all pods can read any configured private registries, all pods can use any images cached on a node [1]_ Implementation ============== Assignee(s) ----------- Primary assignees: * Angie Wang (angiewang) Work Items ---------- #. Provide the credentials and add the manifest across all charts in OSH and OSH-infra #. Update helm-toolkit to provide manifest to create secret for registry authentication #. Update helm-toolkit serviceaccount template to pass the secret in a conditional Testing ======= None Documentation Impact ==================== Documentation of how to enable the registry secret generation References ========== .. [1] https://kubernetes.io/docs/concepts/containers/images .. [2] https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account ================================================ FILE: doc/source/specs/support-linux-bridge-on-neutron.rst ================================================ .. This work is licensed under a Creative Commons Attribution 3.0 Unported License. http://creativecommons.org/licenses/by/3.0/legalcode .. ========================================== Support linux bridge on neutron helm chart ========================================== Blueprint: support-linux-bridge-on-neutron_ .. _support-linux-bridge-on-neutron: https://blueprints.launchpad.net/openstack-helm/+spec/support-linux-bridge-on-neutron Problem Description =================== This specification will address enablement of LinuxBridge network virtualization for OpenStack Helm (OSH). LinuxBridge is second available networking technology in Neutron's reference architecture. The first one is OVS, that is already implemented in OSH. The LinuxBridge (LB) is Neutron's L2 agent, using linux kernel bridges as network configuration for VMs. Both OVS and LB are part of Neutron's Modular Layer 2 (ML2) framework, allowing to simultaneously utilize the variety of layer 2 networking technologies. Other services inside Neutron reference stack (L3/DHCP/metadata agents) are dependent on L2 connectivity agent. Thus, replacing OVS with LB would cause changes in mentioned services configuration. Proposed Change =============== LinuxBridge installation with neutron chart takes advantaged of decomposable neutron chart in OSH. LinuxBridge agent will be added as daemonset, similarly how OVS is implemented. New value :code:`daemonset_lb_agent` should be added in :code:`neutron/values.yaml` in :code:`manifests` section: .. code-block:: yaml manifests: (...) daemonset_dhcp_agent: true daemonset_l3_agent: true daemonset_lb_agent: false daemonset_metadata_agent: true daemonset_ovs_agent: true daemonset_ovs_db: true daemonset_ovs_vswitchd: true (...) By default, :code:`daemonset_lb_agent` will be set to false to remain default behaviour of installing OVS as networking agent. Installing OVS requires Kubernetes worker node labeling with tag :code:`openvswitch=enabled`. To mark nodes where LB should be used, new tag will be introduced: :code:`linuxbridge=enabled`. LinuxBridge should support external bridge configuration, as well as auto bridge add mechanism implemented for OVS. As mentioned before, configuration of L3/DHCP/metadata agent should be adjusted to use LinuxBridge, sample configuration override: .. code-block:: yaml conf: neutron: default: agent: interface_driver: linuxbridge ml2_conf: ml2_type_flat: neutron: ml2: mechanism_drivers: linuxbridge, l2population dhcp_agent: default: neutron: base: agent: interface_driver: linuxbridge l3_agent: default: neutron: base: agent: interface_driver: linuxbridge Having services configured, also the services pod dependencies should be updated to reflect the new kind on L2 agent: .. code-block:: yaml dependencies: dhcp: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent metadata: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent l3: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent LinuxBridge should be also enabled in :code:`manifests` section: .. code-block:: yaml manifests: daemonset_lb_agent: true daemonset_ovs_agent: false daemonset_ovs_db: false daemonset_ovs_vswitchd: false In above example OVS and Neutron OVS agent are disabled. Another place where Neutron L2 agent should be pointed is dependencies list in other OpenStack projects. Currently, :code:`nova-compute` has dependency for :code:`ovs-agent` in :code:`nova/values.yaml`, it should be changed to: .. code-block:: yaml dependencies: compute: daemonset: - lb-agent Security Impact --------------- No security impact. Performance Impact ------------------ VM networking performance would be dependent on linux bridge implementation. Alternatives ------------ OVS is an alternative in Neutron reference architecture. It is already in tree. Implementation ============== Assignee(s) ----------- Primary assignees: * korzen (Artur Korzeniewski) Work Items ---------- #. Add LinuxBridge daemonset #. Add gate job testing VM network connectivity #. Add documentation on how to use LinuxBridge Testing ======= Gate job testing VM network connectivity. Documentation Impact ==================== Documentation on how to use LinuxBridge with Neutron chart. References ========== ================================================ FILE: doc/source/specs/tenant-ceph.rst ================================================ ================================ Deploying multuple Ceph clusters ================================ This guide shows how to setup multiple Ceph clusters. One Ceph cluster will be used for k8s RBD storage and while other Ceph cluster will be for tenant facing storage backend for Cinder and Glance. Ceph Clusters: ============== Ceph for RBD: ------------- This Ceph cluster will be used for k8s RBD storage (pvc). This can be used by entire Kubernetes cluster. - k8s namespace: ceph - mon endpoint port: 6789 - mgr endpoint port: 7000 - metric port: 9283 - storage classes: general (rbd based for pvc) - no ceph-mds and ceph-rgw Ceph for Tenant: ---------------- This Ceph cluster will be used by Cinder and Glance as storage backend. - k8s namespace: tenant-ceph - mon endpoint port: 6790 - mgr endpoint port: 7001 - metric port: 9284 - no storage classes - no ceph-mds Env Setup: ========== 6 VM based hosts (node1, node2, node3, node4, node5, node6) k8s node labels: ---------------- ``Ceph for RBD related labels:`` Labels assigned to nodes: node1, node2, node3: openstack-control-plane=enabled, ceph-mon=enabled, ceph-mgr=enabled, ceph-rgw=enabled, ceph-mds=enabled, ceph-osd=enabled ``Ceph for Tenant related labels:`` Labels assigned to nodes: node1, node2, node3: tenant-ceph-control-plane=enabled, ceph-mon-tenant=enabled, ceph-mgr-tenant=enabled, ceph-rgw-tenant=enabled Labels assigned to nodes: node4, node5, node6: openstack-data-plane=enabled, openstack-compute-node=enabled, ceph-osd-tenant=enabled, openstack-data-plane=enabled ``k8s node list with labels`` After applying above labels, node labels should look like following. .. code-block:: console ubuntu@node1:~$ kubectl get nodes --show-labels=true NAME STATUS ROLES AGE VERSION LABELS node1 Ready 9m v1.10.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ceph-mds=enabled,ceph-mgr-tenant=enabled,ceph-mgr=enabled,ceph-mon-tenant=enabled,ceph-mon=enabled,ceph-osd=enabled,ceph-rgw-tenant=enabled,ceph-rgw=enabled,kubernetes.io/hostname=node1,linuxbridge=enabled,openstack-control-plane=enabled,openstack-helm-node-class=primary,openvswitch=enabled,tenant-ceph-control-plane=enabled node2 Ready 6m v1.10.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ceph-mds=enabled,ceph-mgr-tenant=enabled,ceph-mgr=enabled,ceph-mon-tenant=enabled,ceph-mon=enabled,ceph-osd=enabled,ceph-rgw-tenant=enabled,ceph-rgw=enabled,kubernetes.io/hostname=node2,linuxbridge=enabled,openstack-control-plane=enabled,openstack-helm-node-class=general,openvswitch=enabled,tenant-ceph-control-plane=enabled node3 Ready 6m v1.10.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ceph-mds=enabled,ceph-mgr-tenant=enabled,ceph-mgr=enabled,ceph-mon-tenant=enabled,ceph-mon=enabled,ceph-osd=enabled,ceph-rgw-tenant=enabled,ceph-rgw=enabled,kubernetes.io/hostname=node3,linuxbridge=enabled,openstack-control-plane=enabled,openstack-helm-node-class=general,openvswitch=enabled,tenant-ceph-control-plane=enabled node4 Ready 7m v1.10.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ceph-osd-tenant=enabled,kubernetes.io/hostname=node4,linuxbridge=enabled,openstack-compute-node=enabled,openstack-data-plane=enabled,openstack-helm-node-class=general,openvswitch=enabled node5 Ready 6m v1.10.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ceph-osd-tenant=enabled,kubernetes.io/hostname=node5,linuxbridge=enabled,openstack-compute-node=enabled,openstack-data-plane=enabled,openstack-helm-node-class=general,openvswitch=enabled node6 Ready 6m v1.10.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,ceph-osd-tenant=enabled,kubernetes.io/hostname=node6,linuxbridge=enabled,openstack-compute-node=enabled,openstack-data-plane=enabled,openstack-helm-node-class=general,openvswitch=enabled Test Steps: =========== 1) Prepare scripts: ------------------- OpenStack-Helm multinode guide includes scripts which are used to specify overrides and deploy charts. Duplicate scripts as shows below for later use. .. code-block:: console cd tools/deployment/multinode/ cp 030-ceph.sh 030-tenant-ceph.sh cp 040-ceph-ns-activate.sh 040-tenant-ceph-ns-activate.sh cp 090-ceph-radosgateway.sh 090-tenant-ceph-radosgateway.sh 2) Deploy ingress chart: ------------------------ Script to update and execute: ``020-ingress.sh`` Update script to include namespace ``tenant-ceph`` as shown below. .. code-block:: yaml for NAMESPACE in openstack ceph tenant-ceph; do Execute script. 3) Deploy Ceph for RBD: ----------------------- Script to update and execute: ``030-ceph.sh`` Update script with following overrides. Note: The original RBD provisioner is now deprecated. The CSI RBD provisioner is selected here. If you prefer the original non-CSI RBD provisioner, then set rbd_provisioner to true instead. .. code-block:: yaml deployment: storage_secrets: true ceph: true rbd_provisioner: false csi_rbd_provisioner: true cephfs_provisioner: false client_secrets: false endpoints: ceph_mon: namespace: ceph port: mon: default: 6789 ceph_mgr: namespace: ceph port: mgr: default: 7000 metrics: default: 9283 manifests: deployment_mds: false bootstrap: enabled: true conf: pool: target: osd: 3 storageclass: rbd: ceph_configmap_name: ceph-etc cephfs: provision_storage_class: false ceph_mgr_modules_config: prometheus: server_port: 9283 monitoring: prometheus: enabled: true ceph_mgr: port: 9283 .. note:: ``cephfs_provisioner: false`` and ``provision_storage_class: false`` are set to false to disable cephfs. ``deployment_mds: false`` is set to disable ceph-mds Execute script. 4) Deploy MariaDB, RabbitMQ, Memcached and Keystone: ---------------------------------------------------- Use default overrides and execute following scripts as per OSH guide steps: - ``040-ceph-ns-activate.sh`` - ``050-mariadb.sh`` - ``060-rabbitmq.sh`` - ``070-memcached.sh`` - ``080-keystone.sh`` Result from Steps 2, 3, 4: -------------------------- ``Ceph Pods`` .. code-block:: console ubuntu@node1:~$ kubectl get pods -n ceph -o wide NAME READY STATUS RESTARTS AGE IP NODE ceph-bootstrap-g45qc 0/1 Completed 0 28m 192.168.5.16 node3 ceph-mds-keyring-generator-gsw4m 0/1 Completed 0 28m 192.168.2.11 node2 ceph-mgr-5746dd89db-mmrg4 1/1 Running 0 23m 10.0.0.12 node2 ceph-mgr-5746dd89db-q25lt 1/1 Running 0 23m 10.0.0.9 node3 ceph-mgr-keyring-generator-t4s8l 0/1 Completed 0 28m 192.168.2.9 node2 ceph-mon-6n4hk 1/1 Running 0 28m 10.0.0.9 node3 ceph-mon-b2d9w 1/1 Running 0 28m 10.0.0.12 node2 ceph-mon-check-d85994946-2dcpg 1/1 Running 0 28m 192.168.5.17 node3 ceph-mon-keyring-generator-rmvfz 0/1 Completed 0 28m 192.168.2.10 node2 ceph-mon-svkdl 1/1 Running 0 28m 10.0.0.16 node1 ceph-osd-default-83945928-2mhrj 1/1 Running 0 25m 10.0.0.9 node3 ceph-osd-default-83945928-gqbd9 1/1 Running 0 25m 10.0.0.16 node1 ceph-osd-default-83945928-krrl8 1/1 Running 0 25m 10.0.0.12 node2 ceph-osd-keyring-generator-zg8s5 0/1 Completed 0 28m 192.168.0.195 node1 ceph-rbd-pool-92nbv 0/1 Completed 0 23m 192.168.5.18 node3 ceph-rbd-provisioner-599895579c-jl6qk 1/1 Running 0 21m 192.168.2.15 node2 ceph-rbd-provisioner-599895579c-n4hbk 1/1 Running 0 21m 192.168.5.19 node3 ceph-rgw-keyring-generator-2wv4j 0/1 Completed 0 28m 192.168.5.15 node3 ceph-storage-keys-generator-8vzrx 0/1 Completed 0 28m 192.168.2.12 node2 ingress-796d8cf8d6-9khkm 1/1 Running 0 28m 192.168.2.6 node2 ingress-796d8cf8d6-nznvc 1/1 Running 0 28m 192.168.5.12 node3 ingress-error-pages-54454dc79b-bgc5m 1/1 Running 0 28m 192.168.2.5 node2 ingress-error-pages-54454dc79b-hwnv4 1/1 Running 0 28m 192.168.5.7 node3 ``Openstack Pods:`` .. code-block:: console ubuntu@node1:~$ kubectl get pods -n openstack -o wide NAME READY STATUS RESTARTS AGE IP NODE ceph-openstack-config-ceph-ns-key-generator-mcxrs 0/1 Completed 0 11m 192.168.2.16 node2 ingress-7b4bc84cdd-7wslz 1/1 Running 0 30m 192.168.5.5 node3 ingress-7b4bc84cdd-z6t2z 1/1 Running 0 30m 192.168.2.4 node2 ingress-error-pages-586c7f86d6-7m58l 1/1 Running 0 30m 192.168.5.6 node3 ingress-error-pages-586c7f86d6-n9tzv 1/1 Running 0 30m 192.168.2.3 node2 keystone-api-7974676d5d-5k27d 1/1 Running 0 6m 192.168.5.24 node3 keystone-api-7974676d5d-cd9kv 1/1 Running 0 6m 192.168.2.21 node2 keystone-bootstrap-twfrj 0/1 Completed 0 6m 192.168.0.197 node1 keystone-credential-setup-txf5p 0/1 Completed 0 6m 192.168.5.25 node3 keystone-db-init-tjxgm 0/1 Completed 0 6m 192.168.2.20 node2 keystone-db-sync-zl9t4 0/1 Completed 0 6m 192.168.2.22 node2 keystone-domain-manage-thwdm 0/1 Completed 0 6m 192.168.0.198 node1 keystone-fernet-setup-qm424 0/1 Completed 0 6m 192.168.5.26 node3 keystone-rabbit-init-6699r 0/1 Completed 0 6m 192.168.2.23 node2 keystone-test 0/1 Completed 0 4m 192.168.3.3 node4 mariadb-ingress-84894687fd-wfc9b 1/1 Running 0 11m 192.168.2.17 node2 mariadb-ingress-error-pages-78fb865f84-bg8sg 1/1 Running 0 11m 192.168.5.20 node3 mariadb-server-0 1/1 Running 0 11m 192.168.5.22 node3 memcached-memcached-5db74ddfd5-m5gw2 1/1 Running 0 7m 192.168.2.19 node2 rabbitmq-rabbitmq-0 1/1 Running 0 8m 192.168.2.18 node2 rabbitmq-rabbitmq-1 1/1 Running 0 8m 192.168.5.23 node3 rabbitmq-rabbitmq-2 1/1 Running 0 8m 192.168.0.196 node1 ``Ceph Status`` .. code-block:: console ubuntu@node1:~$ kubectl exec -n ceph ceph-mon-b2d9w -- ceph -s cluster: id: 3e53e3b7-e5d9-4bab-9701-134687f4954e health: HEALTH_OK services: mon: 3 daemons, quorum node3,node2,node1 mgr: node3(active), standbys: node2 osd: 3 osds: 3 up, 3 in data: pools: 18 pools, 93 pgs objects: 127 objects, 218 MB usage: 46820 MB used, 186 GB / 232 GB avail pgs: 93 active+clean ``Ceph ConfigMaps`` .. code-block:: console ubuntu@node1:~$ kubectl get cm -n ceph NAME DATA AGE ceph-client-bin 7 25m ceph-client-etc 1 25m ceph-etc 1 23m ceph-mon-bin 10 29m ceph-mon-etc 1 29m ceph-osd-bin 7 27m ceph-osd-default 1 27m ceph-osd-etc 1 27m ceph-provisioners-ceph-provisioners-bin 4 23m ceph-templates 6 29m ingress-bin 2 30m ingress-ceph-nginx 0 30m ingress-conf 3 30m ingress-services-tcp 0 30m ingress-services-udp 0 30m ``ceph-mon-etc (ceph.conf)`` .. code-block:: console ubuntu@node1:~$ kubectl get cm -n ceph ceph-mon-etc -o yaml .. code-block:: yaml apiVersion: v1 data: ceph.conf: | [global] cephx = true cephx_cluster_require_signatures = true cephx_require_signatures = false cephx_service_require_signatures = false fsid = 3e53e3b7-e5d9-4bab-9701-134687f4954e mon_addr = :6789 mon_host = ceph-mon-discovery.ceph.svc.cluster.local:6789 [osd] cluster_network = 10.0.0.0/24 ms_bind_port_max = 7100 ms_bind_port_min = 6800 osd_max_object_name_len = 256 osd_mkfs_options_xfs = -f -i size=2048 osd_mkfs_type = xfs public_network = 10.0.0.0/24 kind: ConfigMap metadata: creationTimestamp: 2018-08-27T04:55:32Z name: ceph-mon-etc namespace: ceph resourceVersion: "3218" selfLink: /api/v1/namespaces/ceph/configmaps/ceph-mon-etc uid: 6d9fdcba-a9b5-11e8-bb1d-fa163ec12213 .. note:: Note that mon_addr and mon_host have default mon port 6789. ``k8s storageclass`` .. code-block:: console ubuntu@node1:~$ kubectl get storageclasses NAME PROVISIONER AGE general ceph.com/rbd 14m ``Ceph services`` .. code-block:: console ubuntu@node1:~$ kubectl get svc -n ceph NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ceph-mgr ClusterIP 10.111.185.73 7000/TCP,9283/TCP 27m ceph-mon ClusterIP None 6789/TCP 31m ceph-mon-discovery ClusterIP None 6789/TCP 31m ingress ClusterIP 10.100.23.32 80/TCP,443/TCP 32m ingress-error-pages ClusterIP None 80/TCP 32m ingress-exporter ClusterIP 10.109.196.155 10254/TCP 32m ``Ceph endpoints`` .. code-block:: console ubuntu@node1:~$ kubectl get endpoints -n ceph NAME ENDPOINTS AGE ceph-mgr 10.0.0.12:9283,10.0.0.9:9283,10.0.0.12:7000 + 1 more... 27m ceph-mon 10.0.0.12:6789,10.0.0.16:6789,10.0.0.9:6789 31m ceph-mon-discovery 10.0.0.12:6789,10.0.0.16:6789,10.0.0.9:6789 31m ingress 192.168.2.6:80,192.168.5.12:80,192.168.2.6:443 + 1 more... 32m ingress-error-pages 192.168.2.5:8080,192.168.5.7:8080 32m ingress-exporter 192.168.2.6:10254,192.168.5.12:10254 32m ``netstat ceph mon port`` .. code-block:: console ubuntu@node1: netstat -ntlp | grep 6789 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 10.0.0.16:6789 0.0.0.0:* LISTEN - ubuntu@node1: netstat -ntlp | grep 6790 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) ``Ceph secrets`` .. code-block:: console ubuntu@node1:~$ kubectl get secrets -n ceph NAME TYPE DATA AGE ceph-bootstrap-mds-keyring Opaque 1 34m ceph-bootstrap-mgr-keyring Opaque 1 34m ceph-bootstrap-osd-keyring Opaque 1 34m ceph-bootstrap-rgw-keyring Opaque 1 34m ceph-bootstrap-token-w2sqp kubernetes.io/service-account-token 3 34m ceph-client-admin-keyring Opaque 1 34m ceph-mds-keyring-generator-token-s9kst kubernetes.io/service-account-token 3 34m ceph-mgr-keyring-generator-token-h5sw6 kubernetes.io/service-account-token 3 34m ceph-mgr-token-hr88m kubernetes.io/service-account-token 3 30m ceph-mon-check-token-bfvgk kubernetes.io/service-account-token 3 34m ceph-mon-keyring Opaque 1 34m ceph-mon-keyring-generator-token-5gs5q kubernetes.io/service-account-token 3 34m ceph-mon-token-zsd6w kubernetes.io/service-account-token 3 34m ceph-osd-keyring-generator-token-h97wb kubernetes.io/service-account-token 3 34m ceph-osd-token-4wfm5 kubernetes.io/service-account-token 3 32m ceph-provisioners-ceph-rbd-provisioner-token-f92tw kubernetes.io/service-account-token 3 28m ceph-rbd-pool-token-p2nxt kubernetes.io/service-account-token 3 30m ceph-rgw-keyring-generator-token-wmfx6 kubernetes.io/service-account-token 3 34m ceph-storage-keys-generator-token-dq5ts kubernetes.io/service-account-token 3 34m default-token-j8h48 kubernetes.io/service-account-token 3 35m ingress-ceph-ingress-token-68rws kubernetes.io/service-account-token 3 35m ingress-error-pages-token-mpvhm kubernetes.io/service-account-token 3 35m pvc-ceph-conf-combined-storageclass kubernetes.io/rbd 1 34m ``Openstack secrets`` .. code-block:: console ubuntu@node1:~$ kubectl get secrets -n openstack NAME TYPE DATA AGE ceph-openstack-config-ceph-ns-key-cleaner-token-jj7n6 kubernetes.io/service-account-token 3 17m ceph-openstack-config-ceph-ns-key-generator-token-5sqfw kubernetes.io/service-account-token 3 17m default-token-r5knr kubernetes.io/service-account-token 3 35m ingress-error-pages-token-xxjxt kubernetes.io/service-account-token 3 35m ingress-openstack-ingress-token-hrvv8 kubernetes.io/service-account-token 3 35m keystone-api-token-xwczg kubernetes.io/service-account-token 3 12m keystone-bootstrap-token-dhnb6 kubernetes.io/service-account-token 3 12m keystone-credential-keys Opaque 2 12m keystone-credential-rotate-token-68lnk kubernetes.io/service-account-token 3 12m keystone-credential-setup-token-b2smc kubernetes.io/service-account-token 3 12m keystone-db-admin Opaque 1 12m keystone-db-init-token-brzkj kubernetes.io/service-account-token 3 12m keystone-db-sync-token-xzqj9 kubernetes.io/service-account-token 3 12m keystone-db-user Opaque 1 12m keystone-domain-manage-token-48gn5 kubernetes.io/service-account-token 3 12m keystone-etc Opaque 9 12m keystone-fernet-keys Opaque 2 12m keystone-fernet-rotate-token-djtzb kubernetes.io/service-account-token 3 12m keystone-fernet-setup-token-n9st2 kubernetes.io/service-account-token 3 12m keystone-keystone-admin Opaque 8 12m keystone-keystone-test Opaque 8 12m keystone-rabbit-init-token-pt5b2 kubernetes.io/service-account-token 3 12m keystone-rabbitmq-admin Opaque 1 12m keystone-rabbitmq-user Opaque 1 12m keystone-test-token-z8mb6 kubernetes.io/service-account-token 3 12m mariadb-db-root-password Opaque 1 17m mariadb-ingress-error-pages-token-cnrqp kubernetes.io/service-account-token 3 17m mariadb-ingress-token-gfrg4 kubernetes.io/service-account-token 3 17m mariadb-secrets Opaque 1 17m mariadb-token-pr5lp kubernetes.io/service-account-token 3 17m memcached-memcached-token-gq96p kubernetes.io/service-account-token 3 13m pvc-ceph-client-key kubernetes.io/rbd 1 17m rabbitmq-rabbitmq-token-5bj85 kubernetes.io/service-account-token 3 14m rabbitmq-test-token-w4clj kubernetes.io/service-account-token 3 14m ``Openstack PV list`` .. code-block:: console ubuntu@node1:~$ kubectl get pv -n openstack NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-348f4c52-a9b8-11e8-bb1d-fa163ec12213 256Mi RWO Delete Bound openstack/rabbitmq-data-rabbitmq-rabbitmq-0 general 15m pvc-4418c745-a9b8-11e8-bb1d-fa163ec12213 256Mi RWO Delete Bound openstack/rabbitmq-data-rabbitmq-rabbitmq-1 general 14m pvc-524d4213-a9b8-11e8-bb1d-fa163ec12213 256Mi RWO Delete Bound openstack/rabbitmq-data-rabbitmq-rabbitmq-2 general 14m pvc-da9c9dd2-a9b7-11e8-bb1d-fa163ec12213 5Gi RWO Delete Bound openstack/mysql-data-mariadb-server-0 general 17m ``Openstack endpoints`` .. code-block:: console ubuntu@node1:~$ openstack endpoint list +----------------------------------+-----------+--------------+--------------+---------+-----------+---------------------------------------------------------+ | ID | Region | Service Name | Service Type | Enabled | Interface | URL | +----------------------------------+-----------+--------------+--------------+---------+-----------+---------------------------------------------------------+ | 480cc7360752498e822cbbc7211d213a | RegionOne | keystone | identity | True | internal | http://keystone-api.openstack.svc.cluster.local:5000/v3 | | 8dfe4e4725b84e51a5eda564dee0960c | RegionOne | keystone | identity | True | public | http://keystone.openstack.svc.cluster.local:80/v3 | | 9b3526e36307400b9accfc7cc834cf99 | RegionOne | keystone | identity | True | admin | http://keystone.openstack.svc.cluster.local:80/v3 | +----------------------------------+-----------+--------------+--------------+---------+-----------+---------------------------------------------------------+ ``Openstack services`` .. code-block:: console ubuntu@node1:~$ openstack service list +----------------------------------+----------+----------+ | ID | Name | Type | +----------------------------------+----------+----------+ | 67cc6b945e934246b25d31a9374a64af | keystone | identity | +----------------------------------+----------+----------+ 5) Deploy Ceph for Tenant: -------------------------- Script to update and execute: ``030-tenant-ceph.sh`` Make following changes to script: 1 Replace occurrence of ``ceph-fs-uuid.txt`` with ``tenant-ceph-fs-uuid.txt`` 2 Replace occurrence of ``ceph.yaml`` with ``tenant-ceph.yaml`` 3 For tenant Ceph, no need to deploy ceph-provisioners. Update script to ``for CHART in ceph-mon ceph-osd ceph-client; do`` Update script's override section with following: .. code-block:: yaml endpoints: identity: namespace: openstack object_store: namespace: openstack ceph_mon: namespace: tenant-ceph port: mon: default: 6790 ceph_mgr: namespace: tenant-ceph port: mgr: default: 7001 metrics: default: 9284 network: public: ${CEPH_PUBLIC_NETWORK} cluster: ${CEPH_CLUSTER_NETWORK} deployment: storage_secrets: true ceph: true rbd_provisioner: false csi_rbd_provisioner: false cephfs_provisioner: false client_secrets: false labels: mon: node_selector_key: ceph-mon-tenant osd: node_selector_key: ceph-osd-tenant rgw: node_selector_key: ceph-rgw-tenant mgr: node_selector_key: ceph-mgr-tenant job: node_selector_key: tenant-ceph-control-plane storageclass: rbd: ceph_configmap_name: tenant-ceph-etc provision_storage_class: false name: tenant-rbd admin_secret_name: pvc-tenant-ceph-conf-combined-storageclass admin_secret_namespace: tenant-ceph user_secret_name: pvc-tenant-ceph-client-key cephfs: provision_storage_class: false name: cephfs user_secret_name: pvc-tenant-ceph-cephfs-client-key admin_secret_name: pvc-tenant-ceph-conf-combined-storageclass admin_secret_namespace: tenant-ceph bootstrap: enabled: true manifests: deployment_mds: false ceph_mgr_modules_config: prometheus: server_port: 9284 monitoring: prometheus: enabled: true ceph_mgr: port: 9284 conf: ceph: global: fsid: ${CEPH_FS_ID} rgw_ks: enabled: true pool: crush: tunables: ${CRUSH_TUNABLES} target: osd: 3 pg_per_osd: 100 storage: osd: - data: type: directory location: /var/lib/openstack-helm/tenant-ceph/osd/osd-one journal: type: directory location: /var/lib/openstack-helm/tenant-ceph/osd/journal-one mon: directory: /var/lib/openstack-helm/tenant-ceph/mon .. note:: - Port numbers for Ceph_Mon and Ceph_Mgr are different from default. - We are disabling rbd and cephfs provisioners. - Labels for mon, osd, rgw, mgr and job have been updated for tenant Ceph. - Under storageclass section, values for following have been updated: ceph_configmap_name, admin_secret_name, admin_secret_namespace, user_secret_name - Under storage: mon directory have been updated. For Tenant Ceph, we will not be provisioning storage classes therefor, update script to not install ceph-provisioners chart as following. ``for CHART in ceph-mon ceph-osd ceph-client; do`` Execute script. 6) Enable Openstack namespace to use Tenant Ceph: ------------------------------------------------- Script to update and execute: ``040-tenant-ceph-ns-activate.sh`` Update script as following: .. code-block:: console ... tee /tmp/tenant-ceph-openstack-config.yaml < 7001/TCP,9284/TCP 2h ceph-mon ClusterIP None 6790/TCP 2h ceph-mon-discovery ClusterIP None 6790/TCP 2h ingress ClusterIP 10.109.105.140 80/TCP,443/TCP 3h ingress-error-pages ClusterIP None 80/TCP 3h ingress-exporter ClusterIP 10.102.110.153 10254/TCP 3h .. code-block:: console ubuntu@node1: kubectl get endpoints -n tenant-ceph NAME ENDPOINTS AGE ceph-mgr 10.0.0.12:9284,10.0.0.16:9284,10.0.0.12:7001 + 1 more... 2h ceph-mon 10.0.0.12:6790,10.0.0.16:6790,10.0.0.9:6790 2h ceph-mon-discovery 10.0.0.12:6790,10.0.0.16:6790,10.0.0.9:6790 2h ingress 192.168.2.7:80,192.168.5.14:80,192.168.2.7:443 + 1 more... 3h ingress-error-pages 192.168.2.8:8080,192.168.5.13:8080 3h ingress-exporter 192.168.2.7:10254,192.168.5.14:10254 3h .. code-block:: console ubuntu@node1: kubectl get endpoints -n openstack NAME ENDPOINTS AGE ceph-rgw 192.168.2.42:8088,192.168.5.44:8088 20m ingress 192.168.2.4:80,192.168.5.5:80,192.168.2.4:443 + 1 more... 3h ingress-error-pages 192.168.2.3:8080,192.168.5.6:8080 3h ingress-exporter 192.168.2.4:10254,192.168.5.5:10254 3h keystone 192.168.2.4:80,192.168.5.5:80,192.168.2.4:443 + 1 more... 2h keystone-api 192.168.2.21:5000,192.168.5.24:5000 2h mariadb 192.168.2.17:3306 2h mariadb-discovery 192.168.5.22:4567,192.168.5.22:3306 2h mariadb-ingress-error-pages 192.168.5.20:8080 2h mariadb-server 192.168.5.22:3306 2h memcached 192.168.2.19:11211 2h rabbitmq 192.168.0.196:15672,192.168.2.18:15672,192.168.5.23:15672 + 6 more... 2h rabbitmq-dsv-7b1733 192.168.0.196:15672,192.168.2.18:15672,192.168.5.23:15672 + 6 more... 2h rabbitmq-mgr-7b1733 192.168.2.4:80,192.168.5.5:80,192.168.2.4:443 + 1 more... 2h radosgw 192.168.2.4:80,192.168.5.5:80,192.168.2.4:443 + 1 more... 20m .. code-block:: console ubuntu@node1: kubectl get svc -n openstack NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ceph-rgw ClusterIP 10.102.173.130 8088/TCP 20m ingress ClusterIP 10.102.1.71 80/TCP,443/TCP 3h ingress-error-pages ClusterIP None 80/TCP 3h ingress-exporter ClusterIP 10.105.29.29 10254/TCP 3h keystone ClusterIP 10.108.94.108 80/TCP,443/TCP 2h keystone-api ClusterIP 10.99.50.35 5000/TCP 2h mariadb ClusterIP 10.111.140.93 3306/TCP 2h mariadb-discovery ClusterIP None 3306/TCP,4567/TCP 2h mariadb-ingress-error-pages ClusterIP None 80/TCP 2h mariadb-server ClusterIP 10.101.237.241 3306/TCP 2h memcached ClusterIP 10.111.175.130 11211/TCP 2h rabbitmq ClusterIP 10.96.78.137 5672/TCP,25672/TCP,15672/TCP 2h rabbitmq-dsv-7b1733 ClusterIP None 5672/TCP,25672/TCP,15672/TCP 2h rabbitmq-mgr-7b1733 ClusterIP 10.104.105.46 80/TCP,443/TCP 2h radosgw ClusterIP 10.101.237.167 80/TCP,443/TCP 20m .. code-block:: console ubuntu@node1: kubectl get storageclasses NAME PROVISIONER AGE general ceph.com/rbd 1h 8) Deploy Glance: ----------------- Script to update and execute: ``100-glance.sh`` Update script overrides as following: .. code-block:: yaml endpoints: object_store: namespace: tenant-ceph ceph_object_store: namespace: tenant-ceph ceph_client: configmap: tenant-ceph-etc user_secret_name: tenant-pvc-ceph-client-key .. code-block:: console ubuntu@node1: openstack service list +----------------------------------+----------+--------------+ | ID | Name | Type | +----------------------------------+----------+--------------+ | 0eddeb6af4fd43ea8f73f63a1ae01438 | swift | object-store | | 67cc6b945e934246b25d31a9374a64af | keystone | identity | | 81a61ec8eff74070bb3c2f0118c1bcd5 | glance | image | +----------------------------------+----------+--------------+ .. code-block:: console ubuntu@node1: openstack endpoint list +----------------------------------+-----------+--------------+--------------+---------+-----------+-----------------------------------------------------------------------------+ | ID | Region | Service Name | Service Type | Enabled | Interface | URL | +----------------------------------+-----------+--------------+--------------+---------+-----------+-----------------------------------------------------------------------------+ | 265212a5856e4a0aba8eb294508279c7 | RegionOne | swift | object-store | True | admin | http://ceph-rgw.openstack.svc.cluster.local:8088/swift/v1/KEY_$(tenant_id)s | | 3fd88bc6e4774ff78c94bfa8aaaec3cf | RegionOne | glance | image | True | admin | http://glance-api.openstack.svc.cluster.local:9292/ | | 430174e280444598b676d503c5ed9799 | RegionOne | swift | object-store | True | internal | http://ceph-rgw.openstack.svc.cluster.local:8088/swift/v1/KEY_$(tenant_id)s | | 47505d5186ab448e9213f67bc833d2f1 | RegionOne | glance | image | True | public | http://glance.openstack.svc.cluster.local:80/ | | 480cc7360752498e822cbbc7211d213a | RegionOne | keystone | identity | True | internal | http://keystone-api.openstack.svc.cluster.local:5000/v3 | | 8dfe4e4725b84e51a5eda564dee0960c | RegionOne | keystone | identity | True | public | http://keystone.openstack.svc.cluster.local:80/v3 | | 937c2eacce8b4159bf918f4005c2b0ab | RegionOne | glance | image | True | internal | http://glance-api.openstack.svc.cluster.local:9292/ | | 948552a0d90940f7944f8c2eba7ef462 | RegionOne | swift | object-store | True | public | http://radosgw.openstack.svc.cluster.local:80/swift/v1/KEY_$(tenant_id)s | | 9b3526e36307400b9accfc7cc834cf99 | RegionOne | keystone | identity | True | admin | http://keystone.openstack.svc.cluster.local:80/v3 | +----------------------------------+-----------+--------------+--------------+---------+-----------+-----------------------------------------------------------------------------+ .. note:: Above output shows ``http://ceph-rgw.openstack.svc.cluster.local`` which shows that swift is pointing to tenant-ceph. 9) Deploy Cinder: ----------------- Script to update and execute: ``110-cinder.sh`` Update script overrides as following: .. code-block:: yaml backup: posix: volume: class_name: rbd-tenant ceph_client: configmap: tenant-ceph-etc user_secret_name: pvc-tenant-ceph-client-key .. code-block:: console + OS_CLOUD=openstack_helm + openstack service list +----------------------------------+----------+--------------+ | ID | Name | Type | +----------------------------------+----------+--------------+ | 0eddeb6af4fd43ea8f73f63a1ae01438 | swift | object-store | | 66bd0179eada4ab8899a58356fd4d508 | cinder | volume | | 67cc6b945e934246b25d31a9374a64af | keystone | identity | | 81a61ec8eff74070bb3c2f0118c1bcd5 | glance | image | | c126046fc5ec4c52acfc8fee0e2f4dda | cinderv2 | volumev2 | | f89b99a31a124b7790e3bb60387380b1 | cinderv3 | volumev3 | +----------------------------------+----------+--------------+ + sleep 30 + openstack volume type list +--------------------------------------+------+-----------+ | ID | Name | Is Public | +--------------------------------------+------+-----------+ | d1734540-38e7-4ef8-b74d-36a2c71df8e5 | rbd1 | True | +--------------------------------------+------+-----------+ + helm test cinder --timeout 900 RUNNING: cinder-test PASSED: cinder-test .. code-block:: console ubuntu@node1: kubectl exec -n tenant-ceph ceph-mon-2g6km -- ceph osd lspools 1 rbd,2 cephfs_metadata,3 cephfs_data,4 .rgw.root,5 default.rgw.control, 6 default.rgw.data.root,7 default.rgw.gc,8 default.rgw.log, 9 default.rgw.intent-log,10 default.rgw.meta, 11 default.rgw.usage,12 default.rgw.users.keys, 13 default.rgw.users.email,14 default.rgw.users.swift, 15 default.rgw.users.uid,16 default.rgw.buckets.extra, 17 default.rgw.buckets.index,18 default.rgw.buckets.data, 19 cinder.volumes, .. note:: Above output shows that tenant ceph now has 19 pools including one for Cinder. .. code-block:: console ubuntu@node1: kubectl exec -n tenant-ceph ceph-mon-2g6km -- ceph -s cluster: id: 38339a5a-d976-49dd-88a0-2ac092c271c7 health: HEALTH_OK services: mon: 3 daemons, quorum node3,node2,node1 mgr: node2(active), standbys: node1 osd: 3 osds: 3 up, 3 in rgw: 2 daemons active data: pools: 19 pools, 101 pgs objects: 233 objects, 52644 bytes usage: 33404 MB used, 199 GB / 232 GB avail pgs: 101 active+clean io: client: 27544 B/s rd, 0 B/s wr, 26 op/s rd, 17 op/s wr ================================================ FILE: doc/source/specs/values-ordering.rst ================================================ ==================== Values File Ordering ==================== Problem Description =================== Each chart's values.yaml file contains various settings such as docker image definition, chart structure setting, form of the resources being distributed, and process configuration. Currently, the structure of the yaml file is complicated, and finding keys between charts proves difficult due to the lack of uniform values organization across charts. This specification proposes introducing a uniform values.yaml structure across all charts in openstack-helm, openstack-helm-infra, and openstack-helm-addons, with the goal of reducing the complexities of working across multiple charts and reducing the effort for creating new charts. Proposed Change =============== This specification proposes defining entries in the values.yaml file into two categories: top-level keys, and their children (sub-level) keys. * The top-level keys are based on the organizational keys common to all charts in the openstack-helm repositories. The top-level keys are strictly ordered according to function, which creates a common organization pattern between all charts. * All keys under top-level keys are listed in alphabetical order, with the exception of the conf key. As some configuration files require a strict ordering of their content, excluding this key from any alphabetical organization is required. This specification also proposes to restrict the addition of any new top-level keys in charts across all OpenStack-Helm repositories, in order to maintain the common structure the ordering creates. The addition of a new top-level key shall be agreed upon by the OpenStack-Helm team on a case-by-case basis. The addition of any new top-level keys should be documented, and this specification shall be amended to account for any added keys. Top-level keys are placed in this order: * images * sub-keys (alphabetical order) * labels * sub-keys (alphabetical order) * dependencies * sub-keys (alphabetical order) * pod * sub-keys (alphabetical order) * secrets * sub-keys (alphabetical order) * endpoints * sub-keys (alphabetical order) * bootstrap * sub-keys (alphabetical order) * network * sub-keys (alphabetical order) * manifests * sub-keys (alphabetical order) * monitoring * sub-keys (alphabetical order) * conf * sub-keys (up-to-chart-developer) Security Impact --------------- No security impact. Performance Impact ------------------ This feature will not affect the performance of OpenStack-Helm. Alternatives ------------ The alternative is to provide no organization layout for charts across all openstack-helm repositories. Implementation ============== Assignee(s) ----------- Primary assignees: powerds0111 (DaeSeong Kim ) srwilkers (Steve Wilkerson ) Work Items ---------- The following work items need to be completed for this specification to be implemented. * Update of developer documentation * Add a template highlighting the updated values ordering for use in chart development * Change ordering of keys across all charts in openstack-helm, openstack-helm-infra, and openstack-helm-addons Testing ======= To successfully enforce the ordering defined here, our gates need a method for validating the ordering and the schema of all values.yaml files. Without such a mechanism, the overhead associated with properly reviewing and validating any changes to the structure will be substantial. A tool, such as yamllint, would provide this functionality and remove the need to write a custom validation tool Documentation Impact ==================== The developer documentation in OpenStack-Helm should be updated to guide key ordering on value files. ================================================ FILE: doc/source/testing/ceph-node-resiliency.rst ================================================ ================================================== Ceph - Node Reduction, Expansion and Ceph Recovery ================================================== This document captures steps and result from node reduction and expansion as well as ceph recovery. Test Scenarios: =============== 1) Node reduction: Shutdown 1 of 3 nodes to simulate node failure. Capture effect of node failure on Ceph as well as other OpenStack services that are using Ceph. 2) Node expansion: Apply Ceph and OpenStack related labels to another unused k8 node. Node expansion should provide more resources for k8 to schedule PODs for Ceph and OpenStack services. 3) Fix Ceph Cluster: After node expansion, perform maintenance on Ceph cluster to ensure quorum is reached and Ceph is HEALTH_OK. Setup: ====== - 6 Nodes (VM based) env - Only 3 nodes will have Ceph and OpenStack related labels. Each of these 3 nodes will have one MON and one OSD running on them. - Followed OSH multinode guide steps to setup nodes and install K8s cluster - Followed OSH multinode guide steps to install Ceph and OpenStack charts up to Cinder. Steps: ====== 1) Initial Ceph and OpenStack deployment: Install Ceph and OpenStack charts on 3 nodes (mnode1, mnode2 and mnode3). Capture Ceph cluster status as well as K8s PODs status. 2) Node reduction (failure): Shutdown 1 of 3 nodes (mnode3) to test node failure. This should cause Ceph cluster to go in HEALTH_WARN state as it has lost 1 MON and 1 OSD. Capture Ceph cluster status as well as K8s PODs status. 3) Node expansion: Add Ceph and OpenStack related labels to 4th node (mnode4) for expansion. Ceph cluster would show new MON and OSD being added to cluster. However Ceph cluster would continue to show HEALTH_WARN because 1 MON and 1 OSD are still missing. 4) Ceph cluster recovery: Perform Ceph maintenance to make Ceph cluster HEALTH_OK. Remove lost MON and OSD from Ceph cluster. Step 1: Initial Ceph and OpenStack deployment ============================================= .. note:: Make sure only 3 nodes (mnode1, mnode2, mnode3) have Ceph and OpenStack related labels. K8s would only schedule PODs on these 3 nodes. ``Ceph status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph -s cluster: id: 54d9af7e-da6d-4980-9075-96bb145db65c health: HEALTH_OK services: mon: 3 daemons, quorum mnode1,mnode2,mnode3 mgr: mnode2(active), standbys: mnode3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-6f66956547-c25cx=up:active}, 1 up:standby osd: 3 osds: 3 up, 3 in rgw: 2 daemons active data: pools: 19 pools, 101 pgs objects: 354 objects, 260 MB usage: 77807 MB used, 70106 MB / 144 GB avail pgs: 101 active+clean io: client: 48769 B/s wr, 0 op/s rd, 12 op/s wr ``Ceph MON Status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph mon_status -f json-pretty .. code-block:: json { "name": "mnode2", "rank": 1, "state": "peon", "election_epoch": 92, "quorum": [ 0, 1, 2 ], "features": { "required_con": "153140804152475648", "required_mon": [ "kraken", "luminous" ], "quorum_con": "2305244844532236283", "quorum_mon": [ "kraken", "luminous" ] }, "outside_quorum": [], "extra_probe_peers": [], "sync_provider": [], "monmap": { "epoch": 1, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 21:02:24.330403", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode3", "addr": "192.168.10.248:6789/0", "public_addr": "192.168.10.248:6789/0" } ] }, "feature_map": { "mon": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "mds": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "osd": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "client": { "group": { "features": "0x7010fb86aa42ada", "release": "jewel", "num": 1 }, "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } } } } ``Ceph quorum status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph quorum_status -f json-pretty .. code-block:: json { "election_epoch": 92, "quorum": [ 0, 1, 2 ], "quorum_names": [ "mnode1", "mnode2", "mnode3" ], "quorum_leader_name": "mnode1", "monmap": { "epoch": 1, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 21:02:24.330403", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode3", "addr": "192.168.10.248:6789/0", "public_addr": "192.168.10.248:6789/0" } ] } } ``Ceph PODs:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl get pods -n ceph --show-all=false -o wide NAME READY STATUS RESTARTS AGE IP NODE ceph-mds-6f66956547-5x4ng 1/1 Running 0 1h 192.168.4.14 mnode2 ceph-mds-6f66956547-c25cx 1/1 Running 0 1h 192.168.3.14 mnode3 ceph-mgr-5746dd89db-9dbmv 1/1 Running 0 1h 192.168.10.248 mnode3 ceph-mgr-5746dd89db-qq4nl 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-mon-5qn68 1/1 Running 0 1h 192.168.10.248 mnode3 ceph-mon-check-d85994946-4g5xc 1/1 Running 0 1h 192.168.4.8 mnode2 ceph-mon-mwkj9 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-mon-ql9zp 1/1 Running 0 1h 192.168.10.246 mnode1 ceph-osd-default-83945928-c7gdd 1/1 Running 0 1h 192.168.10.248 mnode3 ceph-osd-default-83945928-s6gs6 1/1 Running 0 1h 192.168.10.246 mnode1 ceph-osd-default-83945928-vsc5b 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-rbd-provisioner-5bfb577ffd-j6hlx 1/1 Running 0 1h 192.168.4.16 mnode2 ceph-rbd-provisioner-5bfb577ffd-zdx2d 1/1 Running 0 1h 192.168.3.16 mnode3 ceph-rgw-6c64b444d7-7bgqs 1/1 Running 0 1h 192.168.3.12 mnode3 ceph-rgw-6c64b444d7-hv6vn 1/1 Running 0 1h 192.168.4.13 mnode2 ingress-796d8cf8d6-4txkq 1/1 Running 0 1h 192.168.2.6 mnode5 ingress-796d8cf8d6-9t7m8 1/1 Running 0 1h 192.168.5.4 mnode4 ingress-error-pages-54454dc79b-hhb4f 1/1 Running 0 1h 192.168.2.5 mnode5 ingress-error-pages-54454dc79b-twpgc 1/1 Running 0 1h 192.168.4.4 mnode2 ``OpenStack PODs:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl get pods -n openstack --show-all=false -o wide NAME READY STATUS RESTARTS AGE IP NODE cinder-api-66f4f9678-2lgwk 1/1 Running 0 12m 192.168.3.41 mnode3 cinder-api-66f4f9678-flvr5 1/1 Running 0 12m 192.168.0.202 mnode1 cinder-backup-659b68b474-582kr 1/1 Running 0 12m 192.168.4.39 mnode2 cinder-scheduler-6778f6f88c-mm9mt 1/1 Running 0 12m 192.168.0.201 mnode1 cinder-volume-79b9bd8bb9-qsxdk 1/1 Running 0 12m 192.168.4.40 mnode2 glance-api-676fd49d4d-j4bdb 1/1 Running 0 16m 192.168.3.37 mnode3 glance-api-676fd49d4d-wtxqt 1/1 Running 0 16m 192.168.4.31 mnode2 ingress-7b4bc84cdd-9fs78 1/1 Running 0 1h 192.168.5.3 mnode4 ingress-7b4bc84cdd-wztz7 1/1 Running 0 1h 192.168.1.4 mnode6 ingress-error-pages-586c7f86d6-2jl5q 1/1 Running 0 1h 192.168.2.4 mnode5 ingress-error-pages-586c7f86d6-455j5 1/1 Running 0 1h 192.168.3.3 mnode3 keystone-api-5bcc7cb698-dzm8q 1/1 Running 0 25m 192.168.4.24 mnode2 keystone-api-5bcc7cb698-vvwwr 1/1 Running 0 25m 192.168.3.25 mnode3 mariadb-ingress-84894687fd-dfnkm 1/1 Running 2 1h 192.168.3.20 mnode3 mariadb-ingress-error-pages-78fb865f84-p8lpg 1/1 Running 0 1h 192.168.4.17 mnode2 mariadb-server-0 1/1 Running 0 1h 192.168.4.18 mnode2 memcached-memcached-5db74ddfd5-wfr9q 1/1 Running 0 29m 192.168.3.23 mnode3 rabbitmq-rabbitmq-0 1/1 Running 0 1h 192.168.3.21 mnode3 rabbitmq-rabbitmq-1 1/1 Running 0 1h 192.168.4.19 mnode2 rabbitmq-rabbitmq-2 1/1 Running 0 1h 192.168.0.195 mnode1 ``Result/Observation:`` - Ceph cluster is in HEALTH_OK state with 3 MONs and 3 OSDs. - All PODs are in running state. Step 2: Node reduction (failure): ================================= Shutdown 1 of 3 nodes (mnode1, mnode2, mnode3) to simulate node failure/lost. In this test env, let's shutdown ``mnode3`` node. ``Following are PODs scheduled on mnode3 before shutdown:`` .. code-block:: console ceph ceph-mds-6f66956547-c25cx 0 (0%) 0 (0%) 0 (0%) 0 (0%) ceph ceph-mgr-5746dd89db-9dbmv 0 (0%) 0 (0%) 0 (0%) 0 (0%) ceph ceph-mon-5qn68 0 (0%) 0 (0%) 0 (0%) 0 (0%) ceph ceph-osd-default-83945928-c7gdd 0 (0%) 0 (0%) 0 (0%) 0 (0%) ceph ceph-rbd-provisioner-5bfb577ffd-zdx2d 0 (0%) 0 (0%) 0 (0%) 0 (0%) ceph ceph-rgw-6c64b444d7-7bgqs 0 (0%) 0 (0%) 0 (0%) 0 (0%) kube-system ingress-ggckm 0 (0%) 0 (0%) 0 (0%) 0 (0%) kube-system kube-flannel-ds-hs29q 0 (0%) 0 (0%) 0 (0%) 0 (0%) kube-system kube-proxy-gqpz5 0 (0%) 0 (0%) 0 (0%) 0 (0%) openstack cinder-api-66f4f9678-2lgwk 0 (0%) 0 (0%) 0 (0%) 0 (0%) openstack glance-api-676fd49d4d-j4bdb 0 (0%) 0 (0%) 0 (0%) 0 (0%) openstack ingress-error-pages-586c7f86d6-455j5 0 (0%) 0 (0%) 0 (0%) 0 (0%) openstack keystone-api-5bcc7cb698-vvwwr 0 (0%) 0 (0%) 0 (0%) 0 (0%) openstack mariadb-ingress-84894687fd-dfnkm 0 (0%) 0 (0%) 0 (0%) 0 (0%) openstack memcached-memcached-5db74ddfd5-wfr9q 0 (0%) 0 (0%) 0 (0%) 0 (0%) openstack rabbitmq-rabbitmq-0 0 (0%) 0 (0%) 0 (0%) 0 (0%) .. note:: In this test env, MariaDB chart is deployed with only 1 replica. In order to test properly, the node with MariaDB server POD (mnode2) should not be shutdown. .. note:: In this test env, each node has Ceph and OpenStack related PODs. Due to this, shutting down a Node will cause issue with Ceph as well as OpenStack services. These PODs level failures are captured following subsequent screenshots. ``Check node status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl get nodes NAME STATUS ROLES AGE VERSION mnode1 Ready 1h v1.10.6 mnode2 Ready 1h v1.10.6 mnode3 NotReady 1h v1.10.6 mnode4 Ready 1h v1.10.6 mnode5 Ready 1h v1.10.6 mnode6 Ready 1h v1.10.6 ``Ceph status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph -s cluster: id: 54d9af7e-da6d-4980-9075-96bb145db65c health: HEALTH_WARN insufficient standby MDS daemons available 1 osds down 1 host (1 osds) down Degraded data redundancy: 354/1062 objects degraded (33.333%), 46 pgs degraded, 101 pgs undersized 1/3 mons down, quorum mnode1,mnode2 services: mon: 3 daemons, quorum mnode1,mnode2, out of quorum: mnode3 mgr: mnode2(active) mds: cephfs-1/1/1 up {0=mds-ceph-mds-6f66956547-5x4ng=up:active} osd: 3 osds: 2 up, 3 in rgw: 1 daemon active data: pools: 19 pools, 101 pgs objects: 354 objects, 260 MB usage: 77845 MB used, 70068 MB / 144 GB avail pgs: 354/1062 objects degraded (33.333%) 55 active+undersized 46 active+undersized+degraded ``Ceph quorum status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph quorum_status -f json-pretty .. code-block:: json { "election_epoch": 96, "quorum": [ 0, 1 ], "quorum_names": [ "mnode1", "mnode2" ], "quorum_leader_name": "mnode1", "monmap": { "epoch": 1, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 21:02:24.330403", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode3", "addr": "192.168.10.248:6789/0", "public_addr": "192.168.10.248:6789/0" } ] } } ``Ceph MON Status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph mon_status -f json-pretty .. code-block:: json { "name": "mnode1", "rank": 0, "state": "leader", "election_epoch": 96, "quorum": [ 0, 1 ], "features": { "required_con": "153140804152475648", "required_mon": [ "kraken", "luminous" ], "quorum_con": "2305244844532236283", "quorum_mon": [ "kraken", "luminous" ] }, "outside_quorum": [], "extra_probe_peers": [], "sync_provider": [], "monmap": { "epoch": 1, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 21:02:24.330403", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode3", "addr": "192.168.10.248:6789/0", "public_addr": "192.168.10.248:6789/0" } ] }, "feature_map": { "mon": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "mds": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "osd": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "client": { "group": { "features": "0x7010fb86aa42ada", "release": "jewel", "num": 1 }, "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 5 } } } } ``Ceph PODs:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl get pods -n ceph --show-all=false -o wide NAME READY STATUS RESTARTS AGE IP NODE ceph-mds-6f66956547-57tf9 1/1 Running 0 1m 192.168.0.207 mnode1 ceph-mds-6f66956547-5x4ng 1/1 Running 0 1h 192.168.4.14 mnode2 ceph-mds-6f66956547-c25cx 1/1 Unknown 0 1h 192.168.3.14 mnode3 ceph-mgr-5746dd89db-9dbmv 1/1 Unknown 0 1h 192.168.10.248 mnode3 ceph-mgr-5746dd89db-d5fcw 1/1 Running 0 1m 192.168.10.246 mnode1 ceph-mgr-5746dd89db-qq4nl 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-mon-5qn68 1/1 NodeLost 0 1h 192.168.10.248 mnode3 ceph-mon-check-d85994946-4g5xc 1/1 Running 0 1h 192.168.4.8 mnode2 ceph-mon-mwkj9 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-mon-ql9zp 1/1 Running 0 1h 192.168.10.246 mnode1 ceph-osd-default-83945928-c7gdd 1/1 NodeLost 0 1h 192.168.10.248 mnode3 ceph-osd-default-83945928-s6gs6 1/1 Running 0 1h 192.168.10.246 mnode1 ceph-osd-default-83945928-vsc5b 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-rbd-provisioner-5bfb577ffd-j6hlx 1/1 Running 0 1h 192.168.4.16 mnode2 ceph-rbd-provisioner-5bfb577ffd-kdmrv 1/1 Running 0 1m 192.168.0.209 mnode1 ceph-rbd-provisioner-5bfb577ffd-zdx2d 1/1 Unknown 0 1h 192.168.3.16 mnode3 ceph-rgw-6c64b444d7-4qgkw 1/1 Running 0 1m 192.168.0.210 mnode1 ceph-rgw-6c64b444d7-7bgqs 1/1 Unknown 0 1h 192.168.3.12 mnode3 ceph-rgw-6c64b444d7-hv6vn 1/1 Running 0 1h 192.168.4.13 mnode2 ingress-796d8cf8d6-4txkq 1/1 Running 0 1h 192.168.2.6 mnode5 ingress-796d8cf8d6-9t7m8 1/1 Running 0 1h 192.168.5.4 mnode4 ingress-error-pages-54454dc79b-hhb4f 1/1 Running 0 1h 192.168.2.5 mnode5 ingress-error-pages-54454dc79b-twpgc 1/1 Running 0 1h 192.168.4.4 mnode2 ``OpenStack PODs:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl get pods -n openstack --show-all=false -o wide NAME READY STATUS RESTARTS AGE IP NODE cinder-api-66f4f9678-2lgwk 1/1 Unknown 0 22m 192.168.3.41 mnode3 cinder-api-66f4f9678-flvr5 1/1 Running 0 22m 192.168.0.202 mnode1 cinder-api-66f4f9678-w5xhd 1/1 Running 0 1m 192.168.4.45 mnode2 cinder-backup-659b68b474-582kr 1/1 Running 0 22m 192.168.4.39 mnode2 cinder-scheduler-6778f6f88c-mm9mt 1/1 Running 0 22m 192.168.0.201 mnode1 cinder-volume-79b9bd8bb9-qsxdk 1/1 Running 0 22m 192.168.4.40 mnode2 cinder-volume-usage-audit-1534286100-mm8r7 1/1 Running 0 4m 192.168.4.44 mnode2 glance-api-676fd49d4d-4tnm6 1/1 Running 0 1m 192.168.0.212 mnode1 glance-api-676fd49d4d-j4bdb 1/1 Unknown 0 26m 192.168.3.37 mnode3 glance-api-676fd49d4d-wtxqt 1/1 Running 0 26m 192.168.4.31 mnode2 ingress-7b4bc84cdd-9fs78 1/1 Running 0 1h 192.168.5.3 mnode4 ingress-7b4bc84cdd-wztz7 1/1 Running 0 1h 192.168.1.4 mnode6 ingress-error-pages-586c7f86d6-2jl5q 1/1 Running 0 1h 192.168.2.4 mnode5 ingress-error-pages-586c7f86d6-455j5 1/1 Unknown 0 1h 192.168.3.3 mnode3 ingress-error-pages-586c7f86d6-55j4x 1/1 Running 0 1m 192.168.4.47 mnode2 keystone-api-5bcc7cb698-dzm8q 1/1 Running 0 35m 192.168.4.24 mnode2 keystone-api-5bcc7cb698-vvwwr 1/1 Unknown 0 35m 192.168.3.25 mnode3 keystone-api-5bcc7cb698-wx5l6 1/1 Running 0 1m 192.168.0.213 mnode1 mariadb-ingress-84894687fd-9lmpx 1/1 Running 0 1m 192.168.4.48 mnode2 mariadb-ingress-84894687fd-dfnkm 1/1 Unknown 2 1h 192.168.3.20 mnode3 mariadb-ingress-error-pages-78fb865f84-p8lpg 1/1 Running 0 1h 192.168.4.17 mnode2 mariadb-server-0 1/1 Running 0 1h 192.168.4.18 mnode2 memcached-memcached-5db74ddfd5-926ln 1/1 Running 0 1m 192.168.4.49 mnode2 memcached-memcached-5db74ddfd5-wfr9q 1/1 Unknown 0 38m 192.168.3.23 mnode3 rabbitmq-rabbitmq-0 1/1 Unknown 0 1h 192.168.3.21 mnode3 rabbitmq-rabbitmq-1 1/1 Running 0 1h 192.168.4.19 mnode2 rabbitmq-rabbitmq-2 1/1 Running 0 1h 192.168.0.195 mnode1 ``Result/Observation:`` - PODs that were scheduled on mnode3 node has status of NodeLost/Unknown. - Ceph status shows HEALTH_WARN as expected - Ceph status shows 1 Ceph MON and 1 Ceph OSD missing. - OpenStack PODs that were scheduled mnode3 also shows NodeLost/Unknown. Step 3: Node Expansion ====================== Let's add more resources for K8s to schedule PODs on. In this test env, let's use ``mnode4`` and apply Ceph and OpenStack related labels. .. note:: Since the node that was shutdown earlier had both Ceph and OpenStack PODs, mnode4 should get Ceph and OpenStack related labels as well. After applying labels, let's check status ``Ceph status:`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph -s cluster: id: 54d9af7e-da6d-4980-9075-96bb145db65c health: HEALTH_WARN 1/4 mons down, quorum mnode1,mnode2,mnode4 services: mon: 4 daemons, quorum mnode1,mnode2,mnode4, out of quorum: mnode3 mgr: mnode2(active), standbys: mnode1 mds: cephfs-1/1/1 up {0=mds-ceph-mds-6f66956547-5x4ng=up:active}, 1 up:standby osd: 4 osds: 3 up, 3 in rgw: 2 daemons active data: pools: 19 pools, 101 pgs objects: 354 objects, 260 MB usage: 74684 MB used, 73229 MB / 144 GB avail pgs: 101 active+clean ``Ceph MON Status`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph mon_status -f json-pretty .. code-block:: json { "name": "mnode2", "rank": 1, "state": "peon", "election_epoch": 100, "quorum": [ 0, 1, 3 ], "features": { "required_con": "153140804152475648", "required_mon": [ "kraken", "luminous" ], "quorum_con": "2305244844532236283", "quorum_mon": [ "kraken", "luminous" ] }, "outside_quorum": [], "extra_probe_peers": [ "192.168.10.249:6789/0" ], "sync_provider": [], "monmap": { "epoch": 2, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 22:43:31.517568", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode3", "addr": "192.168.10.248:6789/0", "public_addr": "192.168.10.248:6789/0" }, { "rank": 3, "name": "mnode4", "addr": "192.168.10.249:6789/0", "public_addr": "192.168.10.249:6789/0" } ] }, "feature_map": { "mon": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "mds": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "osd": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 2 } }, "client": { "group": { "features": "0x7010fb86aa42ada", "release": "jewel", "num": 1 }, "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } } } } ``Ceph quorum status:`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph quorum_status -f json-pretty .. code-block:: json { "election_epoch": 100, "quorum": [ 0, 1, 3 ], "quorum_names": [ "mnode1", "mnode2", "mnode4" ], "quorum_leader_name": "mnode1", "monmap": { "epoch": 2, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 22:43:31.517568", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode3", "addr": "192.168.10.248:6789/0", "public_addr": "192.168.10.248:6789/0" }, { "rank": 3, "name": "mnode4", "addr": "192.168.10.249:6789/0", "public_addr": "192.168.10.249:6789/0" } ] } } ``Ceph PODs:`` .. code-block:: console ubuntu@mnode1:~$ kubectl get pods -n ceph --show-all=false -o wide Flag --show-all has been deprecated, will be removed in an upcoming release NAME READY STATUS RESTARTS AGE IP NODE ceph-mds-6f66956547-57tf9 1/1 Running 0 10m 192.168.0.207 mnode1 ceph-mds-6f66956547-5x4ng 1/1 Running 0 1h 192.168.4.14 mnode2 ceph-mds-6f66956547-c25cx 1/1 Unknown 0 1h 192.168.3.14 mnode3 ceph-mgr-5746dd89db-9dbmv 1/1 Unknown 0 1h 192.168.10.248 mnode3 ceph-mgr-5746dd89db-d5fcw 1/1 Running 0 10m 192.168.10.246 mnode1 ceph-mgr-5746dd89db-qq4nl 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-mon-5krkd 1/1 Running 0 4m 192.168.10.249 mnode4 ceph-mon-5qn68 1/1 NodeLost 0 1h 192.168.10.248 mnode3 ceph-mon-check-d85994946-4g5xc 1/1 Running 0 1h 192.168.4.8 mnode2 ceph-mon-mwkj9 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-mon-ql9zp 1/1 Running 0 1h 192.168.10.246 mnode1 ceph-osd-default-83945928-c7gdd 1/1 NodeLost 0 1h 192.168.10.248 mnode3 ceph-osd-default-83945928-kf5tj 1/1 Running 0 4m 192.168.10.249 mnode4 ceph-osd-default-83945928-s6gs6 1/1 Running 0 1h 192.168.10.246 mnode1 ceph-osd-default-83945928-vsc5b 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-rbd-provisioner-5bfb577ffd-j6hlx 1/1 Running 0 1h 192.168.4.16 mnode2 ceph-rbd-provisioner-5bfb577ffd-kdmrv 1/1 Running 0 10m 192.168.0.209 mnode1 ceph-rbd-provisioner-5bfb577ffd-zdx2d 1/1 Unknown 0 1h 192.168.3.16 mnode3 ceph-rgw-6c64b444d7-4qgkw 1/1 Running 0 10m 192.168.0.210 mnode1 ceph-rgw-6c64b444d7-7bgqs 1/1 Unknown 0 1h 192.168.3.12 mnode3 ceph-rgw-6c64b444d7-hv6vn 1/1 Running 0 1h 192.168.4.13 mnode2 ingress-796d8cf8d6-4txkq 1/1 Running 0 1h 192.168.2.6 mnode5 ingress-796d8cf8d6-9t7m8 1/1 Running 0 1h 192.168.5.4 mnode4 ingress-error-pages-54454dc79b-hhb4f 1/1 Running 0 1h 192.168.2.5 mnode5 ingress-error-pages-54454dc79b-twpgc 1/1 Running 0 1h 192.168.4.4 mnode2 ``OpenStack PODs:`` .. code-block:: console ubuntu@mnode1:~$ kubectl get pods -n openstack --show-all=false -o wide Flag --show-all has been deprecated, will be removed in an upcoming release NAME READY STATUS RESTARTS AGE IP NODE cinder-api-66f4f9678-2lgwk 1/1 Unknown 0 32m 192.168.3.41 mnode3 cinder-api-66f4f9678-flvr5 1/1 Running 0 32m 192.168.0.202 mnode1 cinder-api-66f4f9678-w5xhd 1/1 Running 0 11m 192.168.4.45 mnode2 cinder-backup-659b68b474-582kr 1/1 Running 0 32m 192.168.4.39 mnode2 cinder-scheduler-6778f6f88c-mm9mt 1/1 Running 0 32m 192.168.0.201 mnode1 cinder-volume-79b9bd8bb9-qsxdk 1/1 Running 0 32m 192.168.4.40 mnode2 glance-api-676fd49d4d-4tnm6 1/1 Running 0 11m 192.168.0.212 mnode1 glance-api-676fd49d4d-j4bdb 1/1 Unknown 0 36m 192.168.3.37 mnode3 glance-api-676fd49d4d-wtxqt 1/1 Running 0 36m 192.168.4.31 mnode2 ingress-7b4bc84cdd-9fs78 1/1 Running 0 1h 192.168.5.3 mnode4 ingress-7b4bc84cdd-wztz7 1/1 Running 0 1h 192.168.1.4 mnode6 ingress-error-pages-586c7f86d6-2jl5q 1/1 Running 0 1h 192.168.2.4 mnode5 ingress-error-pages-586c7f86d6-455j5 1/1 Unknown 0 1h 192.168.3.3 mnode3 ingress-error-pages-586c7f86d6-55j4x 1/1 Running 0 11m 192.168.4.47 mnode2 keystone-api-5bcc7cb698-dzm8q 1/1 Running 0 45m 192.168.4.24 mnode2 keystone-api-5bcc7cb698-vvwwr 1/1 Unknown 0 45m 192.168.3.25 mnode3 keystone-api-5bcc7cb698-wx5l6 1/1 Running 0 11m 192.168.0.213 mnode1 mariadb-ingress-84894687fd-9lmpx 1/1 Running 0 11m 192.168.4.48 mnode2 mariadb-ingress-84894687fd-dfnkm 1/1 Unknown 2 1h 192.168.3.20 mnode3 mariadb-ingress-error-pages-78fb865f84-p8lpg 1/1 Running 0 1h 192.168.4.17 mnode2 mariadb-server-0 1/1 Running 0 1h 192.168.4.18 mnode2 memcached-memcached-5db74ddfd5-926ln 1/1 Running 0 11m 192.168.4.49 mnode2 memcached-memcached-5db74ddfd5-wfr9q 1/1 Unknown 0 48m 192.168.3.23 mnode3 rabbitmq-rabbitmq-0 1/1 Unknown 0 1h 192.168.3.21 mnode3 rabbitmq-rabbitmq-1 1/1 Running 0 1h 192.168.4.19 mnode2 rabbitmq-rabbitmq-2 1/1 Running 0 1h 192.168.0.195 mnode1 ``Result/Observation:`` - Ceph MON and OSD PODs got scheduled on mnode4 node. - Ceph status shows that MON and OSD count has been increased. - Ceph status still shows HEALTH_WARN as one MON and OSD are still down. Step 4: Ceph cluster recovery ============================= Now that we have added new node for Ceph and OpenStack PODs, let's perform maintenance on Ceph cluster. 1) Remove out of quorum MON: ---------------------------- Using ``ceph mon_status`` and ``ceph -s`` commands, confirm ID of MON that is out of quorum. In this test env, ``mnode3`` is out of quorum. .. note:: In this test env, since out of quorum MON is no longer available due to node failure, we can processed with removing it from Ceph cluster. ``Remove MON from Ceph cluster`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph mon remove mnode3 removing mon.mnode3 at 192.168.10.248:6789/0, there will be 3 monitors ``Ceph Status:`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph -s cluster: id: 54d9af7e-da6d-4980-9075-96bb145db65c health: HEALTH_OK services: mon: 3 daemons, quorum mnode1,mnode2,mnode4 mgr: mnode2(active), standbys: mnode1 mds: cephfs-1/1/1 up {0=mds-ceph-mds-6f66956547-5x4ng=up:active}, 1 up:standby osd: 4 osds: 3 up, 3 in rgw: 2 daemons active data: pools: 19 pools, 101 pgs objects: 354 objects, 260 MB usage: 74705 MB used, 73208 MB / 144 GB avail pgs: 101 active+clean io: client: 132 kB/s wr, 0 op/s rd, 23 op/s wr As shown above, Ceph status is now HEALTH_OK and shows 3 MONs available. ``Ceph MON Status`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph mon_status -f json-pretty .. code-block:: json { "name": "mnode4", "rank": 2, "state": "peon", "election_epoch": 106, "quorum": [ 0, 1, 2 ], "features": { "required_con": "153140804152475648", "required_mon": [ "kraken", "luminous" ], "quorum_con": "2305244844532236283", "quorum_mon": [ "kraken", "luminous" ] }, "outside_quorum": [], "extra_probe_peers": [], "sync_provider": [], "monmap": { "epoch": 3, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 22:55:41.256612", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode4", "addr": "192.168.10.249:6789/0", "public_addr": "192.168.10.249:6789/0" } ] }, "feature_map": { "mon": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } }, "client": { "group": { "features": "0x1ffddff8eea4fffb", "release": "luminous", "num": 1 } } } } ``Ceph quorum status`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph quorum_status -f json-pretty .. code-block:: json { "election_epoch": 106, "quorum": [ 0, 1, 2 ], "quorum_names": [ "mnode1", "mnode2", "mnode4" ], "quorum_leader_name": "mnode1", "monmap": { "epoch": 3, "fsid": "54d9af7e-da6d-4980-9075-96bb145db65c", "modified": "2018-08-14 22:55:41.256612", "created": "2018-08-14 21:02:24.330403", "features": { "persistent": [ "kraken", "luminous" ], "optional": [] }, "mons": [ { "rank": 0, "name": "mnode1", "addr": "192.168.10.246:6789/0", "public_addr": "192.168.10.246:6789/0" }, { "rank": 1, "name": "mnode2", "addr": "192.168.10.247:6789/0", "public_addr": "192.168.10.247:6789/0" }, { "rank": 2, "name": "mnode4", "addr": "192.168.10.249:6789/0", "public_addr": "192.168.10.249:6789/0" } ] } } 2) Remove down OSD from Ceph cluster: ------------------------------------- As shown in Ceph status above, ``osd: 4 osds: 3 up, 3 in`` 1 of 4 OSDs is still down. Let's remove that OSD. First, run ``ceph osd tree`` command to get list of OSDs. .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 0.19995 root default -7 0.04999 host mnode1 2 hdd 0.04999 osd.2 up 1.00000 1.00000 -2 0.04999 host mnode2 0 hdd 0.04999 osd.0 up 1.00000 1.00000 -3 0.04999 host mnode3 1 hdd 0.04999 osd.1 down 0 1.00000 -9 0.04999 host mnode4 3 hdd 0.04999 osd.3 up 1.00000 1.00000 Above output shows that ``osd.1`` is down. Run ``ceph osd purge`` command to remove OSD from ceph cluster. .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph osd purge osd.1 --yes-i-really-mean-it purged osd.1 ``Ceph status`` .. code-block:: console ubuntu@mnode1:~$ kubectl exec -n ceph ceph-mon-ql9zp -- ceph -s cluster: id: 54d9af7e-da6d-4980-9075-96bb145db65c health: HEALTH_OK services: mon: 3 daemons, quorum mnode1,mnode2,mnode4 mgr: mnode2(active), standbys: mnode1 mds: cephfs-1/1/1 up {0=mds-ceph-mds-6f66956547-5x4ng=up:active}, 1 up:standby osd: 3 osds: 3 up, 3 in rgw: 2 daemons active data: pools: 19 pools, 101 pgs objects: 354 objects, 260 MB usage: 74681 MB used, 73232 MB / 144 GB avail pgs: 101 active+clean io: client: 57936 B/s wr, 0 op/s rd, 14 op/s wr Above output shows Ceph cluster in HEALTH_OK with all OSDs and MONs up and running. ``Ceph PODs`` .. code-block:: console ubuntu@mnode1:~$ kubectl get pods -n ceph --show-all=false -o wide Flag --show-all has been deprecated, will be removed in an upcoming release NAME READY STATUS RESTARTS AGE IP NODE ceph-mds-6f66956547-57tf9 1/1 Running 0 25m 192.168.0.207 mnode1 ceph-mds-6f66956547-5x4ng 1/1 Running 0 1h 192.168.4.14 mnode2 ceph-mds-6f66956547-c25cx 1/1 Unknown 0 1h 192.168.3.14 mnode3 ceph-mgr-5746dd89db-9dbmv 1/1 Unknown 0 1h 192.168.10.248 mnode3 ceph-mgr-5746dd89db-d5fcw 1/1 Running 0 25m 192.168.10.246 mnode1 ceph-mgr-5746dd89db-qq4nl 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-mon-5krkd 1/1 Running 0 19m 192.168.10.249 mnode4 ceph-mon-5qn68 1/1 NodeLost 0 2h 192.168.10.248 mnode3 ceph-mon-check-d85994946-4g5xc 1/1 Running 0 2h 192.168.4.8 mnode2 ceph-mon-mwkj9 1/1 Running 0 2h 192.168.10.247 mnode2 ceph-mon-ql9zp 1/1 Running 0 2h 192.168.10.246 mnode1 ceph-osd-default-83945928-c7gdd 1/1 NodeLost 0 1h 192.168.10.248 mnode3 ceph-osd-default-83945928-kf5tj 1/1 Running 0 19m 192.168.10.249 mnode4 ceph-osd-default-83945928-s6gs6 1/1 Running 0 1h 192.168.10.246 mnode1 ceph-osd-default-83945928-vsc5b 1/1 Running 0 1h 192.168.10.247 mnode2 ceph-rbd-provisioner-5bfb577ffd-j6hlx 1/1 Running 0 1h 192.168.4.16 mnode2 ceph-rbd-provisioner-5bfb577ffd-kdmrv 1/1 Running 0 25m 192.168.0.209 mnode1 ceph-rbd-provisioner-5bfb577ffd-zdx2d 1/1 Unknown 0 1h 192.168.3.16 mnode3 ceph-rgw-6c64b444d7-4qgkw 1/1 Running 0 25m 192.168.0.210 mnode1 ceph-rgw-6c64b444d7-7bgqs 1/1 Unknown 0 1h 192.168.3.12 mnode3 ceph-rgw-6c64b444d7-hv6vn 1/1 Running 0 1h 192.168.4.13 mnode2 ingress-796d8cf8d6-4txkq 1/1 Running 0 2h 192.168.2.6 mnode5 ingress-796d8cf8d6-9t7m8 1/1 Running 0 2h 192.168.5.4 mnode4 ingress-error-pages-54454dc79b-hhb4f 1/1 Running 0 2h 192.168.2.5 mnode5 ingress-error-pages-54454dc79b-twpgc 1/1 Running 0 2h 192.168.4.4 mnode2 ``OpenStack PODs`` .. code-block:: console ubuntu@mnode1:~$ kubectl get pods -n openstack --show-all=false -o wide Flag --show-all has been deprecated, will be removed in an upcoming release NAME READY STATUS RESTARTS AGE IP NODE cinder-api-66f4f9678-2lgwk 1/1 Unknown 0 47m 192.168.3.41 mnode3 cinder-api-66f4f9678-flvr5 1/1 Running 0 47m 192.168.0.202 mnode1 cinder-api-66f4f9678-w5xhd 1/1 Running 0 26m 192.168.4.45 mnode2 cinder-backup-659b68b474-582kr 1/1 Running 0 47m 192.168.4.39 mnode2 cinder-scheduler-6778f6f88c-mm9mt 1/1 Running 0 47m 192.168.0.201 mnode1 cinder-volume-79b9bd8bb9-qsxdk 1/1 Running 0 47m 192.168.4.40 mnode2 glance-api-676fd49d4d-4tnm6 1/1 Running 0 26m 192.168.0.212 mnode1 glance-api-676fd49d4d-j4bdb 1/1 Unknown 0 51m 192.168.3.37 mnode3 glance-api-676fd49d4d-wtxqt 1/1 Running 0 51m 192.168.4.31 mnode2 ingress-7b4bc84cdd-9fs78 1/1 Running 0 2h 192.168.5.3 mnode4 ingress-7b4bc84cdd-wztz7 1/1 Running 0 2h 192.168.1.4 mnode6 ingress-error-pages-586c7f86d6-2jl5q 1/1 Running 0 2h 192.168.2.4 mnode5 ingress-error-pages-586c7f86d6-455j5 1/1 Unknown 0 2h 192.168.3.3 mnode3 ingress-error-pages-586c7f86d6-55j4x 1/1 Running 0 26m 192.168.4.47 mnode2 keystone-api-5bcc7cb698-dzm8q 1/1 Running 0 1h 192.168.4.24 mnode2 keystone-api-5bcc7cb698-vvwwr 1/1 Unknown 0 1h 192.168.3.25 mnode3 keystone-api-5bcc7cb698-wx5l6 1/1 Running 0 26m 192.168.0.213 mnode1 mariadb-ingress-84894687fd-9lmpx 1/1 Running 0 26m 192.168.4.48 mnode2 mariadb-ingress-84894687fd-dfnkm 1/1 Unknown 2 1h 192.168.3.20 mnode3 mariadb-ingress-error-pages-78fb865f84-p8lpg 1/1 Running 0 1h 192.168.4.17 mnode2 mariadb-server-0 1/1 Running 0 1h 192.168.4.18 mnode2 memcached-memcached-5db74ddfd5-926ln 1/1 Running 0 26m 192.168.4.49 mnode2 memcached-memcached-5db74ddfd5-wfr9q 1/1 Unknown 0 1h 192.168.3.23 mnode3 rabbitmq-rabbitmq-0 1/1 Unknown 0 1h 192.168.3.21 mnode3 rabbitmq-rabbitmq-1 1/1 Running 0 1h 192.168.4.19 mnode2 rabbitmq-rabbitmq-2 1/1 Running 0 1h 192.168.0.195 mnode1 ================================================ FILE: doc/source/testing/ceph-resiliency/README.rst ================================================ ======================================== Resiliency Tests for OpenStack-Helm/Ceph ======================================== Mission ======= The goal of our resiliency tests for `OpenStack-Helm/Ceph `_ is to show symptoms of software/hardware failure and provide the solutions. Caveats: - Our focus lies on resiliency for various failure scenarios but not on performance or stress testing. Software Failure ================ * `Monitor failure <./monitor-failure.html>`_ * `OSD failure <./osd-failure.html>`_ Hardware Failure ================ * `Disk failure <./disk-failure.html>`_ * `Host failure <./host-failure.html>`_ ================================================ FILE: doc/source/testing/ceph-resiliency/disk-failure.rst ================================================ ============ Disk Failure ============ Test Environment ================ - Cluster size: 4 host machines - Number of disks: 24 (= 6 disks per host * 4 hosts) - Kubernetes version: 1.10.5 - Ceph version: 12.2.3 - OpenStack-Helm commit: 25e50a34c66d5db7604746f4d2e12acbdd6c1459 Case: A disk fails ================== Symptom: -------- This is to test a scenario when a disk failure happens. We monitor the ceph status and notice one OSD (osd.2) on voyager4 which has ``/dev/sdh`` as a backend is down. .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN too few PGs per OSD (23 < min 30) mon voyager1 is low on available space services: mon: 3 daemons, quorum voyager1,voyager2,voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 23 up, 23 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2548 MB used, 42814 GB / 42816 GB avail pgs: 182 active+clean .. code-block:: console (mon-pod):/# ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 43.67981 root default -9 10.91995 host voyager1 5 hdd 1.81999 osd.5 up 1.00000 1.00000 6 hdd 1.81999 osd.6 up 1.00000 1.00000 10 hdd 1.81999 osd.10 up 1.00000 1.00000 17 hdd 1.81999 osd.17 up 1.00000 1.00000 19 hdd 1.81999 osd.19 up 1.00000 1.00000 21 hdd 1.81999 osd.21 up 1.00000 1.00000 -3 10.91995 host voyager2 1 hdd 1.81999 osd.1 up 1.00000 1.00000 4 hdd 1.81999 osd.4 up 1.00000 1.00000 11 hdd 1.81999 osd.11 up 1.00000 1.00000 13 hdd 1.81999 osd.13 up 1.00000 1.00000 16 hdd 1.81999 osd.16 up 1.00000 1.00000 18 hdd 1.81999 osd.18 up 1.00000 1.00000 -2 10.91995 host voyager3 0 hdd 1.81999 osd.0 up 1.00000 1.00000 3 hdd 1.81999 osd.3 up 1.00000 1.00000 12 hdd 1.81999 osd.12 up 1.00000 1.00000 20 hdd 1.81999 osd.20 up 1.00000 1.00000 22 hdd 1.81999 osd.22 up 1.00000 1.00000 23 hdd 1.81999 osd.23 up 1.00000 1.00000 -4 10.91995 host voyager4 2 hdd 1.81999 osd.2 down 0 1.00000 7 hdd 1.81999 osd.7 up 1.00000 1.00000 8 hdd 1.81999 osd.8 up 1.00000 1.00000 9 hdd 1.81999 osd.9 up 1.00000 1.00000 14 hdd 1.81999 osd.14 up 1.00000 1.00000 15 hdd 1.81999 osd.15 up 1.00000 1.00000 Solution: --------- To replace the failed OSD, execute the following procedure: 1. From the Kubernetes cluster, remove the failed OSD pod, which is running on ``voyager4``: .. code-block:: console $ kubectl label nodes --all ceph_maintenance_window=inactive $ kubectl label nodes voyager4 --overwrite ceph_maintenance_window=active $ kubectl patch -n ceph ds ceph-osd-default-64779b8c -p='{"spec":{"template":{"spec":{"nodeSelector":{"ceph-osd":"enabled","ceph_maintenance_window":"inactive"}}}}}' Note: To find the daemonset associated with a failed OSD, check out the followings: .. code-block:: console (voyager4)$ ps -ef|grep /usr/bin/ceph-osd (voyager1)$ kubectl get ds -n ceph (voyager1)$ kubectl get ds -n ceph -o yaml 2. Remove the failed OSD (OSD ID = 2 in this example) from the Ceph cluster: .. code-block:: console (mon-pod):/# ceph osd lost 2 (mon-pod):/# ceph osd crush remove osd.2 (mon-pod):/# ceph auth del osd.2 (mon-pod):/# ceph osd rm 2 3. Find that Ceph is healthy with a lost OSD (i.e., a total of 23 OSDs): .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN too few PGs per OSD (23 < min 30) mon voyager1 is low on available space services: mon: 3 daemons, quorum voyager1,voyager2,voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 23 osds: 23 up, 23 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2551 MB used, 42814 GB / 42816 GB avail pgs: 182 active+clean 4. Replace the failed disk with a new one. If you repair (not replace) the failed disk, you may need to run the following: .. code-block:: console (voyager4)$ parted /dev/sdh mklabel msdos 5. Start a new OSD pod on ``voyager4``: .. code-block:: console $ kubectl label nodes voyager4 --overwrite ceph_maintenance_window=inactive 6. Validate the Ceph status (i.e., one OSD is added, so the total number of OSDs becomes 24): .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN too few PGs per OSD (22 < min 30) mon voyager1 is low on available space services: mon: 3 daemons, quorum voyager1,voyager2,voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 24 up, 24 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2665 MB used, 44675 GB / 44678 GB avail pgs: 182 active+clean ================================================ FILE: doc/source/testing/ceph-resiliency/failure-domain.rst ================================================ .. -*- coding: utf-8 -*- .. NOTE TO MAINTAINERS: use rst2html script to convert .rst to .html rst2html ./failure-domain.rst ./failure-domain.html open ./failure-domain.html ============================== Failure Domains in CRUSH Map ============================== .. contents:: .. sectnum:: Overview ======== The `CRUSH Map `__ in a Ceph cluster is best visualized as an inverted tree. The hierarchical layout describes the physical topology of the Ceph cluster. Through the physical topology, failure domains are conceptualized from the different branches in the inverted tree. CRUSH rules are created and map to failure domains with data placement policy to distribute the data. The internal nodes (non-leaves and non-root) in the hierarchy are identified as buckets. Each bucket is a hierarchical aggregation of storage locations and their assigned weights. These are the types defined by CRUSH as the supported buckets. :: # types type 0 osd type 1 host type 2 chassis type 3 rack type 4 row type 5 pdu type 6 pod type 7 room type 8 datacenter type 9 region type 10 root This guide describes the host and rack buckets and their role in constructing a CRUSH Map with separate failure domains. Once a Ceph cluster is configured with the expected CRUSh Map and Rule, the PGs of the designated pool are verified with a script (**utils-checkPGs.py**) to ensure that the OSDs in all the PGs reside in separate failure domains. Ceph Environment ================ The ceph commands and scripts described in this write-up are executed as Linux user root on one of orchestration nodes and one of the ceph monitors deployed as kubernetes pods. The root user has the credential to execute all the ceph commands. On a kubernetes cluster, a separate namespace named **ceph** is configured for the ceph cluster. Include the **ceph** namespace in **kubectl** when executing this command. A kubernetes pod is a collection of docker containers sharing a network and mount namespace. It is the basic unit of deployment in the kubernetes cluster. The node in the kubernetes cluster where the orchestration operations are performed needs access to the **kubectl** command. In this guide, this node is referred to as the orchestration node. On this node, you can list all the pods that are deployed. To execute a command in a given pod, use **kubectl** to locate the name of the pod and switch to it to execute the command. Orchestration Node ------------------ To gain access to the kubernetes orchestration node, use your login credential and the authentication procedure assigned to you. For environments setup with SSH key-based access, your id_rsa.pub (generated through the ssh-keygen) public key should be in your ~/.ssh/authorized_keys file on the orchestration node. The kubernetes and ceph commands require the root login credential to execute. Your Linux login requires the *sudo* privilege to execute commands as user root. On the orchestration node, acquire the root's privilege with your Linux login through the *sudo* command. :: [orchestration]$ sudo -i : [orchestration]# Kubernetes Pods --------------- On the orchestration node, execute the **kubectl** command to list the specific set of pods with the **--selector** option. This **kubectl** command lists all the ceph monitor pods. :: [orchestration]# kubectl get pods -n ceph --selector component=mon NAME READY STATUS RESTARTS AGE ceph-mon-85mlt 2/2 Running 0 9d ceph-mon-9mpnb 2/2 Running 0 9d ceph-mon-rzzqr 2/2 Running 0 9d ceph-mon-snds8 2/2 Running 0 9d ceph-mon-snzwx 2/2 Running 0 9d The following **kubectl** command lists the Ceph OSD pods. :: [orchestration]# kubectl get pods -n ceph --selector component=osd NAME READY STATUS RESTARTS AGE ceph-osd-default-166a1044-95s74 2/2 Running 0 9d ceph-osd-default-166a1044-bglnm 2/2 Running 0 9d ceph-osd-default-166a1044-lq5qq 2/2 Running 0 9d ceph-osd-default-166a1044-lz6x6 2/2 Running 0 9d . . . To list all the pods in all the namespaces, execute this **kubectl** command. :: [orchestration]# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE ceph ceph-bootstrap-rpzld 0/1 Completed 0 10d ceph ceph-cephfs-client-key-generator-pvzs6 0/1 Completed 0 10d Execute Commands in Pods ^^^^^^^^^^^^^^^^^^^^^^^^ To execute multiple commands in a pod, you can switch to the execution context of the pod with a /bin/bash session. :: [orchestration]# kubectl exec -it ceph-mon-85mlt -n ceph -- /bin/bash [ceph-mon]# ceph status cluster: id: 07c31d0f-bcc6-4db4-aadf-2d2a0f13edb8 health: HEALTH_OK services: mon: 5 daemons, quorum host1,host2,host3,host4,host5 mgr: host6(active), standbys: host1 mds: cephfs-1/1/1 up {0=mds-ceph-mds-7cb4f57cc-prh87=up:active}, 1 up:standby osd: 72 osds: 72 up, 72 in rgw: 2 daemons active data: pools: 20 pools, 3944 pgs objects: 86970 objects, 323 GB usage: 1350 GB used, 79077 GB / 80428 GB avail pgs: 3944 active+clean io: client: 981 kB/s wr, 0 op/s rd, 84 op/s wr To verify that you are executing within the context of a pod. Display the content of the */proc/self/cgroup* control group file. The *kubepods* output in the cgroup file shows that you're executing in a docker container of a pod. :: [ceph-mon]# cat /proc/self/cgroup 11:hugetlb:/kubepods/besteffort/podafb3689c-8c5b-11e8-be6a-246e96290f14/ff6cbc58348a44722ee6a493845b9c2903fabdce80d0902d217cc4d6962d7b53 . . . To exit the pod and resume the orchestration node's execution context. :: [ceph-mon]# exit [orchestration]# To verify that you are executing on the orchestration node's context, display the */proc/self/cgroup* control group file. You would not see the *kubepods* docker container in the output. :: [orchestration]# cat /proc/self/cgroup 11:blkio:/user.slice 10:freezer:/ 9:hugetlb:/ . . . It is also possible to run the ceph commands via the **kubectl exec** without switching to a pod's container. :: [orchestration]# kubectl exec ceph-mon-9mpnb -n ceph -- ceph status cluster: id: 07c31d0f-bcc6-4db4-aadf-2d2a0f13edb8 health: HEALTH_OK . . . Failure Domains =============== A failure domain provides the fault isolation for the data and it corresponds to a branch on the hierarchical topology. To protect against data loss, OSDs that are allocated to PGs should be chosen from different failure domains. Losing a branch takes down all the OSDs in that branch only and OSDs in the other branches are not effected. In a data center, baremetal hosts are typically installed in a rack (refrigerator size cabinet). Multiple racks with hosts in each rack are used to provision the OSDs running on each host. A rack is envisioned as a branch in the CRUSH topology. To provide data redundancy, ceph maintains multiple copies of the data. The total number of copies to store for each piece of data is determined by the ceph **osd_pool_default_size** ceph.conf parameter. With this parameter set to 3, each piece of the data has 3 copies that gets stored in a pool. Each copy is stored on different OSDs allocated from different failure domains. Host ---- Choosing host as the failure domain lacks all the protections against data loss. To illustrate, a Ceph cluster has been provisioned with six hosts and four OSDs on each host. The hosts are enclosed in respective racks where each rack contains two hosts. In the configuration of the Ceph cluster, without explicit instructions on where the host and rack buckets should be placed, Ceph would create a CRUSH map without the rack bucket. A CRUSH rule that get created uses the host as the failure domain. With the size (replica) of a pool set to 3, the OSDs in all the PGs are allocated from different hosts. :: root=default ├── host1 │   ├── osd.1 │   ├── osd.2 │   ├── osd.3 │   └── osd.4 ├── host2 │   ├── osd.5 │   ├── osd.6 │   ├── osd.7 │   └── osd.8 ├── host3 │   ├── osd.9 │   ├── osd.10 │   ├── osd.11 │   └── osd.12 ├── host4 │   ├── osd.13 │   ├── osd.14 │   ├── osd.15 │   └── osd.16 ├── host5 │   ├── osd.17 │   ├── osd.18 │   ├── osd.19 │   └── osd.20 └── host6 ├── osd.21 ├── osd.22 ├── osd.23 └── osd.24 On this ceph cluster, it has a CRUSH rule that uses the host as the failure domain. :: # ceph osd crush rule ls replicated_host # ceph osd crush rule dump replicated_host { "rule_id": 0, "rule_name": "replicated_host", "ruleset": 0, "type": 1, "min_size": 1, "max_size": 10, "steps": [ { "op": "take", "item": -1, "item_name": "default" }, { "op": "chooseleaf_firstn", "num": 0, "type": "host" }, { "op": "emit" } ] } Verify the CRUSH rule that is assigned to the ceph pool. In this example, the rbd pool is used. :: # ceph osd pool get rbd crush_rule crush_rule: replicated_host # ceph osd pool get rbd size size: 3 # ceph osd pool get rbd pg_num pg_num: 1024 To verify that the OSDs in all the PGs are allocated from different hosts, invoke the **utils-checkPGs.py** utility on the ceph pool. The offending PGs are printed to stdout. :: # /tmp/utils-checkPGs.py rbd Checking PGs in pool rbd ... Passed With host as the failure domain, quite possibly, some of the PGs might have OSDs allocated from different hosts that are located in the same rack. For example, one PG might have OSD numbers [1, 8, 13]. OSDs 1 and 8 are found on hosts located in rack1. When rack1 suffers a catastrophe failure, PGs with OSDs allocated from the hosts in rack1 would be severely degraded. Rack ---- Choosing rack as the failure domain provides better protection against data loss. To prevent PGs with OSDs allocated from hosts that are located in the same rack, configure the CRUSH hierarchy with the rack buckets. In each rack bucket, it contains the hosts that reside in the same physical rack. A CRUSH Rule is configured with rack as the failure domain. In the following hierarchical topology, the Ceph cluster was configured with three rack buckets. Each bucket has two hosts. In pools that were created with the CRUSH rule set to rack, the OSDs in all the PGs are allocated from the distinct rack. :: root=default ├── rack1 │   ├── host1 │   │   ├── osd.1 │   │   ├── osd.2 │   │   ├── osd.3 │   │   └── osd.4 │   └── host2 │   ├── osd.5 │   ├── osd.6 │   ├── osd.7 │   └── osd.8 ├── rack2 │   ├── host3 │   │   ├── osd.9 │   │   ├── osd.10 │   │   ├── osd.11 │   │   └── osd.12 │   └── host4 │   ├── osd.13 │   ├── osd.14 │   ├── osd.15 │   └── osd.16 └── rack3 ├── host5 │   ├── osd.17 │   ├── osd.18 │   ├── osd.19 │   └── osd.20 └── host6 ├── osd.21 ├── osd.22 ├── osd.23 └── osd.24 Verify the Ceph cluster has a CRUSH rule with rack as the failure domain. :: # ceph osd crush rule ls rack_replicated_rule # ceph osd crush rule dump rack_replicated_rule { "rule_id": 2, "rule_name": "rack_replicated_rule", "ruleset": 2, "type": 1, "min_size": 1, "max_size": 10, "steps": [ { "op": "take", "item": -1, "item_name": "default" }, { "op": "chooseleaf_firstn", "num": 0, "type": "rack" }, { "op": "emit" } ] } Create a ceph pool with its CRUSH rule set to the rack's rule. :: # ceph osd pool create rbd 2048 2048 replicated rack_replicated_rule pool 'rbd' created # ceph osd pool get rbd crush_rule crush_rule: rack_replicated_rule # ceph osd pool get rbd size size: 3 # ceph osd pool get rbd pg_num pg_num: 2048 Invoke the **utils-checkPGs.py** script on the pool to verify that there are no PGs with OSDs allocated from the same rack. The offending PGs are printed to stdout. :: # /tmp/utils-checkPGs.py rbd Checking PGs in pool rbd ... Passed CRUSH Map and Rule ================== On a properly configured Ceph cluster, there are different ways to view the CRUSH hierarchy. ceph CLI -------- Print to stdout the CRUSH hierarchy with the ceph CLI. :: root@host5:/# ceph osd crush tree ID CLASS WEIGHT TYPE NAME -1 78.47974 root default -15 26.15991 rack rack1 -2 13.07996 host host1 0 hdd 1.09000 osd.0 1 hdd 1.09000 osd.1 2 hdd 1.09000 osd.2 3 hdd 1.09000 osd.3 4 hdd 1.09000 osd.4 5 hdd 1.09000 osd.5 6 hdd 1.09000 osd.6 7 hdd 1.09000 osd.7 8 hdd 1.09000 osd.8 9 hdd 1.09000 osd.9 10 hdd 1.09000 osd.10 11 hdd 1.09000 osd.11 -5 13.07996 host host2 12 hdd 1.09000 osd.12 13 hdd 1.09000 osd.13 14 hdd 1.09000 osd.14 15 hdd 1.09000 osd.15 16 hdd 1.09000 osd.16 17 hdd 1.09000 osd.17 18 hdd 1.09000 osd.18 19 hdd 1.09000 osd.19 20 hdd 1.09000 osd.20 21 hdd 1.09000 osd.21 22 hdd 1.09000 osd.22 23 hdd 1.09000 osd.23 -16 26.15991 rack rack2 -13 13.07996 host host3 53 hdd 1.09000 osd.53 54 hdd 1.09000 osd.54 58 hdd 1.09000 osd.58 59 hdd 1.09000 osd.59 64 hdd 1.09000 osd.64 65 hdd 1.09000 osd.65 66 hdd 1.09000 osd.66 67 hdd 1.09000 osd.67 68 hdd 1.09000 osd.68 69 hdd 1.09000 osd.69 70 hdd 1.09000 osd.70 71 hdd 1.09000 osd.71 -9 13.07996 host host4 36 hdd 1.09000 osd.36 37 hdd 1.09000 osd.37 38 hdd 1.09000 osd.38 39 hdd 1.09000 osd.39 40 hdd 1.09000 osd.40 41 hdd 1.09000 osd.41 42 hdd 1.09000 osd.42 43 hdd 1.09000 osd.43 44 hdd 1.09000 osd.44 45 hdd 1.09000 osd.45 46 hdd 1.09000 osd.46 47 hdd 1.09000 osd.47 -17 26.15991 rack rack3 -11 13.07996 host host5 48 hdd 1.09000 osd.48 49 hdd 1.09000 osd.49 50 hdd 1.09000 osd.50 51 hdd 1.09000 osd.51 52 hdd 1.09000 osd.52 55 hdd 1.09000 osd.55 56 hdd 1.09000 osd.56 57 hdd 1.09000 osd.57 60 hdd 1.09000 osd.60 61 hdd 1.09000 osd.61 62 hdd 1.09000 osd.62 63 hdd 1.09000 osd.63 -7 13.07996 host host6 24 hdd 1.09000 osd.24 25 hdd 1.09000 osd.25 26 hdd 1.09000 osd.26 27 hdd 1.09000 osd.27 28 hdd 1.09000 osd.28 29 hdd 1.09000 osd.29 30 hdd 1.09000 osd.30 31 hdd 1.09000 osd.31 32 hdd 1.09000 osd.32 33 hdd 1.09000 osd.33 34 hdd 1.09000 osd.34 35 hdd 1.09000 osd.35 root@host5:/# To see weight and affinity of each OSD. :: root@host5:/# ceph osd tree ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 78.47974 root default -15 26.15991 rack rack1 -2 13.07996 host host1 0 hdd 1.09000 osd.0 up 1.00000 1.00000 1 hdd 1.09000 osd.1 up 1.00000 1.00000 2 hdd 1.09000 osd.2 up 1.00000 1.00000 3 hdd 1.09000 osd.3 up 1.00000 1.00000 4 hdd 1.09000 osd.4 up 1.00000 1.00000 5 hdd 1.09000 osd.5 up 1.00000 1.00000 6 hdd 1.09000 osd.6 up 1.00000 1.00000 7 hdd 1.09000 osd.7 up 1.00000 1.00000 8 hdd 1.09000 osd.8 up 1.00000 1.00000 9 hdd 1.09000 osd.9 up 1.00000 1.00000 10 hdd 1.09000 osd.10 up 1.00000 1.00000 11 hdd 1.09000 osd.11 up 1.00000 1.00000 -5 13.07996 host host2 12 hdd 1.09000 osd.12 up 1.00000 1.00000 13 hdd 1.09000 osd.13 up 1.00000 1.00000 14 hdd 1.09000 osd.14 up 1.00000 1.00000 15 hdd 1.09000 osd.15 up 1.00000 1.00000 16 hdd 1.09000 osd.16 up 1.00000 1.00000 17 hdd 1.09000 osd.17 up 1.00000 1.00000 18 hdd 1.09000 osd.18 up 1.00000 1.00000 19 hdd 1.09000 osd.19 up 1.00000 1.00000 20 hdd 1.09000 osd.20 up 1.00000 1.00000 21 hdd 1.09000 osd.21 up 1.00000 1.00000 22 hdd 1.09000 osd.22 up 1.00000 1.00000 23 hdd 1.09000 osd.23 up 1.00000 1.00000 crushtool CLI ------------- To extract the CRUSH Map from a running cluster and convert it into ascii text. :: # ceph osd getcrushmap -o /tmp/cm.bin 100 # crushtool -d /tmp/cm.bin -o /tmp/cm.rack.ascii # cat /tmp/cm.rack.ascii . . . # buckets host host1 { id -2 # do not change unnecessarily id -3 class hdd # do not change unnecessarily # weight 13.080 alg straw2 hash 0 # rjenkins1 item osd.0 weight 1.090 item osd.1 weight 1.090 item osd.2 weight 1.090 item osd.3 weight 1.090 item osd.4 weight 1.090 item osd.5 weight 1.090 item osd.6 weight 1.090 item osd.7 weight 1.090 item osd.8 weight 1.090 item osd.9 weight 1.090 item osd.10 weight 1.090 item osd.11 weight 1.090 } host host2 { id -5 # do not change unnecessarily id -6 class hdd # do not change unnecessarily # weight 13.080 alg straw2 hash 0 # rjenkins1 item osd.12 weight 1.090 item osd.13 weight 1.090 item osd.14 weight 1.090 item osd.15 weight 1.090 item osd.16 weight 1.090 item osd.18 weight 1.090 item osd.19 weight 1.090 item osd.17 weight 1.090 item osd.20 weight 1.090 item osd.21 weight 1.090 item osd.22 weight 1.090 item osd.23 weight 1.090 } rack rack1 { id -15 # do not change unnecessarily id -20 class hdd # do not change unnecessarily # weight 26.160 alg straw2 hash 0 # rjenkins1 item host1 weight 13.080 item host2 weight 13.080 } . . . root default { id -1 # do not change unnecessarily id -4 class hdd # do not change unnecessarily # weight 78.480 alg straw2 hash 0 # rjenkins1 item rack1 weight 26.160 item rack2 weight 26.160 item rack3 weight 26.160 } # rules rule replicated_rack { id 2 type replicated min_size 1 max_size 10 step take default step chooseleaf firstn 0 type rack step emit } # end crush map The **utils-checkPGs.py** script can read the same data from memory and construct the failure domains with OSDs. Verify the OSDs in each PG against the constructed failure domains. Configure the Failure Domain in CRUSH Map ========================================= The Ceph ceph-osd, ceph-client and cinder charts accept configuration parameters to set the Failure Domain for CRUSH. The options available are **failure_domain**, **failure_domain_by_hostname**, **failure_domain_name** and **crush_rule** :: ceph-osd specific overrides failure_domain: Set the CRUSH bucket type for your OSD to reside in. (DEFAULT: "host") failure_domain_by_hostname: Specify the portion of the hostname to use for your failure domain bucket name. (DEFAULT: "false") failure_domain_name: Manually name the failure domain bucket name. This configuration option should only be used when using host based overrides. (DEFAULT: "false") :: ceph-client and cinder specific overrides crush_rule**: Set the crush rule for a pool (DEFAULT: "replicated_rule") An example of a lab enviroment had the following paramters set for the ceph yaml override file to apply a rack level failure domain within CRUSH. :: endpoints: identity: namespace: openstack object_store: namespace: ceph ceph_mon: namespace: ceph network: public: 10.0.0.0/24 cluster: 10.0.0.0/24 deployment: storage_secrets: true ceph: true csi_rbd_provisioner: true rbd_provisioner: false cephfs_provisioner: false client_secrets: false rgw_keystone_user_and_endpoints: false bootstrap: enabled: true conf: ceph: global: fsid: 6c12a986-148d-45a7-9120-0cf0522ca5e0 rgw_ks: enabled: true pool: default: crush_rule: rack_replicated_rule crush: tunables: null target: # NOTE(portdirect): 5 nodes, with one osd per node osd: 18 pg_per_osd: 100 storage: osd: - data: type: block-logical location: /dev/vdb journal: type: block-logical location: /dev/vde1 - data: type: block-logical location: /dev/vdc journal: type: block-logical location: /dev/vde2 - data: type: block-logical location: /dev/vdd journal: type: block-logical location: /dev/vde3 overrides: ceph_osd: hosts: - name: osh-1 conf: storage: failure_domain: "rack" failure_domain_name: "rack1" - name: osh-2 conf: storage: failure_domain: "rack" failure_domain_name: "rack1" - name: osh-3 conf: storage: failure_domain: "rack" failure_domain_name: "rack2" - name: osh-4 conf: storage: failure_domain: "rack" failure_domain_name: "rack2" - name: osh-5 conf: storage: failure_domain: "rack" failure_domain_name: "rack3" - name: osh-6 conf: storage: failure_domain: "rack" failure_domain_name: "rack3" .. NOTE:: Note that the cinder chart will need an override configured to ensure the cinder pools in Ceph are using the correct **crush_rule**. :: pod: replicas: api: 2 volume: 1 scheduler: 1 backup: 1 conf: cinder: DEFAULT: backup_driver: cinder.backup.drivers.swift ceph: pools: backup: replicated: 3 crush_rule: rack_replicated_rule chunk_size: 8 volume: replicated: 3 crush_rule: rack_replicated_rule chunk_size: 8 The charts can be updated with these overrides pre or post deployment. If this is a post deployment change then the following steps will apply for a gate based openstack-helm deployment. :: cd /opt/openstack-helm helm upgrade --install ceph-osd ../openstack-helm/ceph-osd --namespace=ceph --values=/tmp/ceph.yaml kubectl delete jobs/ceph-rbd-pool -n ceph helm upgrade --install ceph-client ../openstack-helm/ceph-client --namespace=ceph --values=/tmp/ceph.yaml helm delete cinder --purge helm upgrade --install cinder ./cinder --namespace=openstack --values=/tmp/cinder.yaml .. NOTE:: There will be a brief interuption of I/O and a data movement of placement groups in Ceph while these changes are applied. The data movement operation can take several minutes to several days to complete. The utils-checkPGs.py Script ============================ The purpose of the **utils-checkPGs.py** script is to check whether a PG has OSDs allocated from the same failure domain. The violating PGs with their respective OSDs are printed to the stdout. In this example, a pool was created with the CRUSH rule set to the host failure domain. The ceph cluster was configured with the rack buckets. The CRUSH algorithm allocated the OSDs from different hosts in each PG. The rack buckets were ignored and thus the duplicate racks which get reported by the script. :: root@host5:/# /tmp/utils-checkPGs.py cmTestPool Checking PGs in pool cmTestPool ... Failed OSDs [44, 32, 53] in PG 20.a failed check in rack [u'rack2', u'rack2', u'rack2'] OSDs [61, 5, 12] in PG 20.19 failed check in rack [u'rack1', u'rack1', u'rack1'] OSDs [69, 9, 15] in PG 20.2a failed check in rack [u'rack1', u'rack1', u'rack1'] . . . .. NOTE:: The **utils-checkPGs.py** utility is executed on-demand. It is intended to be executed on one of the ceph-mon pods. If the **utils-checkPGs.py** script did not find any violation, it prints Passed. In this example, the ceph cluster was configured with the rack buckets. The rbd pool was created with its CRUSH rule set to the rack. The **utils-checkPGs.py** script did not find duplicate racks in PGs. :: root@host5:/# /tmp/utils-checkPGs.py rbd Checking PGs in pool rbd ... Passed Invoke the **utils-checkPGs.py** script with the --help option to get the script's usage. :: root@host5:/# /tmp/utils-checkPGs.py --help usage: utils-checkPGs.py [-h] PoolName [PoolName ...] Cross-check the OSDs assigned to the Placement Groups (PGs) of a ceph pool with the CRUSH topology. The cross-check compares the OSDs in a PG and verifies the OSDs reside in separate failure domains. PGs with OSDs in the same failure domain are flagged as violation. The offending PGs are printed to stdout. This CLI is executed on-demand on a ceph-mon pod. To invoke the CLI, you can specify one pool or list of pools to check. The special pool name All (or all) checks all the pools in the ceph cluster. positional arguments: PoolName List of pools (or All) to validate the PGs and OSDs mapping optional arguments: -h, --help show this help message and exit root@host5:/# The source for the **utils-checkPGs.py** script is available at **openstack-helm/ceph-mon/templates/bin/utils/_checkPGs.py.tpl**. Ceph Deployments ================ Through testing and verification, you derive at a CRUSH Map with the buckets that are deemed beneficial to your ceph cluster. Standardize on the verified CRUSH map to have the consistency in all the Ceph deployments across the data centers. Mimicking the hierarchy in your CRUSH Map with the physical hardware setup should provide the needed information on the topology layout. With the racks layout, each rack can store a replica of your data. To validate a ceph cluster with the number of replica that is based on the number of racks: #. The number of physical racks and the number of replicas are 3, respectively. Create a ceph pool with replica set to 3 and pg_num set to (# of OSDs * 50) / 3 and round the number to the next power-of-2. For example, if the calculation is 240, round it to 256. Assuming the pool you just created had 256 PGs. In each PG, verify the OSDs are chosen from the three racks, respectively. Use the **utils-checkPGs.py** script to verify the OSDs in all the PGs of the pool. #. The number of physical racks is 2 and the number of replica is 3. Create a ceph pool as described in the previous step. In the pool you created, in each PG, verify two of the OSDs are chosen from the two racks, respectively. The third OSD can come from one of the two racks but not from the same hosts as the other two OSDs. Data Movement ============= Changes to the CRUSH Map always trigger data movement. It is prudent that you plan accordingly when restructuring the CRUSH Map. Once started, the CRUSH Map restructuring runs to completion and can neither be stopped nor suspended. On a busy Ceph cluster with live transactions, it is always safer to use divide-and-conquer approach to complete small chunk of works in multiple sessions. Watch the progress of the data movement while the Ceph cluster re-balances itself. :: # watch ceph status cluster: id: 07c31d0f-bcc6-4db4-aadf-2d2a0f13edb8 health: HEALTH_WARN 137084/325509 objects misplaced (42.114%) Degraded data redundancy: 28/325509 objects degraded (0.009%), 15 pgs degraded services: mon: 5 daemons, quorum host1,host2,host3,host4,host5 mgr: host6(active), standbys: host1 mds: cephfs-1/1/1 up {0=mds-ceph-mds-7cb4f57cc-prh87=up:active}, 1 up:standby osd: 72 osds: 72 up, 72 in; 815 remapped pgs rgw: 2 daemons active data: pools: 19 pools, 2920 pgs objects: 105k objects, 408 GB usage: 1609 GB used, 78819 GB / 80428 GB avail pgs: 28/325509 objects degraded (0.009%) 137084/325509 objects misplaced (42.114%) 2085 active+clean 790 active+remapped+backfill_wait 22 active+remapped+backfilling 15 active+recovery_wait+degraded 4 active+recovery_wait+remapped 4 active+recovery_wait io: client: 11934 B/s rd, 3731 MB/s wr, 2 op/s rd, 228 kop/s wr recovery: 636 MB/s, 163 objects/s At the time this **ceph status** command was executed, the status's output showed that the ceph cluster was going through re-balancing. Among the overall 2920 pgs, 2085 of them are in **active+clean** state. The remaining pgs are either being remapped or recovered. As the ceph cluster continues its re-balance, the number of pgs in **active+clean** increases. :: # ceph status cluster: id: 07c31d0f-bcc6-4db4-aadf-2d2a0f13edb8 health: HEALTH_OK services: mon: 5 daemons, quorum host1,host2,host3,host4,host5 mgr: host6(active), standbys: host1 mds: cephfs-1/1/1 up {0=mds-ceph-mds-7cc55c9695-lj22d=up:active}, 1 up:standby osd: 72 osds: 72 up, 72 in rgw: 2 daemons active data: pools: 19 pools, 2920 pgs objects: 134k objects, 519 GB usage: 1933 GB used, 78494 GB / 80428 GB avail pgs: 2920 active+clean io: client: 1179 B/s rd, 971 kB/s wr, 1 op/s rd, 41 op/s wr When the overall number of pgs is equal to the number of **active+clean** pgs, the health of the ceph cluster changes to **HEALTH_OK** (assuming there are no other warning conditions). ================================================ FILE: doc/source/testing/ceph-resiliency/host-failure.rst ================================================ ============ Host Failure ============ Test Environment ================ - Cluster size: 4 host machines - Number of disks: 24 (= 6 disks per host * 4 hosts) - Kubernetes version: 1.10.5 - Ceph version: 12.2.3 - OpenStack-Helm commit: 25e50a34c66d5db7604746f4d2e12acbdd6c1459 Case: One host machine where ceph-mon is running is rebooted ============================================================ Symptom: -------- After reboot (node voyager3), the node status changes to ``NotReady``. .. code-block:: console $ kubectl get nodes NAME STATUS ROLES AGE VERSION voyager1 Ready master 6d v1.10.5 voyager2 Ready 6d v1.10.5 voyager3 NotReady 6d v1.10.5 voyager4 Ready 6d v1.10.5 Ceph status shows that ceph-mon running on ``voyager3`` becomes out of quorum. Also, six osds running on ``voyager3`` are down; i.e., 18 osds are up out of 24 osds. .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN 6 osds down 1 host (6 osds) down Degraded data redundancy: 195/624 objects degraded (31.250%), 8 pgs degraded too few PGs per OSD (17 < min 30) mon voyager1 is low on available space 1/3 mons down, quorum voyager1,voyager2 services: mon: 3 daemons, quorum voyager1,voyager2, out of quorum: voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 18 up, 24 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 208 objects, 3359 bytes usage: 2630 MB used, 44675 GB / 44678 GB avail pgs: 195/624 objects degraded (31.250%) 126 active+undersized 48 active+clean 8 active+undersized+degraded Recovery: --------- The node status of ``voyager3`` changes to ``Ready`` after the node is up again. Also, Ceph pods are restarted automatically. Ceph status shows that the monitor running on ``voyager3`` is now in quorum. .. code-block:: console $ kubectl get nodes NAME STATUS ROLES AGE VERSION voyager1 Ready master 6d v1.10.5 voyager2 Ready 6d v1.10.5 voyager3 Ready 6d v1.10.5 voyager4 Ready 6d v1.10.5 .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN too few PGs per OSD (22 < min 30) mon voyager1 is low on available space services: mon: 3 daemons, quorum voyager1,voyager2,voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 24 up, 24 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 208 objects, 3359 bytes usage: 2635 MB used, 44675 GB / 44678 GB avail pgs: 182 active+clean Case: A host machine where ceph-mon is running is down ====================================================== This is for the case when a host machine (where ceph-mon is running) is down. Symptom: -------- After the host is down (node voyager3), the node status changes to ``NotReady``. .. code-block:: console $ kubectl get nodes NAME STATUS ROLES AGE VERSION voyager1 Ready master 14d v1.10.5 voyager2 Ready 14d v1.10.5 voyager3 NotReady 14d v1.10.5 voyager4 Ready 14d v1.10.5 Ceph status shows that ceph-mon running on ``voyager3`` becomes out of quorum. Also, 6 osds running on ``voyager3`` are down (i.e., 18 out of 24 osds are up). Some placement groups become degraded and undersized. .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN 6 osds down 1 host (6 osds) down Degraded data redundancy: 227/720 objects degraded (31.528%), 8 pgs degraded too few PGs per OSD (17 < min 30) mon voyager1 is low on available space 1/3 mons down, quorum voyager1,voyager2 services: mon: 3 daemons, quorum voyager1,voyager2, out of quorum: voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:stan dby osd: 24 osds: 18 up, 24 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2695 MB used, 44675 GB / 44678 GB avail pgs: 227/720 objects degraded (31.528%) 126 active+undersized 48 active+clean 8 active+undersized+degraded The pod status of ceph-mon and ceph-osd shows as ``NodeLost``. .. code-block:: console $ kubectl get pods -n ceph -o wide|grep voyager3 ceph-mgr-55f68d44b8-hncrq 1/1 Unknown 6 8d 135.207.240.43 voyager3 ceph-mon-6bbs6 1/1 NodeLost 8 8d 135.207.240.43 voyager3 ceph-osd-default-64779b8c-lbkcd 1/1 NodeLost 1 6d 135.207.240.43 voyager3 ceph-osd-default-6ea9de2c-gp7zm 1/1 NodeLost 2 8d 135.207.240.43 voyager3 ceph-osd-default-7544b6da-7mfdc 1/1 NodeLost 2 8d 135.207.240.43 voyager3 ceph-osd-default-7cfc44c1-hhk8v 1/1 NodeLost 2 8d 135.207.240.43 voyager3 ceph-osd-default-83945928-b95qs 1/1 NodeLost 2 8d 135.207.240.43 voyager3 ceph-osd-default-f9249fa9-n7p4v 1/1 NodeLost 3 8d 135.207.240.43 voyager3 After 10+ miniutes, Ceph starts rebalancing with one node lost (i.e., 6 osds down) and the status stablizes with 18 osds. .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN mon voyager1 is low on available space 1/3 mons down, quorum voyager1,voyager2 services: mon: 3 daemons, quorum voyager1,voyager2, out of quorum: voyager3 mgr: voyager1(active), standbys: voyager2 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 18 up, 18 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2025 MB used, 33506 GB / 33508 GB avail pgs: 182 active+clean Recovery: --------- The node status of ``voyager3`` changes to ``Ready`` after the node is up again. Also, Ceph pods are restarted automatically. The Ceph status shows that the monitor running on ``voyager3`` is now in quorum and 6 osds gets back up (i.e., a total of 24 osds are up). .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN too few PGs per OSD (22 < min 30) mon voyager1 is low on available space services: mon: 3 daemons, quorum voyager1,voyager2,voyager3 mgr: voyager1(active), standbys: voyager2 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 24 up, 24 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2699 MB used, 44675 GB / 44678 GB avail pgs: 182 active+clean Also, the pod status of ceph-mon and ceph-osd changes from ``NodeLost`` back to ``Running``. .. code-block:: console $ kubectl get pods -n ceph -o wide|grep voyager3 ceph-mon-6bbs6 1/1 Running 9 8d 135.207.240.43 voyager3 ceph-osd-default-64779b8c-lbkcd 1/1 Running 2 7d 135.207.240.43 voyager3 ceph-osd-default-6ea9de2c-gp7zm 1/1 Running 3 8d 135.207.240.43 voyager3 ceph-osd-default-7544b6da-7mfdc 1/1 Running 3 8d 135.207.240.43 voyager3 ceph-osd-default-7cfc44c1-hhk8v 1/1 Running 3 8d 135.207.240.43 voyager3 ceph-osd-default-83945928-b95qs 1/1 Running 3 8d 135.207.240.43 voyager3 ceph-osd-default-f9249fa9-n7p4v 1/1 Running 4 8d 135.207.240.43 voyager3 ================================================ FILE: doc/source/testing/ceph-resiliency/index.rst ================================================ =============== Ceph Resiliency =============== .. toctree:: :maxdepth: 2 README monitor-failure osd-failure disk-failure host-failure failure-domain validate-object-replication namespace-deletion ================================================ FILE: doc/source/testing/ceph-resiliency/monitor-failure.rst ================================================ =============== Monitor Failure =============== Test Environment ================ - Cluster size: 4 host machines - Number of disks: 24 (= 6 disks per host * 4 hosts) - Kubernetes version: 1.9.3 - Ceph version: 12.2.3 - OpenStack-Helm commit: 28734352741bae228a4ea4f40bcacc33764221eb We have 3 Monitors in this Ceph cluster, one on each of the 3 Monitor hosts. Case: 1 out of 3 Monitor Processes is Down ========================================== This is to test a scenario when 1 out of 3 Monitor processes is down. To bring down 1 Monitor process (out of 3), we identify a Monitor process and kill it from the monitor host (not a pod). .. code-block:: console $ ps -ef | grep ceph-mon ceph 16112 16095 1 14:58 ? 00:00:03 /usr/bin/ceph-mon --cluster ceph --setuser ceph --setgroup ceph -d -i voyager2 --mon-data /var/lib/ceph/mon/ceph-voyager2 --public-addr 135.207.240.42:6789 $ sudo kill -9 16112 In the mean time, we monitored the status of Ceph and noted that it takes about 24 seconds for the killed Monitor process to recover from ``down`` to ``up``. The reason is that Kubernetes automatically restarts pods whenever they are killed. .. code-block:: console (mon-pod):/# ceph -s cluster: id: fd366aef-b356-4fe7-9ca5-1c313fe2e324 health: HEALTH_WARN mon voyager1 is low on available space 1/3 mons down, quorum voyager1,voyager3 services: mon: 3 daemons, quorum voyager1,voyager3, out of quorum: voyager2 mgr: voyager4(active) osd: 24 osds: 24 up, 24 in .. code-block:: console (mon-pod):/# ceph -s cluster: id: fd366aef-b356-4fe7-9ca5-1c313fe2e324 health: HEALTH_WARN mon voyager1 is low on available space 1/3 mons down, quorum voyager1,voyager2 services: mon: 3 daemons, quorum voyager1,voyager2,voyager3 mgr: voyager4(active) osd: 24 osds: 24 up, 24 in We also monitored the status of the Monitor pod through ``kubectl get pods -n ceph``, and the status of the pod (where a Monitor process is killed) changed as follows: ``Running`` -> ``Error`` -> ``Running`` and this recovery process takes about 24 seconds. Case: 2 out of 3 Monitor Processes are Down =========================================== This is to test a scenario when 2 out of 3 Monitor processes are down. To bring down 2 Monitor processes (out of 3), we identify two Monitor processes and kill them from the 2 monitor hosts (not a pod). We monitored the status of Ceph when the Monitor processes are killed and noted that the symptoms are similar to when 1 Monitor process is killed: - It takes longer (about 1 minute) for the killed Monitor processes to recover from ``down`` to ``up``. - The status of the pods (where the two Monitor processes are killed) changed as follows: ``Running`` -> ``Error`` -> ``CrashLoopBackOff`` -> ``Running`` and this recovery process takes about 1 minute. Case: 3 out of 3 Monitor Processes are Down =========================================== This is to test a scenario when 3 out of 3 Monitor processes are down. To bring down 3 Monitor processes (out of 3), we identify all 3 Monitor processes and kill them from the 3 monitor hosts (not pods). We monitored the status of Ceph Monitor pods and noted that the symptoms are similar to when 1 or 2 Monitor processes are killed: .. code-block:: console $ kubectl get pods -n ceph -o wide | grep ceph-mon NAME READY STATUS RESTARTS AGE ceph-mon-8tml7 0/1 Error 4 10d ceph-mon-kstf8 0/1 Error 4 10d ceph-mon-z4sl9 0/1 Error 7 10d .. code-block:: console $ kubectl get pods -n ceph -o wide | grep ceph-mon NAME READY STATUS RESTARTS AGE ceph-mon-8tml7 0/1 CrashLoopBackOff 4 10d ceph-mon-kstf8 0/1 Error 4 10d ceph-mon-z4sl9 0/1 CrashLoopBackOff 7 10d .. code-block:: console $ kubectl get pods -n ceph -o wide | grep ceph-mon NAME READY STATUS RESTARTS AGE ceph-mon-8tml7 1/1 Running 5 10d ceph-mon-kstf8 1/1 Running 5 10d ceph-mon-z4sl9 1/1 Running 8 10d The status of the pods (where the three Monitor processes are killed) changed as follows: ``Running`` -> ``Error`` -> ``CrashLoopBackOff`` -> ``Running`` and this recovery process takes about 1 minute. Case: Monitor database is destroyed =================================== We intentionlly destroy a Monitor database by removing ``/var/lib/openstack-helm/ceph/mon/mon/ceph-voyager3/store.db``. Symptom: -------- A Ceph Monitor running on voyager3 (whose Monitor database is destroyed) becomes out of quorum, and the mon-pod's status stays in ``Running`` -> ``Error`` -> ``CrashLoopBackOff`` while keeps restarting. .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN too few PGs per OSD (22 < min 30) mon voyager1 is low on available space 1/3 mons down, quorum voyager1,voyager2 services: mon: 3 daemons, quorum voyager1,voyager2, out of quorum: voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 24 up, 24 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2675 MB used, 44675 GB / 44678 GB avail pgs: 182 active+clean .. code-block:: console $ kubectl get pods -n ceph -o wide|grep ceph-mon ceph-mon-4gzzw 1/1 Running 0 6d 135.207.240.42 voyager2 ceph-mon-6bbs6 0/1 CrashLoopBackOff 5 6d 135.207.240.43 voyager3 ceph-mon-qgc7p 1/1 Running 0 6d 135.207.240.41 voyager1 The logs of the failed mon-pod shows the ceph-mon process cannot run as ``/var/lib/ceph/mon/ceph-voyager3/store.db`` does not exist. .. code-block:: console $ kubectl logs ceph-mon-6bbs6 -n ceph + ceph-mon --setuser ceph --setgroup ceph --cluster ceph -i voyager3 --inject-monmap /etc/ceph/monmap-ceph --keyring /etc/ceph/ceph.mon.keyring --mon-data /var/lib/ceph/mon/ceph-voyager3 2018-07-10 18:30:04.546200 7f4ca9ed4f00 -1 rocksdb: Invalid argument: /var/lib/ceph/mon/ceph-voyager3/store.db: does not exist (create_if_missing is false) 2018-07-10 18:30:04.546214 7f4ca9ed4f00 -1 error opening mon data directory at '/var/lib/ceph/mon/ceph-voyager3': (22) Invalid argument Recovery: --------- Remove the entire ceph-mon directory on voyager3, and then Ceph will automatically recreate the database by using the other ceph-mons' database. .. code-block:: console $ sudo rm -rf /var/lib/openstack-helm/ceph/mon/mon/ceph-voyager3 .. code-block:: console (mon-pod):/# ceph -s cluster: id: 9d4d8c61-cf87-4129-9cef-8fbf301210ad health: HEALTH_WARN too few PGs per OSD (22 < min 30) mon voyager1 is low on available space services: mon: 3 daemons, quorum voyager1,voyager2,voyager3 mgr: voyager1(active), standbys: voyager3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-65bb45dffc-cslr6=up:active}, 1 up:standby osd: 24 osds: 24 up, 24 in rgw: 2 daemons active data: pools: 18 pools, 182 pgs objects: 240 objects, 3359 bytes usage: 2675 MB used, 44675 GB / 44678 GB avail pgs: 182 active+clean ================================================ FILE: doc/source/testing/ceph-resiliency/namespace-deletion.rst ================================================ =============================== 3. Namespace deletion recovery =============================== This document captures steps to bring Ceph back up after deleting it's associated namespace. 3.1 Setup ========== .. note:: Follow OSH single node or multinode guide to bring up OSH envronment. 3.2 Setup the OSH environment and check ceph cluster health ============================================================= .. note:: Ensure a healthy ceph cluster is running. .. code-block:: console kubectl exec -n ceph ceph-mon-dtw6m -- ceph -s cluster: id: fbaf9ce8-5408-4fce-9bfe-bf7fb938474c health: HEALTH_OK services: mon: 5 daemons, quorum osh-1,osh-2,osh-5,osh-4,osh-3 mgr: osh-3(active), standbys: osh-4 mds: cephfs-1/1/1 up {0=mds-ceph-mds-77dc68f476-jb5th=up:active}, 1 up:standby osd: 15 osds: 15 up, 15 in data: pools: 18 pools, 182 pgs objects: 21 objects, 2246 bytes usage: 3025 MB used, 1496 GB / 1499 GB avail pgs: 182 active+clean - Ceph cluster is in HEALTH_OK state with 5 MONs and 15 OSDs. 3.3 Delete Ceph namespace ========================== .. note:: Removing the namespace will delete all pods and secrets associated to Ceph. !! DO NOT PROCEED WITH DELETING THE CEPH NAMESPACES ON A PRODUCTION ENVIRONMENT !! .. code-block:: console CEPH_NAMESPACE="ceph" MON_POD=$(kubectl get pods --namespace=${CEPH_NAMESPACE} \ --selector="application=ceph" --selector="component=mon" \ --no-headers | awk '{ print $1; exit }') kubectl exec --namespace=${CEPH_NAMESPACE} ${MON_POD} -- ceph status \ | awk '/id:/{print $2}' | tee /tmp/ceph-fs-uuid.txt .. code-block:: console kubectl delete namespace ${CEPH_NAMESPACE} .. code-block:: console kubectl get pods --namespace ${CEPH_NAMESPACE} -o wide No resources found. kubectl get secrets --namespace ${CEPH_NAMESPACE} No resources found. - Ceph namespace is currently deleted and all associated resources will be not found. 3.4 Reinstall Ceph charts ========================== .. note:: Instructions are specific to a multinode environment. For AIO environments follow the development guide for reinstalling Ceph. .. code-block:: console helm delete --purge ceph-openstack-config for chart in $(helm list --namespace ${CEPH_NAMESPACE} | awk '/ceph-/{print $1}'); do helm delete ${chart} --purge; done .. note:: It will be normal not to see all PODs come back online during a reinstall. Only the ceph-mon helm chart is required. .. code-block:: console cd /opt/openstack-helm/ ./tools/deployment/multinode/030-ceph.sh 3.5 Disable CephX authentication ================================= .. note:: Wait until MON pods are running before proceeding here. .. code-block:: console mkdir -p /tmp/ceph/ceph-templates /tmp/ceph/extracted-keys kubectl get -n ${CEPH_NAMESPACE} configmaps ceph-mon-etc -o=jsonpath='{.data.ceph\.conf}' > /tmp/ceph/ceph-mon.conf sed '/\[global\]/a auth_client_required = none' /tmp/ceph/ceph-mon.conf | \ sed '/\[global\]/a auth_service_required = none' | \ sed '/\[global\]/a auth_cluster_required = none' > /tmp/ceph/ceph-mon-noauth.conf kubectl --namespace ${CEPH_NAMESPACE} delete configmap ceph-mon-etc kubectl --namespace ${CEPH_NAMESPACE} create configmap ceph-mon-etc --from-file=ceph.conf=/tmp/ceph/ceph-mon-noauth.conf kubectl delete pod --namespace ${CEPH_NAMESPACE} -l application=ceph,component=mon .. note:: Wait until the MON pods are running before proceeding here. .. code-block:: console MON_POD=$(kubectl get pods --namespace=${CEPH_NAMESPACE} \ --selector="application=ceph" --selector="component=mon" \ --no-headers | awk '{ print $1; exit }') kubectl exec --namespace=${CEPH_NAMESPACE} ${MON_POD} -- ceph status - The Ceph cluster will not be healthy and in a HEALTH_WARN or HEALTH_ERR state. 3.6 Replace key secrets with ones extracted from a Ceph MON ============================================================ .. code-block:: console tee /tmp/ceph/ceph-templates/mon < ``Init:1/3`` -> ``Init:2/3`` -> ``Init:3/3`` -> ``Running``, and this process takes about 90 seconds. The reason is that Kubernetes automatically restarts OSD pods whenever they are deleted. ================================================ FILE: doc/source/testing/ceph-resiliency/validate-object-replication.rst ================================================ =========================================== Ceph - Test object replication across hosts =========================================== This document captures steps to validate object replcation is happening across hosts or not . Setup: ====== - Follow OSH single node or multinode guide to bring up OSH envronment. Step 1: Setup the OSH environment and check ceph cluster health ================================================================= .. note:: Make sure we have healthy ceph cluster running ``Ceph status:`` .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph -s cluster: id: 54d9af7e-da6d-4980-9075-96bb145db65c health: HEALTH_OK services: mon: 3 daemons, quorum mnode1,mnode2,mnode3 mgr: mnode2(active), standbys: mnode3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-6f66956547-c25cx=up:active}, 1 up:standby osd: 3 osds: 3 up, 3 in rgw: 2 daemons active data: pools: 19 pools, 101 pgs objects: 354 objects, 260 MB usage: 77807 MB used, 70106 MB / 144 GB avail pgs: 101 active+clean io: client: 48769 B/s wr, 0 op/s rd, 12 op/s wr - Ceph cluster is in HEALTH_OK state with 3 MONs and 3 OSDs. Step 2: Run validation script ============================= .. note:: Exec into ceph mon pod and execute the validation script by giving pool name as first argument, as shown below rbd is the pool name . .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ /tmp/checkObjectReplication.py rbd Test object got replicated on these osds: [1, 0, 2] Test object got replicated on these hosts: [u'mnode1', u'mnode2', u'mnode3'] Hosts hosting multiple copies of a placement groups are:[] - If there are any objects replicated on same host then we will see them in the last line of the script output ================================================ FILE: doc/source/testing/ceph-upgrade.rst ================================================ ============ Ceph Upgrade ============ This guide documents steps showing Ceph version upgrade. The main goal of this document is to demostrate Ceph chart update without downtime for OSH components. Test Scenario: ============== Upgrade Ceph component version from ``12.2.4`` to ``12.2.5`` without downtime to OSH components. Setup: ====== - 3 Node (VM based) env. - Followed OSH multinode guide steps to setup nodes and install K8s cluster - Followed OSH multinode guide steps upto Ceph install Plan: ===== 1) Install Ceph charts (12.2.4) by updating Docker images in overrides. 2) Install OSH components as per OSH multinode guide. 3) Upgrade Ceph charts to version 12.2.5 by updating docker images in overrides. Docker Images: ============== 1) Ceph Luminous point release images for Ceph components .. code-block:: console Ceph 12.2.4: ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64 Ceph 12.2.5: ceph/daemon:master-a8d20ed-luminous-ubuntu-16.04-x86_64 2) Ceph RBD provisioner docker images. .. code-block:: console quay.io/external_storage/rbd-provisioner:v0.1.0 quay.io/external_storage/rbd-provisioner:v0.1.1 3) Ceph Cephfs provisioner docker images. .. code-block:: console quay.io/external_storage/cephfs-provisioner:v0.1.1 quay.io/external_storage/cephfs-provisioner:v0.1.2 Steps: ====== .. note:: Follow all steps from OSH multinode guide with below changes. 1) Install Ceph charts (version 12.2.4) Update ceph install script ``./tools/deployment/multinode/030-ceph.sh`` to add ``images:`` section in overrides as shown below. .. note:: OSD count is set to 3 based on env setup. .. note:: Following is a partial part from script to show changes. .. code-block:: yaml tee /tmp/ceph.yaml << EOF ... network: public: ${CEPH_PUBLIC_NETWORK} cluster: ${CEPH_CLUSTER_NETWORK} images: tags: ceph_bootstrap: 'docker.io/ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64' ceph_config_helper: 'docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal' ceph_rbd_pool: 'docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal' ceph_mon_check: 'docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal' ceph_mon: 'docker.io/ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64' ceph_osd: 'docker.io/ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64' ceph_mds: 'docker.io/ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64' ceph_mgr: 'docker.io/ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64' ceph_rgw: 'docker.io/ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64' ceph_cephfs_provisioner: 'quay.io/external_storage/cephfs-provisioner:v0.1.1' ceph_rbd_provisioner: 'quay.io/external_storage/rbd-provisioner:v0.1.0' conf: ceph: global: fsid: ${CEPH_FS_ID} rgw_ks: enabled: true pool: crush: tunables: ${CRUSH_TUNABLES} target: # NOTE(portdirect): 5 nodes, with one osd per node osd: 5 pg_per_osd: 100 ... EOF .. note:: ``ceph_bootstrap``, ``ceph-config_helper`` and ``ceph_rbs_pool`` images are used for jobs. ``ceph_mon_check`` has one script that is stable so no need to upgrade. 2) Deploy and Validate Ceph .. code-block:: console + kubectl exec -n ceph ceph-mon-4c8xs -- ceph -s cluster: id: 39061799-d25e-4f3b-8c1a-a350e4c6d06c health: HEALTH_OK services: mon: 3 daemons, quorum mnode1,mnode2,mnode3 mgr: mnode2(active), standbys: mnode3 mds: cephfs-1/1/1 up {0=mds-ceph-mds-745576757f-4vdn4=up:active}, 1 up:standby osd: 3 osds: 3 up, 3 in rgw: 2 daemons active data: pools: 18 pools, 93 pgs objects: 208 objects, 3359 bytes usage: 72175 MB used, 75739 MB / 144 GB avail pgs: 93 active+clean 3) Check Ceph Pods .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl get pods -n ceph NAME READY STATUS RESTARTS AGE ceph-bootstrap-s4jkx 0/1 Completed 0 10m ceph-cephfs-client-key-generator-6bmzz 0/1 Completed 0 3m ceph-mds-745576757f-4vdn4 1/1 Running 0 6m ceph-mds-745576757f-bxdcs 1/1 Running 0 6m ceph-mds-keyring-generator-f5lxf 0/1 Completed 0 10m ceph-mgr-86bdc7c64b-7ptr4 1/1 Running 0 6m ceph-mgr-86bdc7c64b-xgplj 1/1 Running 0 6m ceph-mgr-keyring-generator-w7nxq 0/1 Completed 0 10m ceph-mon-4c8xs 1/1 Running 0 10m ceph-mon-check-d85994946-zzwb4 1/1 Running 0 10m ceph-mon-keyring-generator-jdgfw 0/1 Completed 0 10m ceph-mon-kht8d 1/1 Running 0 10m ceph-mon-mkpmm 1/1 Running 0 10m ceph-osd-default-83945928-7jz4s 1/1 Running 0 8m ceph-osd-default-83945928-bh82j 1/1 Running 0 8m ceph-osd-default-83945928-t9szk 1/1 Running 0 8m ceph-osd-keyring-generator-6rg65 0/1 Completed 0 10m ceph-rbd-pool-z8vlc 0/1 Completed 0 6m ceph-rbd-provisioner-84665cb84f-6s55r 1/1 Running 0 3m ceph-rbd-provisioner-84665cb84f-chwhd 1/1 Running 0 3m ceph-rgw-74559877-h56xs 1/1 Running 0 6m ceph-rgw-74559877-pfjr5 1/1 Running 0 6m ceph-rgw-keyring-generator-6rwct 0/1 Completed 0 10m ceph-storage-keys-generator-bgj2t 0/1 Completed 0 10m ingress-796d8cf8d6-nzrd2 1/1 Running 0 11m ingress-796d8cf8d6-qqvq9 1/1 Running 0 11m ingress-error-pages-54454dc79b-d5r5w 1/1 Running 0 11m ingress-error-pages-54454dc79b-gfpqv 1/1 Running 0 11m 4) Check version of each Ceph components. .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-4c8xs -- ceph -v ceph version 12.2.4 (52085d5249a80c5f5121a76d6288429f35e4e77b) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-osd-default-83945928-7jz4s -- ceph -v ceph version 12.2.4 (52085d5249a80c5f5121a76d6288429f35e4e77b) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mgr-86bdc7c64b-7ptr4 -- ceph -v ceph version 12.2.4 (52085d5249a80c5f5121a76d6288429f35e4e77b) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mds-745576757f-4vdn4 -- ceph -v ceph version 12.2.4 (52085d5249a80c5f5121a76d6288429f35e4e77b) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-rgw-74559877-h56xs -- ceph -v ceph version 12.2.4 (52085d5249a80c5f5121a76d6288429f35e4e77b) luminous (stable) 5) Check which images Provisionors and Mon-Check PODs are using .. note:: Showing partial output from kubectl describe command to show which image is Docker container is using .. code-block:: console ubuntu@mnode1:~$ kubectl describe pod -n ceph ceph-rbd-provisioner-84665cb84f-6s55r Containers: ceph-rbd-provisioner: Container ID: docker://383be3d653cecf4cbf0c3c7509774d39dce54102309f1f0bdb07cdc2441e5e47 Image: quay.io/external_storage/rbd-provisioner:v0.1.0 .. code-block:: console ubuntu@mnode1:~$ kubectl describe pod -n ceph ceph-mon-check-d85994946-zzwb4 Containers: ceph-mon: Container ID: docker://d5a3396f99704038ab8ef6bfe329013ed46472ebb8e26dddc140b621329f0f92 Image: docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal 6) Install Openstack charts Continue with OSH multinode guide to install other Openstack charts. 7) Capture Ceph pods statuses. .. code-block:: console NAME READY STATUS RESTARTS AGE ceph-bootstrap-s4jkx 0/1 Completed 0 2h ceph-cephfs-client-key-generator-6bmzz 0/1 Completed 0 2h ceph-mds-745576757f-4vdn4 1/1 Running 0 2h ceph-mds-745576757f-bxdcs 1/1 Running 0 2h ceph-mds-keyring-generator-f5lxf 0/1 Completed 0 2h ceph-mgr-86bdc7c64b-7ptr4 1/1 Running 0 2h ceph-mgr-86bdc7c64b-xgplj 1/1 Running 0 2h ceph-mgr-keyring-generator-w7nxq 0/1 Completed 0 2h ceph-mon-4c8xs 1/1 Running 0 2h ceph-mon-check-d85994946-zzwb4 1/1 Running 0 2h ceph-mon-keyring-generator-jdgfw 0/1 Completed 0 2h ceph-mon-kht8d 1/1 Running 0 2h ceph-mon-mkpmm 1/1 Running 0 2h ceph-osd-default-83945928-7jz4s 1/1 Running 0 2h ceph-osd-default-83945928-bh82j 1/1 Running 0 2h ceph-osd-default-83945928-t9szk 1/1 Running 0 2h ceph-osd-keyring-generator-6rg65 0/1 Completed 0 2h ceph-rbd-pool-z8vlc 0/1 Completed 0 2h ceph-rbd-provisioner-84665cb84f-6s55r 1/1 Running 0 2h ceph-rbd-provisioner-84665cb84f-chwhd 1/1 Running 0 2h ceph-rgw-74559877-h56xs 1/1 Running 0 2h ceph-rgw-74559877-pfjr5 1/1 Running 0 2h ceph-rgw-keyring-generator-6rwct 0/1 Completed 0 2h ceph-storage-keys-generator-bgj2t 0/1 Completed 0 2h ingress-796d8cf8d6-nzrd2 1/1 Running 0 2h ingress-796d8cf8d6-qqvq9 1/1 Running 0 2h ingress-error-pages-54454dc79b-d5r5w 1/1 Running 0 2h ingress-error-pages-54454dc79b-gfpqv 1/1 Running 0 2h 8) Capture Openstack pods statuses. .. code-block:: console NAME READY STATUS RESTARTS AGE cinder-api-67495cdffc-24fhs 1/1 Running 0 51m cinder-api-67495cdffc-kz5fn 1/1 Running 0 51m cinder-backup-65b7bd9b79-8n9pb 1/1 Running 0 51m cinder-scheduler-9ddbb7878-rbt4l 1/1 Running 0 51m cinder-volume-75bf4cc9bd-6298x 1/1 Running 0 51m glance-api-68f6df4d5d-q84hs 1/1 Running 0 1h glance-api-68f6df4d5d-qbfwb 1/1 Running 0 1h ingress-7b4bc84cdd-84dtj 1/1 Running 0 2h ingress-7b4bc84cdd-ws45r 1/1 Running 0 2h ingress-error-pages-586c7f86d6-dlpm2 1/1 Running 0 2h ingress-error-pages-586c7f86d6-w7cj2 1/1 Running 0 2h keystone-api-7d9759db58-dz6kt 1/1 Running 0 1h keystone-api-7d9759db58-pvsc2 1/1 Running 0 1h libvirt-f7ngc 1/1 Running 0 24m libvirt-gtjc7 1/1 Running 0 24m libvirt-qmwf5 1/1 Running 0 24m mariadb-ingress-84894687fd-m8fkr 1/1 Running 0 1h mariadb-ingress-error-pages-78fb865f84-c6th5 1/1 Running 0 1h mariadb-server-0 1/1 Running 0 1h memcached-memcached-5db74ddfd5-qjgvz 1/1 Running 0 1h neutron-dhcp-agent-default-9bpxc 1/1 Running 0 16m neutron-l3-agent-default-47n7k 1/1 Running 0 16m neutron-metadata-agent-default-hp46c 1/1 Running 0 16m neutron-ovs-agent-default-6sbtg 1/1 Running 0 16m neutron-ovs-agent-default-nl8fr 1/1 Running 0 16m neutron-ovs-agent-default-tvmc4 1/1 Running 0 16m neutron-server-775c765d9f-cx2gk 1/1 Running 0 16m neutron-server-775c765d9f-ll5ml 1/1 Running 0 16m nova-api-metadata-557c68cb46-8f8d5 1/1 Running 1 16m nova-api-osapi-7658bfd554-7fbtx 1/1 Running 0 16m nova-api-osapi-7658bfd554-v7qcr 1/1 Running 0 16m nova-compute-default-g2jbd 1/1 Running 0 16m nova-compute-default-ljcbc 1/1 Running 0 16m nova-compute-default-mr24c 1/1 Running 0 16m nova-conductor-64457cf995-lbv65 1/1 Running 0 16m nova-conductor-64457cf995-zts48 1/1 Running 0 16m nova-novncproxy-54467b9c66-vp49j 1/1 Running 0 16m nova-scheduler-59647c6d9f-vm78p 1/1 Running 0 16m openvswitch-db-cv47r 1/1 Running 0 41m openvswitch-db-dq7rc 1/1 Running 0 41m openvswitch-db-znp6l 1/1 Running 0 41m openvswitch-vswitchd-8p2j5 1/1 Running 0 41m openvswitch-vswitchd-v9rrp 1/1 Running 0 41m openvswitch-vswitchd-wlgkx 1/1 Running 0 41m rabbitmq-rabbitmq-0 1/1 Running 0 1h rabbitmq-rabbitmq-1 1/1 Running 0 1h rabbitmq-rabbitmq-2 1/1 Running 0 1h 9) Upgrade Ceph charts to update version Use Ceph override file ``ceph.yaml`` that was generated previously and update images section as below ``cp /tmp/ceph.yaml ceph-update.yaml`` Update, image section in new overrides ``ceph-update.yaml`` as shown below .. code-block:: yaml images: tags: ceph_bootstrap: 'docker.io/ceph/daemon:master-0351083-luminous-ubuntu-16.04-x86_64' ceph_config_helper: 'docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal' ceph_rbd_pool: 'docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal' ceph_mon_check: 'docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal' ceph_mon: 'docker.io/ceph/daemon:master-a8d20ed-luminous-ubuntu-16.04-x86_64' ceph_osd: 'docker.io/ceph/daemon:master-a8d20ed-luminous-ubuntu-16.04-x86_64' ceph_mds: 'docker.io/ceph/daemon:master-a8d20ed-luminous-ubuntu-16.04-x86_64' ceph_mgr: 'docker.io/ceph/daemon:master-a8d20ed-luminous-ubuntu-16.04-x86_64' ceph_rgw: 'docker.io/ceph/daemon:master-a8d20ed-luminous-ubuntu-16.04-x86_64' ceph_cephfs_provisioner: 'quay.io/external_storage/cephfs-provisioner:v0.1.2' ceph_rbd_provisioner: 'quay.io/external_storage/rbd-provisioner:v0.1.1' 10) Update Ceph Mon chart with new overrides ``helm upgrade ceph-mon ./ceph-mon --values=ceph-update.yaml`` ``series of console outputs:`` .. code-block:: console ceph-mon-4c8xs 0/1 Terminating 0 2h ceph-mon-check-d85994946-zzwb4 1/1 Running 0 2h ceph-mon-keyring-generator-jdgfw 0/1 Completed 0 2h ceph-mon-kht8d 1/1 Running 0 2h ceph-mon-mkpmm 1/1 Running 0 2h .. code-block:: console ceph-mon-7zxjs 1/1 Running 1 4m ceph-mon-84xt2 1/1 Running 1 2m ceph-mon-check-d85994946-zzwb4 1/1 Running 0 2h ceph-mon-fsrv4 1/1 Running 1 6m ceph-mon-keyring-generator-jdgfw 0/1 Completed 0 2h ``Results:`` Mon pods got updated one by one (rolling updates). Each Mon pod got respawn and was in 1/1 running state before next Mon pod got updated. Each Mon pod got restarted. Other ceph pods were not affected with this update. No interruption to OSH pods. 11) Update Ceph OSD chart with new overrides: ``helm upgrade ceph-osd ./ceph-osd --values=ceph-update.yaml`` ``series of console outputs:`` .. code-block:: console ceph-osd-default-83945928-7jz4s 0/1 Terminating 0 2h ceph-osd-default-83945928-bh82j 1/1 Running 0 2h ceph-osd-default-83945928-t9szk 1/1 Running 0 2h ceph-osd-keyring-generator-6rg65 0/1 Completed 0 2h .. code-block:: console ceph-osd-default-83945928-l84tl 1/1 Running 0 9m ceph-osd-default-83945928-twzmk 1/1 Running 0 6m ceph-osd-default-83945928-wxpmh 1/1 Running 0 11m ceph-osd-keyring-generator-6rg65 0/1 Completed 0 2h ``Results:`` Rolling updates (one pod at a time). Other ceph pods are running. No interruption to OSH pods. 12) Update Ceph Client chart with new overrides: ``helm upgrade ceph-client ./ceph-client --values=ceph-update.yaml`` .. code-block:: console ceph-mds-5fdcb5c64c-t9nmb 0/1 Init:0/2 0 11s ceph-mds-745576757f-4vdn4 1/1 Running 0 2h ceph-mds-745576757f-bxdcs 1/1 Running 0 2h ceph-mgr-86bdc7c64b-7ptr4 1/1 Terminating 0 2h ceph-mgr-86bdc7c64b-xgplj 0/1 Terminating 0 2h ceph-rgw-57c68b7cd5-vxcc5 0/1 Init:1/3 0 11s ceph-rgw-74559877-h56xs 1/1 Running 0 2h ceph-rgw-74559877-pfjr5 1/1 Running 0 2h .. code-block:: console ceph-mds-5fdcb5c64c-c52xq 1/1 Running 0 2m ceph-mds-5fdcb5c64c-t9nmb 1/1 Running 0 2m ceph-mgr-654f97cbfd-9kcvb 1/1 Running 0 1m ceph-mgr-654f97cbfd-gzb7k 1/1 Running 0 1m ceph-rgw-57c68b7cd5-vxcc5 1/1 Running 0 2m ceph-rgw-57c68b7cd5-zmdqb 1/1 Running 0 2m ``Results:`` Rolling updates (one pod at a time). Other ceph pods are running. No interruption to OSH pods. 13) Update Ceph Provisioners chart with new overrides: ``helm upgrade ceph-provisioners ./ceph-provisioners --values=ceph-update.yaml`` .. code-block:: console ceph-rbd-provisioner-84665cb84f-6s55r 0/1 Terminating 0 2h ceph-rbd-provisioner-84665cb84f-chwhd 0/1 Terminating 0 2h .. code-block:: console ceph-rbd-provisioner-5bfb577ffd-b7tkx 1/1 Running 0 1m ceph-rbd-provisioner-5bfb577ffd-m6gg6 1/1 Running 0 1m ``Results:`` All provisioner pods got terminated at once (same time). Other ceph pods are running. No interruption to OSH pods. 14) Capture final Ceph pod statuses: .. code-block:: console ceph-bootstrap-s4jkx 0/1 Completed 0 2h ceph-cephfs-client-key-generator-6bmzz 0/1 Completed 0 2h ceph-mds-5fdcb5c64c-c52xq 1/1 Running 0 8m ceph-mds-5fdcb5c64c-t9nmb 1/1 Running 0 8m ceph-mds-keyring-generator-f5lxf 0/1 Completed 0 2h ceph-mgr-654f97cbfd-9kcvb 1/1 Running 0 8m ceph-mgr-654f97cbfd-gzb7k 1/1 Running 0 8m ceph-mgr-keyring-generator-w7nxq 0/1 Completed 0 2h ceph-mon-7zxjs 1/1 Running 1 27m ceph-mon-84xt2 1/1 Running 1 24m ceph-mon-check-d85994946-zzwb4 1/1 Running 0 2h ceph-mon-fsrv4 1/1 Running 1 29m ceph-mon-keyring-generator-jdgfw 0/1 Completed 0 2h ceph-osd-default-83945928-l84tl 1/1 Running 0 19m ceph-osd-default-83945928-twzmk 1/1 Running 0 16m ceph-osd-default-83945928-wxpmh 1/1 Running 0 21m ceph-osd-keyring-generator-6rg65 0/1 Completed 0 2h ceph-rbd-pool-z8vlc 0/1 Completed 0 2h ceph-rbd-provisioner-5bfb577ffd-b7tkx 1/1 Running 0 2m ceph-rbd-provisioner-5bfb577ffd-m6gg6 1/1 Running 0 2m ceph-rgw-57c68b7cd5-vxcc5 1/1 Running 0 8m ceph-rgw-57c68b7cd5-zmdqb 1/1 Running 0 8m ceph-rgw-keyring-generator-6rwct 0/1 Completed 0 2h ceph-storage-keys-generator-bgj2t 0/1 Completed 0 2h ingress-796d8cf8d6-nzrd2 1/1 Running 0 2h ingress-796d8cf8d6-qqvq9 1/1 Running 0 2h ingress-error-pages-54454dc79b-d5r5w 1/1 Running 0 2h ingress-error-pages-54454dc79b-gfpqv 1/1 Running 0 2h 15) Capture final Openstack pod statuses: .. code-block:: console cinder-api-67495cdffc-24fhs 1/1 Running 0 1h cinder-api-67495cdffc-kz5fn 1/1 Running 0 1h cinder-backup-65b7bd9b79-8n9pb 1/1 Running 0 1h cinder-scheduler-9ddbb7878-rbt4l 1/1 Running 0 1h cinder-volume-75bf4cc9bd-6298x 1/1 Running 0 1h glance-api-68f6df4d5d-q84hs 1/1 Running 0 2h glance-api-68f6df4d5d-qbfwb 1/1 Running 0 2h ingress-7b4bc84cdd-84dtj 1/1 Running 0 2h ingress-7b4bc84cdd-ws45r 1/1 Running 0 2h ingress-error-pages-586c7f86d6-dlpm2 1/1 Running 0 2h ingress-error-pages-586c7f86d6-w7cj2 1/1 Running 0 2h keystone-api-7d9759db58-dz6kt 1/1 Running 0 2h keystone-api-7d9759db58-pvsc2 1/1 Running 0 2h libvirt-f7ngc 1/1 Running 0 1h libvirt-gtjc7 1/1 Running 0 1h libvirt-qmwf5 1/1 Running 0 1h mariadb-ingress-84894687fd-m8fkr 1/1 Running 0 2h mariadb-ingress-error-pages-78fb865f84-c6th5 1/1 Running 0 2h mariadb-server-0 1/1 Running 0 2h memcached-memcached-5db74ddfd5-qjgvz 1/1 Running 0 2h neutron-dhcp-agent-default-9bpxc 1/1 Running 0 52m neutron-l3-agent-default-47n7k 1/1 Running 0 52m neutron-metadata-agent-default-hp46c 1/1 Running 0 52m neutron-ovs-agent-default-6sbtg 1/1 Running 0 52m neutron-ovs-agent-default-nl8fr 1/1 Running 0 52m neutron-ovs-agent-default-tvmc4 1/1 Running 0 52m neutron-server-775c765d9f-cx2gk 1/1 Running 0 52m neutron-server-775c765d9f-ll5ml 1/1 Running 0 52m nova-api-metadata-557c68cb46-8f8d5 1/1 Running 1 52m nova-api-osapi-7658bfd554-7fbtx 1/1 Running 0 52m nova-api-osapi-7658bfd554-v7qcr 1/1 Running 0 52m nova-compute-default-g2jbd 1/1 Running 0 52m nova-compute-default-ljcbc 1/1 Running 0 52m nova-compute-default-mr24c 1/1 Running 0 52m nova-conductor-64457cf995-lbv65 1/1 Running 0 52m nova-conductor-64457cf995-zts48 1/1 Running 0 52m nova-novncproxy-54467b9c66-vp49j 1/1 Running 0 52m nova-scheduler-59647c6d9f-vm78p 1/1 Running 0 52m openvswitch-db-cv47r 1/1 Running 0 1h openvswitch-db-dq7rc 1/1 Running 0 1h openvswitch-db-znp6l 1/1 Running 0 1h openvswitch-vswitchd-8p2j5 1/1 Running 0 1h openvswitch-vswitchd-v9rrp 1/1 Running 0 1h openvswitch-vswitchd-wlgkx 1/1 Running 0 1h rabbitmq-rabbitmq-0 1/1 Running 0 2h rabbitmq-rabbitmq-1 1/1 Running 0 2h rabbitmq-rabbitmq-2 1/1 Running 0 2h 16) Confirm Ceph component's version. .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-fsrv4 -- ceph -v ceph version 12.2.5 (cad919881333ac92274171586c827e01f554a70a) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-osd-default-83945928-l84tl -- ceph -v ceph version 12.2.5 (cad919881333ac92274171586c827e01f554a70a) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-rgw-57c68b7cd5-vxcc5 -- ceph -v ceph version 12.2.5 (cad919881333ac92274171586c827e01f554a70a) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mgr-654f97cbfd-gzb7k -- ceph -v ceph version 12.2.5 (cad919881333ac92274171586c827e01f554a70a) luminous (stable) ubuntu@mnode1:/opt/openstack-helm$ kubectl exec -n ceph ceph-mds-5fdcb5c64c-c52xq -- ceph -v ceph version 12.2.5 (cad919881333ac92274171586c827e01f554a70a) luminous (stable) 17) Check which images Provisionors and Mon-Check PODs are using .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl describe pod -n ceph ceph-rbd-provisioner-5bfb577ffd-b7tkx Containers: ceph-rbd-provisioner: Container ID: docker://55b18b3400e8753f49f1343ee918a308ed1760816a1ce9797281dbfe3c5f9671 Image: quay.io/external_storage/rbd-provisioner:v0.1.1 .. code-block:: console ubuntu@mnode1:/opt/openstack-helm$ kubectl describe pod -n ceph ceph-mon-check-d85994946-zzwb4 Containers: ceph-mon: Container ID: docker://d5a3396f99704038ab8ef6bfe329013ed46472ebb8e26dddc140b621329f0f92 Image: docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_focal Conclusion: =========== Ceph can be upgraded without downtime for Openstack components in a multinode env. ================================================ FILE: doc/source/testing/helm-tests.rst ================================================ ========== Helm Tests ========== Every OpenStack-Helm chart should include any required Helm tests necessary to provide a sanity check for the OpenStack service. Information on using the Helm testing framework can be found in the Helm repository_. Currently, the Rally testing framework is used to provide these checks for the core services. The Keystone Helm test template can be used as a reference, and can be found here_. .. _repository: https://github.com/kubernetes/helm/blob/master/docs/chart_tests.md .. _here: https://github.com/openstack/openstack-helm/blob/master/keystone/templates/pod-rally-test.yaml Testing Expectations -------------------- Any templates for Helm tests submitted should follow the philosophies applied in the other templates. These include: use of overrides where appropriate, use of endpoint lookups and other common functionality in helm-toolkit, and mounting any required scripting templates via the configmap-bin template for the service chart. If Rally tests are not appropriate or adequate for a service chart, any additional tests should be documented appropriately and adhere to the same expectations. Running Tests ------------- Any Helm tests associated with a chart can be run by executing: :: helm test The output of the Helm tests can be seen by looking at the logs of the pod created by the Helm tests. These logs can be viewed with: :: kubectl logs -n Additional information on Helm tests for OpenStack-Helm and how to execute these tests locally via the scripts used in the gate can be found in the gates_ directory. .. _gates: https://github.com/openstack/openstack-helm/blob/master/tools/gate/ Adding Tests ------------ All tests should be added to the gates during development, and are required for any new service charts prior to merging. All Helm tests should be included as part of the deployment script. An example of this can be seen in this script_. .. _script: https://github.com/openstack/openstack-helm/blob/9d4f9862ca07f08005f9bdb4e6d58ad770fa4178/tools/deployment/multinode/080-keystone.sh#L32 ================================================ FILE: doc/source/testing/index.rst ================================================ ======= Testing ======= .. toctree:: :maxdepth: 2 helm-tests ceph-resiliency/index ceph-upgrade ceph-node-resiliency ================================================ FILE: doc/source/troubleshooting/ceph.rst ================================================ Backing up a PVC ^^^^^^^^^^^^^^^^ Backing up a PVC stored in Ceph, is fairly straigthforward, in this example we use the PVC ``mysql-data-mariadb-server-0`` as an example, but this will also apply to any other services using PVCs eg. RabbitMQ, Postgres. .. code-block:: shell # get all required details NS_NAME="openstack" PVC_NAME="mysql-data-mariadb-server-0" # you can check this by running kubectl get pvc -n ${NS_NAME} PV_NAME="$(kubectl get -n ${NS_NAME} pvc "${PVC_NAME}" --no-headers | awk '{ print $3 }')" RBD_NAME="$(kubectl get pv "${PV_NAME}" -o json | jq -r '.spec.rbd.image')" MON_POD=$(kubectl get pods \ --namespace=ceph \ --selector="application=ceph" \ --selector="component=mon" \ --no-headers | awk '{ print $1; exit }') # copy admin keyring from ceph mon to host node kubectl exec -it ${MON_POD} -n ceph -- cat /etc/ceph/ceph.client.admin.keyring > /etc/ceph/ceph.client.admin.keyring sudo kubectl get cm -n ceph ceph-etc -o json|jq -j .data[] > /etc/ceph/ceph.conf export CEPH_MON_NAME="ceph-mon-discovery.ceph.svc.cluster.local" # create snapshot and export to a file rbd snap create rbd/${RBD_NAME}@snap1 -m ${CEPH_MON_NAME} rbd snap list rbd/${RBD_NAME} -m ${CEPH_MON_NAME} # Export the snapshot and compress, make sure we have enough space on host to accommodate big files that we are working . # a. if we have enough space on host rbd export rbd/${RBD_NAME}@snap1 /backup/${RBD_NAME}.img -m ${CEPH_MON_NAME} cd /backup time xz -0vk --threads=0 /backup/${RBD_NAME}.img # b. if we have less space on host we can directly export and compress in single command rbd export rbd/${RBD_NAME}@snap1 -m ${CEPH_MON_NAME} - | xz -0v --threads=0 > /backup/${RBD_NAME}.img.xz Restoring is just as straightforward. Once the workload consuming the device has been stopped, and the raw RBD device removed the following will import the back up and create a device: .. code-block:: shell cd /backup unxz -k ${RBD_NAME}.img.xz rbd import /backup/${RBD_NAME}.img rbd/${RBD_NAME} -m ${CEPH_MON_NAME} Once this has been done the workload can be restarted. ================================================ FILE: doc/source/troubleshooting/database.rst ================================================ ==================== Database Deployments ==================== This guide is to help users debug any general storage issues when deploying Charts in this repository. Galera Cluster ============== To test MariaDB, do the following: :: admin@kubenode01:~/projects/openstack-helm$ kubectl exec mariadb-0 -it -n openstack -- mysql -h mariadb.openstack -uroot -ppassword -e 'show databases;' +--------------------+ | Database | +--------------------+ | information_schema | | keystone | | mysql | | performance_schema | +--------------------+ admin@kubenode01:~/projects/openstack-helm$ ================================================ FILE: doc/source/troubleshooting/index.rst ================================================ =============== Troubleshooting =============== Sometimes things go wrong. These guides will help you solve many common issues with the following: .. toctree:: :maxdepth: 2 database persistent-storage ubuntu-hwe-kernel ceph migrate-ceph-to-rook Getting help ============ Channels -------- * Join us on `IRC `_: #openstack-helm on oftc * Join us on `Slack `_ - #openstack-helm Bugs and Feature requests ------------------------- Please, refer to `Contribution guidelines <../contributor/contributing.html>`_. ================================================ FILE: doc/source/troubleshooting/migrate-ceph-to-rook.rst ================================================ Migrating Ceph to Rook ^^^^^^^^^^^^^^^^^^^^^^ It may be necessary or desired to migrate an existing `Ceph`_ cluster that was originally deployed using the Ceph charts in `openstack-helm`_ to be managed by the Rook operator moving forward. This operation is not a supported `Rook`_ feature, but it is possible to achieve. The procedure must completely stop and start all of the Ceph pods a few times during the migration process and is therefore disruptive to Ceph operations, but the result is a Ceph cluster deployed and managed by the Rook operator that maintains the same cluster FSID as the original with all OSD data preserved. The steps involved in migrating a legacy openstack-helm Ceph cluster to Rook are based on the Rook `Troubleshooting`_ documentation and are outlined below. #. Retrieve the cluster FSID, the name and IP address of an existing ceph-mon host that contains a healthy monitor store, and the numbers of existing ceph-mon and ceph-mgr pods from the existing Ceph cluster and save this information for later. #. Rename CephFS pools so that they use the naming convention expected by Rook. CephFS pools names are not customizable with Rook, so new metadata and data pools will be created for any filesystems deployed by Rook if the existing pools are not named as expected. Pools must be named "-metadata" and "-data" in order for Rook to use existing CephFS pools. #. Delete Ceph resources deployed via the openstack-helm charts, uninstall the charts, and remove Ceph node labels. #. Add the Rook Helm repository and deploy the Rook operator and a minimal Ceph cluster using the Rook Helm charts. The cluster will have a new FSID and will not include any OSDs because the OSD disks are all initialized in the old Ceph cluster and that will be recognized. #. Save the Ceph monitor keyring, host, and IP address, as well as the IP address of the new monitor itself, for later use. #. Stop the Rook operator by scaling the rook-ceph-operator deployment in the Rook operator namespace to zero replicas and destroy the newly-deployed Ceph cluster by deleting all deployments in the Rook Ceph cluster namespace except for rook-ceph-tools. #. Copy the store from an old monitor saved in the first step to the new monitor and update its keyring with the key saved from the new monitor. #. Edit the monmap in the copied monitor store using monmaptool to remove all of the old monitors from the monmap and add a single new one using the new monitor's IP address. #. Edit the rook-ceph-mon secret in the Rook Ceph cluster namespace and overwrite the base64-encoded FSID with the base64 encoding of the FSID from the old Ceph cluster. Make sure the encoding includes the FSID only, no whitespace or newline characters. #. Edit the rook-config-override configmap in the Rook Ceph cluster namespace and set auth_supported, auth_client_required, auth_service_required, and auth_cluster_required all to none in the global config section to disable authentication in the Ceph cluster. #. Scale the rook-ceph-operator deployment back to one replica to deploy the Ceph cluster again. This time, the cluster will have the old cluster's FSID and the OSD pods will come up in the new cluster with their data intact. #. Using 'ceph auth import' from the rook-ceph-tools pod, import the [client.admin] portion of the key saved from the new monitor from its initial Rook deployment. #. Edit the rook-config-override configmap again and remove the settings previously added to disable authentication. This will re-enable authentication when Ceph daemons are restarted. #. Scale the rook-ceph-operator deployment to zero replicas and delete the Ceph cluster deployments again to destroy the Ceph cluster one more time. #. When everything has terminated, immediately scale the rook-ceph-operator deployment back to one to deploy the Ceph cluster one final time. #. After the Ceph cluster has been deployed again and all of the daemons are running (with authentication enabled now), edit the deployed cephcluster resource in the Rook Ceph cluster namespace to set the mon and mgr counts to their original values saved in the first step. #. Now you have a Ceph cluster, deployed and managed by Rook, with the original FSID and all of its data intact, with the same number of monitors and managers that existed in the previous deployment. There is a rudimentary `script`_ provided that automates this process. It isn't meant to be a complete solution and isn't supported as such. It is simply an example that is known to work for some test implementations. The script makes use of environment variables to tell it which Rook release and Ceph release to deploy, in which Kubernetes namespaces to deploy the Rook operator and Ceph cluster, and paths to YAML files that contain the necessary definitions for the Rook operator and Rook Ceph cluster. All of these have default values and are not required to be set, but it will likely be necessary at least to define paths to the YAML files required to deploy the Rook operator and Ceph cluster. Please refer to the comments near the top of the script for more information about utilizing these environment variables. The Ceph cluster definition provided to Rook should match the existing Ceph cluster as closely as possible. Otherwise, the migration may not migrate Ceph cluster resources as expected. The migration of deployed Ceph resources is unique to each deployment, so sample definitions are not provided here. Migrations using this procedure and/or script are very delicate and will require a lot of testing prior to being implemented in production. This is a risky operation even with testing and should be performed very carefully. .. _Ceph: https://ceph.io .. _openstack-helm: https://opendev.org/openstack/openstack-helm .. _Rook: https://rook.io .. _Troubleshooting: https://rook.io/docs/rook/latest-release/Troubleshooting/disaster-recovery/#adopt-an-existing-rook-ceph-cluster-into-a-new-kubernetes-cluster .. _script: https://opendev.org/openstack/openstack-helm/src/tools/deployment/ceph/migrate-to-rook-ceph.sh ================================================ FILE: doc/source/troubleshooting/persistent-storage.rst ================================================ ================== Persistent Storage ================== This guide is to help users debug any general storage issues when deploying charts in this repository. Ceph ==== Ceph Deployment Status ~~~~~~~~~~~~~~~~~~~~~~ First, we want to validate that Ceph is working correctly. This can be done with the following Ceph command: :: admin@kubenode01:~$ MON_POD=$(kubectl get --no-headers pods -n=ceph -l="application=ceph,component=mon" | awk '{ print $1; exit }') admin@kubenode01:~$ kubectl exec -n ceph ${MON_POD} -- ceph -s cluster: id: 06a191c7-81bd-43f3-b5dd-3d6c6666af71 health: HEALTH_OK services: mon: 1 daemons, quorum att.port.direct mgr: att.port.direct(active) mds: cephfs-1/1/1 up {0=mds-ceph-mds-68c9c76d59-zqc55=up:active} osd: 1 osds: 1 up, 1 in rgw: 1 daemon active data: pools: 11 pools, 208 pgs objects: 352 objects, 464 MB usage: 62467 MB used, 112 GB / 173 GB avail pgs: 208 active+clean io: client: 253 B/s rd, 39502 B/s wr, 1 op/s rd, 8 op/s wr admin@kubenode01:~$ Use one of your Ceph Monitors to check the status of the cluster. A couple of things to note above; our health is ``HEALTH_OK``, we have 3 mons, we've established a quorum, and we can see that all of our OSDs are up and in the OSD map. PVC Preliminary Validation ~~~~~~~~~~~~~~~~~~~~~~~~~~ Before proceeding, it is important to ensure that you have deployed a client key in the namespace you wish to fulfill ``PersistentVolumeClaims``. To verify that your deployment namespace has a client key: :: admin@kubenode01: $ kubectl get secret -n openstack pvc-ceph-client-key NAME TYPE DATA AGE pvc-ceph-client-key kubernetes.io/rbd 1 8h Without this, your RBD-backed PVCs will never reach the ``Bound`` state. For more information, see how to `activate namespace for ceph <../install/multinode.html#activating-control-plane-namespace-for-ceph>`_. Note: This step is not relevant for PVCs within the same namespace Ceph was deployed. Ceph Validating PVC Operation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To validate persistent volume claim (PVC) creation, we've placed a test manifest `here `_. Deploy this manifest and verify the job completes successfully. Ceph Validating StorageClass ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Next we can look at the storage class, to make sure that it was created correctly: :: admin@kubenode01:~$ kubectl describe storageclass/general Name: general IsDefaultClass: No Annotations: Provisioner: ceph.com/rbd Parameters: adminId=admin,adminSecretName=pvc-ceph-conf-combined-storageclass,adminSecretNamespace=ceph,imageFeatures=layering,imageFormat=2,monitors=ceph-mon.ceph.svc.cluster.local:6789,pool=rbd,userId=admin,userSecretName=pvc-ceph-client-key ReclaimPolicy: Delete Events: admin@kubenode01:~$ The parameters are what we're looking for here. If we see parameters passed to the StorageClass correctly, we will see the ``ceph-mon.ceph.svc.cluster.local:6789`` hostname/port, things like ``userid``, and appropriate secrets used for volume claims. ================================================ FILE: doc/source/troubleshooting/ubuntu-hwe-kernel.rst ================================================ ================= Ubuntu HWE Kernel ================= To make use of CephFS in Ubuntu the HWE Kernel is required, until the issue described `here `_ is fixed. Installation ============ To deploy the HWE kernel, prior to deploying Kubernetes and OpenStack-Helm the following commands should be run on each node: .. code-block:: shell #!/bin/bash sudo -H apt-get update sudo -H apt-get install -y linux-generic-hwe-16.04 sudo -H reboot now ================================================ FILE: doc/source/upgrade/index.rst ================================================ Upgrade ======= Contents: .. toctree:: :maxdepth: 2 multiple-osd-releases ================================================ FILE: doc/source/upgrade/multiple-osd-releases.rst ================================================ ================================================================ Ceph - upgrade monolithic ceph-osd chart to multiple ceph charts ================================================================ This document captures the steps to move from installed monolithic ceph-osd chart to mutlitple ceph osd charts. this work will bring flexibility on site update as we will have more control on osds. Install single ceph-osd chart: ============================== step 1: Setup: ============== - Follow OSH single node or multinode guide to bring up OSH environment. .. note:: we will have single ceph osd chart and here are the override values for ceph disks osd: - data: type: block-logical location: /dev/vdb journal: type: block-logical location: /dev/vda1 - data: type: block-logical location: /dev/vdc journal: type: block-logical location: /dev/vda2 Step 2: Setup the OSH environment and check ceph cluster health ================================================================= .. note:: Make sure we have healthy ceph cluster running ``Ceph status:`` .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph -s cluster: id: 61a4e07f-8b4a-4c47-8fc7-a0e7345ac0b0 health: HEALTH_OK services: mon: 3 daemons, quorum k8smaster,k8sslave1,k8sslave2 mgr: k8sslave2(active), standbys: k8sslave1 mds: cephfs-1/1/1 up {0=mds-ceph-mds-5bf9fdfc6b-8nq4p=up:active}, 1 up:standby osd: 6 osds: 6 up, 6 in data: pools: 18 pools, 186 pgs objects: 377 objects, 1.2 GiB usage: 4.2 GiB used, 116 GiB / 120 GiB avail pgs: 186 active+clean - Ceph cluster is in HEALTH_OK state with 3 MONs and 6 OSDs. .. note:: Make sure we have single ceph osd chart only ``Helm status:`` .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ helm list | grep -i osd ceph-osd 1 Tue Mar 26 03:21:07 2019 DEPLOYED ceph-osd-vdb-0.1.0 - single osd chart deployed sucessfully. Upgrade to multiple ceph osd charts: ==================================== step 1: setup ============= - create multiple ceph osd charts as per requirement .. note:: copy ceph-osd folder to multiple ceph osd charts in openstack-helm folder .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ cp -r ceph-osd ceph-osd-vdb ubuntu@k8smaster:/opt/openstack-helm$ cp -r ceph-osd ceph-osd-vdc .. note:: make sure to correct chart name in each osd chart folder created above, need to update it in Charts.yaml . - create script to install multiple ceph osd charts .. note:: create new installation scripts to reflect new ceph osd charts. .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ cp ./tools/deployment/multinode/030-ceph.sh ./tools/deployment/multinode/030-ceph-osd-vdb.sh ubuntu@k8smaster:/opt/openstack-helm$ cp ./tools/deployment/multinode/030-ceph.sh ./tools/deployment/multinode/030-ceph-osd-vdc.sh .. note:: make sure to delete all other ceph charts from above scripts and have only new ceph osd chart. and also have correct overrides as shown below. example1: for CHART in ceph-osd-vdb; do helm upgrade --install ${CHART} ${OSH_PATH}/${CHART} \ --namespace=ceph \ --values=/tmp/ceph.yaml \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_CEPH_DEPLOY} osd: - data: type: block-logical location: /dev/vdb journal: type: block-logical location: /dev/vda1 example2: for CHART in ceph-osd-vdc; do helm upgrade --install ${CHART} ${OSH_PATH}/${CHART} \ --namespace=ceph \ --values=/tmp/ceph.yaml \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_CEPH_DEPLOY} osd: - data: type: block-logical location: /dev/vdc journal: type: block-logical location: /dev/vda2 step 2: Scale down applications using ceph pvc =============================================== .. note:: Scale down all the applications who are using pvcs so that we will not have any writes on ceph rbds . .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ sudo kubectl scale statefulsets -n openstack mariadb-server --replicas=0 ubuntu@k8smaster:/opt/openstack-helm$ sudo kubectl scale statefulsets -n openstack rabbitmq-rabbitmq --replicas=0 - just gave one example but we need to do it for all the applications using pvcs step 3: Setup ceph cluster flags to prevent rebalance ===================================================== .. note:: setup few flags on ceph cluster to prevent rebalance during this process. .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd set noout ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd set nobackfill ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd set norecover ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd set pause step 4: Delete single ceph-osd chart ==================================== .. note:: Delete the single ceph-osd chart. .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ helm delete --purge ceph-osd step 5: install new ceph-osd charts =================================== .. note:: Now we can install multiple ceph osd releases. .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ ./tools/deployment/multinode/030-ceph-osd-vdb.sh ubuntu@k8smaster:/opt/openstack-helm$ ./tools/deployment/multinode/030-ceph-osd-vdc.sh ubuntu@k8smaster:/opt/openstack-helm# helm list | grep -i osd ceph-osd-vdb 1 Tue Mar 26 03:21:07 2019 DEPLOYED ceph-osd-vdb-0.1.0 ceph-osd-vdc 1 Tue Mar 26 03:22:13 2019 DEPLOYED ceph-osd-vdc-0.1.0 - wait and check for healthy ceph cluster , if there are any issues need to sort out until we see healthy ceph cluster. step 6: Unset ceph cluster flags ================================ .. note:: unset the flags we set on the ceph cluster in above steps. .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd unset noout ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd unset nobackfill ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd unset norecover ubuntu@k8smaster:/opt/openstack-helm$ kubectl exec -n ceph ceph-mon-5qn68 -- ceph osd unset pause step 7: Scale up the applications using pvc =========================================== .. note:: Since ceph cluster is back to healthy status, now scale up the applications. .. code-block:: console ubuntu@k8smaster:/opt/openstack-helm$ sudo kubectl scale statefulsets -n openstack mariadb-server --replicas=3 ubuntu@k8smaster:/opt/openstack-helm$ sudo kubectl scale statefulsets -n openstack rabbitmq-rabbitmq --replicas=3 ================================================ FILE: elastic-apm-server/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v6.2.3 description: OpenStack-Helm Elastic APM Server name: elastic-apm-server version: 2025.2.0 home: https://www.elastic.co/guide/en/apm/get-started/current/index.html sources: - https://github.com/elastic/apm-server - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit/ version: ">= 0.1.0" ... ================================================ FILE: elastic-apm-server/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: elastic-apm-server-bin data: image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: elastic-apm-server/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: elastic-apm-server-etc data: apm-server.yml: | {{ toYaml .Values.conf.apm_server | indent 4 }} {{- end }} ================================================ FILE: elastic-apm-server/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $mounts_elastic_apm_server := .Values.pod.mounts.elastic_apm_server.elastic_apm_server }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "elastic-apm-server" }} {{ tuple $envAll "elastic-apm-server" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: [""] resources: - namespaces - pods verbs: - get - list - watch --- apiVersion: apps/v1 kind: Deployment metadata: name: elastic-apm-server labels: {{ tuple $envAll "elastic-apm-server" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "elastic-apm-server" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "elastic-apm-server" | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "elastic-apm-server" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "elastic-apm-server" "containerNames" (list "elastic-apm-server" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: replicas: {{ .Values.pod.replicas.elastic_apm_server }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.elastic_apm_server.node_selector_key }}: {{ .Values.labels.elastic_apm_server.node_selector_value }} initContainers: {{ tuple $envAll "elastic_apm_server" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: elastic-apm-server image: {{ .Values.images.tags.elastic_apm_server }} imagePullPolicy: {{ .Values.images.pull_policy }} securityContext: runAsUser: 0 {{ tuple $envAll $envAll.Values.pod.resources.elastic_apm_server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} args: - "-c" - "/usr/share/apm-server/apm-server.yml" - "-e" ports: - name: server containerPort: {{ tuple "elastic_apm_server" "internal" "server" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: ELASTICSEARCH_HOST value: {{ tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: ELASTICSEARCH_PORT value: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: APM_SERVER_HOST value: {{ tuple "elastic_apm_server" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: APM_SERVER_PORT value: {{ tuple "elastic_apm_server" "internal" "server" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: elastic-apm-server-etc mountPath: /usr/share/apm-server/apm-server.yml readOnly: true subPath: apm-server.yml - name: data mountPath: /usr/share/apm-server/data {{ if $mounts_elastic_apm_server.volumeMounts }}{{ toYaml $mounts_elastic_apm_server.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: elastic-apm-server-etc configMap: name: elastic-apm-server-etc defaultMode: 0444 - name: data hostPath: path: /var/lib/elastic-apm-server type: DirectoryOrCreate {{ if $mounts_elastic_apm_server.volumes }}{{ toYaml $mounts_elastic_apm_server.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: elastic-apm-server/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: elastic-apm-server/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "filebeat" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: elastic-apm-server/templates/secret-elasticsearch-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_elasticsearch }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.elasticsearch.user }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: ELASTICSEARCH_USERNAME: {{ .Values.endpoints.elasticsearch.auth.admin.username | b64enc }} ELASTICSEARCH_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: elastic-apm-server/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: elastic-apm-server/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "elastic_apm_server" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: server port: {{ tuple "elastic_apm_server" "internal" "server" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.elastic_apm_server.node_port.enabled }} nodePort: {{ .Values.network.elastic_apm_server.node_port.port }} {{ end }} selector: {{ tuple $envAll "elastic-apm-server" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.elastic_apm_server.node_port.enabled }} type: NodePort {{ end }} ================================================ FILE: elastic-apm-server/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for elastic-apm-server # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- release_group: null labels: elastic_apm_server: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: elastic_apm_server: docker.elastic.co/apm/apm-server:6.2.3 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync secrets: elasticsearch: user: elastic-apm-server-elasticsearch-user oci_image_registry: elastic-apm-server: elastic-apm-server-oci-image-registry dependencies: dynamic: common: local_image_registry: jobs: - elastic-apm-server-image-repo-sync services: - endpoint: node service: local_image_registry static: elastic_apm_server: services: null image_repo_sync: services: - endpoint: internal service: local_image_registry conf: apm_server: setup: dashboards: enabled: true host: ['${APM_SERVER_HOST}:${APM_SERVER_PORT}'] output: elasticsearch: hosts: ["${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}"] username: "${ELASTICSEARCH_USERNAME}" password: "${ELASTICSEARCH_PASSWORD}" endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false elastic-apm-server: username: elastic-apm-server password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null elasticsearch: namespace: null name: elasticsearch auth: admin: username: admin password: changeme hosts: data: elasticsearch-data default: elasticsearch-logging discovery: elasticsearch-discovery public: elasticsearch host_fqdn_override: default: null path: default: null scheme: default: http port: http: default: 80 elastic_apm_server: namespace: null name: apm-server hosts: default: apm-server host_fqdn_override: default: null path: default: null scheme: default: http port: server: default: 8200 pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate elastic_apm_server: enabled: true min_ready_seconds: 0 max_unavailable: 1 replicas: elastic_apm_server: 1 resources: elastic_apm_server: enabled: false limits: memory: '400Mi' cpu: '400m' requests: memory: '100Mi' cpu: '100m' mounts: elastic_apm_server: elastic_apm_server: network: elastic_apm_server: node_port: enabled: false port: 30200 manifests: configmap_bin: true configmap_etc: true deployment: true service: true job_image_repo_sync: true secret_elasticsearch: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: elastic-filebeat/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v7.1.0 description: OpenStack-Helm Elastic Filebeat name: elastic-filebeat version: 2025.2.0 home: https://www.elastic.co/products/beats/filebeat sources: - https://github.com/elastic/beats/tree/master/filebeat - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit/ version: ">= 0.1.0" ... ================================================ FILE: elastic-filebeat/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: filebeat-bin data: image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: elastic-filebeat/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: filebeat-etc data: filebeat.yml: | {{ toYaml .Values.conf.filebeat | indent 4 }} system.yml: | {{ toYaml .Values.conf.modules.system | indent 4 }} {{- end }} ================================================ FILE: elastic-filebeat/templates/daemonset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $mounts_filebeat := .Values.pod.mounts.filebeat.filebeat }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "filebeat" }} {{ tuple $envAll "filebeat" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - namespaces - nodes - pods - services - endpoints - replicationcontrollers - limitranges verbs: - get - list - watch - apiGroups: - apps resources: - statefulsets - daemonsets - deployments - replicasets verbs: - get - list - watch --- apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat spec: selector: matchLabels: {{ tuple $envAll "filebeat" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "filebeat" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "filebeat" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "filebeat" "containerNames" (list "filebeat" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.filebeat.enabled }} {{ tuple $envAll "filebeat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ else }} nodeSelector: {{ .Values.labels.filebeat.node_selector_key }}: {{ .Values.labels.filebeat.node_selector_value | quote }} {{ end }} initContainers: {{ tuple $envAll "filebeat" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: filebeat image: {{ .Values.images.tags.filebeat }} imagePullPolicy: {{ .Values.images.pull_policy }} securityContext: runAsUser: 0 {{ tuple $envAll $envAll.Values.pod.resources.filebeat | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} args: - "-e" ports: - name: filebeat containerPort: {{ tuple "filebeat" "internal" "service" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: ELASTICSEARCH_HOST value: {{ tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: ELASTICSEARCH_PORT value: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: KIBANA_HOST value: {{ tuple "kibana" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: KIBANA_PORT value: {{ tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: data mountPath: /usr/share/filebeat/data - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: filebeat-etc mountPath: /usr/share/filebeat/filebeat.yml readOnly: true subPath: filebeat.yml - name: filebeat-etc mountPath: /usr/share/filebeat/modules.d/system.yml subPath: system.yml readOnly: true {{ if $mounts_filebeat.volumeMounts }}{{ toYaml $mounts_filebeat.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers - name: filebeat-etc configMap: name: filebeat-etc defaultMode: 0444 - name: data hostPath: path: /var/lib/filebeat type: DirectoryOrCreate {{ if $mounts_filebeat.volumes }}{{ toYaml $mounts_filebeat.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: elastic-filebeat/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: elastic-filebeat/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "filebeat" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: elastic-filebeat/templates/secret-elasticsearch-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_elasticsearch }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.elasticsearch.user }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: ELASTICSEARCH_USERNAME: {{ .Values.endpoints.elasticsearch.auth.admin.username | b64enc }} ELASTICSEARCH_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: elastic-filebeat/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: elastic-filebeat/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for filebeat # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- release_group: null labels: filebeat: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: filebeat: docker.elastic.co/beats/filebeat-oss:7.1.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync secrets: elasticsearch: user: filebeat-elasticsearch-user oci_image_registry: elastic-filebeat: elastic-filebeat-oci-image-registry-key dependencies: dynamic: common: local_image_registry: jobs: - filebeat-image-repo-sync services: - endpoint: node service: local_image_registry static: filebeat: services: - endpoint: internal service: kibana image_repo_sync: services: - endpoint: internal service: local_image_registry conf: filebeat: setup: dashboards: enabled: true index: "filebeat-*" retry: enabled: true interval: 5 kibana: host: "${KIBANA_HOST}:${KIBANA_PORT}" username: "${ELASTICSEARCH_USERNAME}" password: "${ELASTICSEARCH_PASSWORD}" path: logs: /var/log/ output: elasticsearch: hosts: ["${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/"] username: "${ELASTICSEARCH_USERNAME}" password: "${ELASTICSEARCH_PASSWORD}" filebeat: config: modules: path: ${path.config}/modules.d/*.yml reload: enabled: true autodiscover: providers: - type: kubernetes templates: - condition: equals: kubernetes.namespace: kube-system config: - type: docker containers.ids: - "${data.kubernetes.container.id}" exclude_lines: ["^\\s+[\\-`('.|_]"] - type: kubernetes templates: - condition: equals: kubernetes.namespace: ceph config: - type: docker containers.ids: - "${data.kubernetes.container.id}" exclude_lines: ["^\\s+[\\-`('.|_]"] - type: kubernetes templates: - condition: equals: kubernetes.namespace: openstack config: - type: docker containers.ids: - "${data.kubernetes.container.id}" exclude_lines: ["^\\s+[\\-`('.|_]"] - type: kubernetes templates: - condition: equals: kubernetes.namespace: osh-infra config: - type: docker containers.ids: - "${data.kubernetes.container.id}" exclude_lines: ["^\\s+[\\-`('.|_]"] processors: - add_kubernetes_metadata: in_cluster: true - drop_event: when: equals: kubernetes: container: name: "filebeat" modules: system: - module: system syslog: enabled: true var.paths: ["/var/log/syslog*"] fields: host: name: "${NODE_NAME}" auth: enabled: true var.paths: ["/var/log/auth.log"] fields: host: name: "${NODE_NAME}" endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false elastic-filebeat: username: elastic-filebeat password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null elasticsearch: namespace: null name: elasticsearch auth: admin: username: admin password: changeme hosts: data: elasticsearch-data default: elasticsearch-logging discovery: elasticsearch-discovery public: elasticsearch host_fqdn_override: default: null path: default: null scheme: default: http port: http: default: 80 kibana: name: kibana namespace: null hosts: default: kibana-dash public: kibana host_fqdn_override: default: null path: default: null scheme: default: http port: kibana: default: 5601 http: default: 80 filebeat: namespace: null name: filebeat hosts: default: filebeat host_fqdn_override: default: null path: default: null scheme: default: http port: service: default: 5066 pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate filebeat: enabled: true min_ready_seconds: 0 max_unavailable: 1 resources: filebeat: enabled: false limits: memory: '400Mi' cpu: '400m' requests: memory: '100Mi' cpu: '100m' tolerations: filebeat: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/control-plane operator: Exists - key: node-role.kubernetes.io/node operator: Exists mounts: filebeat: filebeat: manifests: configmap_bin: true configmap_etc: true daemonset: true job_image_repo_sync: true secret_elasticsearch: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: elastic-metricbeat/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v7.1.0 description: OpenStack-Helm Elastic Metricbeat name: elastic-metricbeat version: 2025.2.0 home: https://www.elastic.co/products/beats/metricbeat sources: - https://github.com/elastic/beats/tree/master/metricbeat - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit/ version: ">= 0.1.0" ... ================================================ FILE: elastic-metricbeat/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: metricbeat-etc data: metricbeat.yml: | {{ toYaml .Values.conf.metricbeat | indent 4 }} rabbitmq.yml: | {{ toYaml .Values.conf.modules.rabbitmq | indent 4 }} mysql.yml: | {{ toYaml .Values.conf.modules.mysql | indent 4 }} system.yml: | {{ toYaml .Values.conf.modules.system | indent 4 }} daemonset_kubernetes.yml: | {{ toYaml .Values.conf.modules.daemonset_kubernetes | indent 4 }} deployment_kubernetes.yml: | {{ toYaml .Values.conf.modules.deployment_kubernetes | indent 4 }} {{- end }} ================================================ FILE: elastic-metricbeat/templates/daemonset-node-metrics.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $mounts_metricbeat := .Values.pod.mounts.metricbeat.metricbeat }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "metricbeat" }} {{ tuple $envAll "metricbeat" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - namespaces - nodes - pods - services - endpoints - replicationcontrollers - limitranges - events verbs: - get - list - watch - apiGroups: - apps resources: - statefulsets - daemonsets - deployments - replicasets verbs: - get - list - watch --- apiVersion: apps/v1 kind: DaemonSet metadata: name: metricbeat-node-modules spec: selector: matchLabels: {{ tuple $envAll "metricbeat" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "metricbeat" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "metricbeat" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: hostNetwork: true dnsPolicy: {{ .Values.pod.dns_policy }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.metricbeat.enabled }} {{ tuple $envAll "metricbeat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ else }} nodeSelector: {{ .Values.labels.metricbeat.node_selector_key }}: {{ .Values.labels.metricbeat.node_selector_value | quote }} {{ end }} initContainers: {{ tuple $envAll "metricbeat" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: metricbeat securityContext: privileged: true runAsUser: 0 image: {{ .Values.images.tags.metricbeat }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.metricbeat | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} args: - "-c" - "/usr/share/metricbeat/metricbeat.yml" - "-e" - "-system.hostfs=/hostfs" env: - name: ELASTICSEARCH_HOST value: {{ tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: ELASTICSEARCH_PORT value: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: KIBANA_HOST value: {{ tuple "kibana" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: KIBANA_PORT value: {{ tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace volumeMounts: - name: pod-tmp mountPath: /tmp - name: metricbeat-etc mountPath: /usr/share/metricbeat/metricbeat.yml subPath: metricbeat.yml readOnly: true - name: metricbeat-etc mountPath: /usr/share/metricbeat/modules.d/system.yml subPath: system.yml readOnly: true - name: metricbeat-etc mountPath: /usr/share/metricbeat/modules.d/kubernetes.yml subPath: daemonset_kubernetes.yml readOnly: true - name: dockersock mountPath: /var/run/docker.sock - name: proc mountPath: /hostfs/proc readOnly: true - name: cgroup mountPath: /hostfs/sys/fs/cgroup readOnly: true {{ if $mounts_metricbeat.volumeMounts }}{{ toYaml $mounts_metricbeat.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: proc hostPath: path: /proc - name: cgroup hostPath: path: /sys/fs/cgroup - name: dockersock hostPath: path: /var/run/docker.sock - name: metricbeat-etc configMap: defaultMode: 0444 name: metricbeat-etc - name: data emptyDir: {} {{ if $mounts_metricbeat.volumes }}{{ toYaml $mounts_metricbeat.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: elastic-metricbeat/templates/deployment-modules.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "metricbeat-deployments" }} {{ tuple $envAll "metricbeat" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - namespaces - nodes - pods - services - endpoints - replicationcontrollers - limitranges - events verbs: - get - list - watch - apiGroups: - apps resources: - statefulsets - daemonsets - deployments - replicasets verbs: - get - list - watch --- apiVersion: apps/v1 kind: Deployment metadata: name: metricbeat-deployment-modules labels: {{ tuple $envAll "metricbeat" "deployment-modules" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.metricbeat }} selector: matchLabels: {{ tuple $envAll "metricbeat" "deployment-modules" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "metricbeat" "deployment-modules" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "metricbeat" "deployment-modules" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.metricbeat.node_selector_key }}: {{ .Values.labels.metricbeat.node_selector_value }} initContainers: {{ tuple $envAll "metricbeat" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: metricbeat securityContext: runAsUser: 0 {{ tuple $envAll "metricbeat" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.metricbeat | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} args: - "-c" - "/usr/share/metricbeat/metricbeat.yml" - "-e" env: - name: ELASTICSEARCH_HOST value: {{ tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: ELASTICSEARCH_PORT value: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: KUBE_STATE_METRICS_HOST value: {{ tuple "kube_state_metrics" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: KUBE_STATE_METRICS_PORT value: {{ tuple "kube_state_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: KIBANA_HOST value: {{ tuple "kibana" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: KIBANA_PORT value: {{ tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace volumeMounts: - name: pod-tmp mountPath: /tmp - name: metricbeat-etc mountPath: /usr/share/metricbeat/metricbeat.yml subPath: metricbeat.yml readOnly: true - name: metricbeat-etc mountPath: /usr/share/metricbeat/modules.d/kubernetes.yml subPath: deployment_kubernetes.yml readOnly: true - name: metricbeat-etc mountPath: /usr/share/metricbeat/modules.d/mysql.yml subPath: mysql.yml readOnly: true - name: metricbeat-etc mountPath: /usr/share/metricbeat/modules.d/rabbitmq.yml subPath: rabbitmq.yml readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: metricbeat-etc configMap: name: metricbeat-etc defaultMode: 0444 {{- end }} ================================================ FILE: elastic-metricbeat/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: elastic-metricbeat/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "metricbeat" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: elastic-metricbeat/templates/secret-elasticsearch-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_elasticsearch }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.elasticsearch.user }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: ELASTICSEARCH_USERNAME: {{ .Values.endpoints.elasticsearch.auth.admin.username | b64enc }} ELASTICSEARCH_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: elastic-metricbeat/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: elastic-metricbeat/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for metricbeat # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- release_group: null labels: metricbeat: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: metricbeat: docker.elastic.co/beats/metricbeat-oss:7.1.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync secrets: elasticsearch: user: metricbeat-elasticsearch-user oci_image_registry: elastic-metricbeat: elastic-metricbeat-oci-image-registry-key dependencies: dynamic: common: local_image_registry: jobs: - metricbeat-image-repo-sync services: - endpoint: node service: local_image_registry static: metricbeat: services: - endpoint: internal service: kibana image_repo_sync: services: - endpoint: internal service: local_image_registry conf: metricbeat: setup: dashboards: enabled: true index: metricbeat-* retry: enabled: true interval: 5 kibana: host: "${KIBANA_HOST}:${KIBANA_PORT}" username: "${ELASTICSEARCH_USERNAME}" password: "${ELASTICSEARCH_PASSWORD}" metricbeat: config: modules: path: ${path.config}/modules.d/*.yml reload: enabled: true output: elasticsearch: hosts: ['${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}'] username: ${ELASTICSEARCH_USERNAME} password: ${ELASTICSEARCH_PASSWORD} modules: docker: - module: docker metricsets: - "container" - "cpu" - "diskio" - "healthcheck" - "info" - "image" - "memory" - "network" hosts: ["unix:///var/run/docker.sock"] period: 10s enabled: true system: - module: system period: 10s metricsets: - cpu - load - memory - network - process - process_summary - core - diskio - socket - filesystem - fsstat processes: ['.*'] cpu.metrics: ["percentages"] core.metrics: ["percentages"] process.include_top_n: by_cpu: 5 by_memory: 5 enabled: true daemonset_kubernetes: - module: kubernetes metricsets: - node - system - pod - container - volume period: 10s hosts: ["localhost:10255"] add_metadata: true in_cluster: true enabled: true deployment_kubernetes: - module: kubernetes metricsets: - state_node - state_deployment - state_replicaset - state_pod - state_container - event period: 10s hosts: ['${KUBE_STATE_METRICS_HOST}:${KUBE_STATE_METRICS_PORT}'] add_metadata: true in_cluster: true enabled: true endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false elastic-metricbeat: username: elastic-metricbeat password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null kube_state_metrics: namespace: null hosts: default: kube-state-metrics host_fqdn_override: default: null path: default: null scheme: default: 'http' port: metrics: default: 8080 elasticsearch: namespace: null name: elasticsearch auth: admin: username: admin password: changeme hosts: data: elasticsearch-data default: elasticsearch-logging discovery: elasticsearch-discovery public: elasticsearch host_fqdn_override: default: null path: default: null scheme: default: http port: http: default: 80 kibana: name: kibana namespace: osh-infra hosts: default: kibana-dash public: kibana host_fqdn_override: default: null path: default: null scheme: default: http port: kibana: default: 5601 http: default: 80 pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate metricbeat: enabled: true min_ready_seconds: 0 max_unavailable: 1 dns_policy: "ClusterFirstWithHostNet" replicas: metricbeat: 1 resources: metricbeat: enabled: false limits: memory: '400Mi' cpu: '400m' requests: memory: '100Mi' cpu: '100m' tolerations: metricbeat: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/control-plane operator: Exists - key: node-role.kubernetes.io/node operator: Exists mounts: metricbeat: metricbeat: manifests: configmap_bin: true configmap_etc: true daemonset: true deployment: true job_image_repo_sync: true secret_elasticsearch: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: elastic-packetbeat/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v7.1.0 description: OpenStack-Helm Elastic Packetbeat name: elastic-packetbeat version: 2025.2.0 home: https://www.elastic.co/products/beats/packetbeat sources: - https://github.com/elastic/beats/tree/master/packetbeat - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit/ version: ">= 0.1.0" ... ================================================ FILE: elastic-packetbeat/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: packetbeat-etc data: packetbeat.yml: | {{ toYaml .Values.conf.packetbeat | indent 4 }} {{- end }} ================================================ FILE: elastic-packetbeat/templates/daemonset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $mounts_packetbeat := .Values.pod.mounts.packetbeat.packetbeat }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "packetbeat" }} {{ tuple $envAll "packetbeat" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - namespaces - nodes - pods - services - endpoints - replicationcontrollers - limitranges verbs: - get - list - watch - apiGroups: - apps resources: - statefulsets - daemonsets - deployments - replicasets verbs: - get - list - watch --- apiVersion: apps/v1 kind: DaemonSet metadata: name: packetbeat spec: selector: matchLabels: {{ tuple $envAll "packetbeat" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "packetbeat" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "packetbeat" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: securityContext: runAsUser: 0 hostNetwork: true dnsPolicy: {{ .Values.pod.dns_policy }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "packetbeat" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: packetbeat image: {{ .Values.images.tags.packetbeat }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.packetbeat | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: privileged: true capabilities: add: - NET_ADMIN args: - "-c" - "/usr/share/packetbeat/packetbeat.yml" - "-e" env: - name: ELASTICSEARCH_HOST value: {{ tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: ELASTICSEARCH_PORT value: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: KIBANA_HOST value: {{ tuple "kibana" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | quote }} - name: KIBANA_PORT value: {{ tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: pod-tmp mountPath: /tmp - name: packetbeat-etc mountPath: /usr/share/packetbeat/packetbeat.yml subPath: packetbeat.yml readOnly: true {{ if $mounts_packetbeat.volumeMounts }}{{ toYaml $mounts_packetbeat.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: packetbeat-etc configMap: defaultMode: 0444 name: packetbeat-etc {{ if $mounts_packetbeat.volumes }}{{ toYaml $mounts_packetbeat.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: elastic-packetbeat/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: elastic-packetbeat/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "metricbeat" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: elastic-packetbeat/templates/secret-elasticsearch-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_elasticsearch }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.elasticsearch.user }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: ELASTICSEARCH_USERNAME: {{ .Values.endpoints.elasticsearch.auth.admin.username | b64enc }} ELASTICSEARCH_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: elastic-packetbeat/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: elastic-packetbeat/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for packetbeat # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- release_group: null labels: packetbeat: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: packetbeat: docker.elastic.co/beats/packetbeat-oss:7.1.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync secrets: elasticsearch: user: packetbeat-elasticsearch-user oci_image_registry: elastic-packetbeat: elastic-packetbeat-oci-image-registry-key dependencies: dynamic: common: local_image_registry: jobs: - packetbeat-image-repo-sync services: - endpoint: node service: local_image_registry static: packetbeat: services: null image_repo_sync: services: - endpoint: internal service: local_image_registry conf: packetbeat: setup: kibana: host: "${KIBANA_HOST}:${KIBANA_PORT}" username: "${ELASTICSEARCH_USERNAME}" password: "${ELASTICSEARCH_PASSWORD}" dashboards: enabled: true index: "packetbeat-*" retry: enabled: true interval: 5 packetbeat: flows: timeout: 30s period: 10s interfaces: device: any protocols: - type: dhcpv4 ports: [67, 68] - type: dns ports: [53] include_authorities: true include_additionals: true - type: http ports: [80, 8080, 8081, 5000, 8002, 6666, 3000, 5601, 9100, 9090, 44134] output: elasticsearch: hosts: ['${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}'] username: ${ELASTICSEARCH_USERNAME} password: ${ELASTICSEARCH_PASSWORD} endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false elastic-packetbeat: username: elastic-packetbeat password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null elasticsearch: name: elasticsearch namespace: null auth: admin: username: admin password: changeme hosts: data: elasticsearch-data default: elasticsearch-logging discovery: elasticsearch-discovery public: elasticsearch host_fqdn_override: default: null path: default: null scheme: default: http port: http: default: 80 kibana: name: kibana namespace: null hosts: default: kibana-dash public: kibana host_fqdn_override: default: null path: default: null scheme: default: http port: kibana: default: 5601 http: default: 80 pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate packetbeat: enabled: true min_ready_seconds: 0 max_unavailable: 1 dns_policy: "ClusterFirstWithHostNet" replicas: packetbeat: 1 resources: packetbeat: enabled: false limits: memory: '400Mi' cpu: '400m' requests: memory: '100Mi' cpu: '100m' mounts: packetbeat: packetbeat: manifests: configmap_bin: true configmap_etc: true daemonset: true job_image_repo_sync: true secret_elasticsearch: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: elasticsearch/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v8.19.9 description: OpenStack-Helm ElasticSearch name: elasticsearch version: 2025.2.0 home: https://www.elastic.co/ sources: - https://github.com/elastic/elasticsearch - https://opendev.org/openstack/openstack-helm-addons maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: elasticsearch/templates/bin/_apache.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ev COMMAND="${@:-start}" function start () { if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/httpd/apache2/envvars fi # Apache gets grumpy about PID files pre-existing rm -f /etc/httpd/logs/httpd.pid if [ -f /usr/local/apache2/conf/.htpasswd ]; then htpasswd -b /usr/local/apache2/conf/.htpasswd "$ELASTICSEARCH_USERNAME" "$ELASTICSEARCH_PASSWORD" else htpasswd -cb /usr/local/apache2/conf/.htpasswd "$ELASTICSEARCH_USERNAME" "$ELASTICSEARCH_PASSWORD" fi if [ ! -z $ELASTICSEARCH_LOGGING_USERNAME ]; then htpasswd -b /usr/local/apache2/conf/.htpasswd "$ELASTICSEARCH_LOGGING_USERNAME" "$ELASTICSEARCH_LOGGING_PASSWORD" fi #Launch Apache on Foreground exec httpd -DFOREGROUND } function stop () { apachectl -k graceful-stop } $COMMAND ================================================ FILE: elasticsearch/templates/bin/_ceph-admin-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat < /etc/ceph/ceph.client.admin.keyring [client.admin] {{- if .Values.conf.ceph.admin_keyring }} key = {{ .Values.conf.ceph.admin_keyring }} {{- else }} key = $(cat /tmp/client-keyring) {{- end }} EOF exit 0 ================================================ FILE: elasticsearch/templates/bin/_create_s3_buckets.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} #!/bin/bash set -e function check_rgw_s3_bucket () { echo "Checking if bucket exists" s3cmd $CONNECTION_ARGS $USER_AUTH_ARGS ls s3://$S3_BUCKET } function create_rgw_s3_bucket () { echo "Creating bucket" s3cmd $CONNECTION_ARGS $S3_BUCKET_OPTS $USER_AUTH_ARGS mb s3://$S3_BUCKET } function modify_bucket_acl () { echo "Updating bucket ACL" s3cmd $CONNECTION_ARGS $USER_AUTH_ARGS setacl s3://$S3_BUCKET --acl-grant=read:$S3_USERNAME --acl-grant=write:$S3_USERNAME } {{- $envAll := . }} {{- range $bucket := .Values.storage.s3.buckets }} S3_BUCKET={{ $bucket.name }} S3_BUCKET_OPTS={{ $bucket.options | default nil | include "helm-toolkit.utils.joinListWithSpace" }} S3_SSL_OPT={{ $bucket.ssl_connection_option | default "" }} S3_USERNAME=${{ printf "%s_S3_USERNAME" ( $bucket.client | replace "-" "_" | upper) }} S3_ACCESS_KEY=${{ printf "%s_S3_ACCESS_KEY" ( $bucket.client | replace "-" "_" | upper) }} S3_SECRET_KEY=${{ printf "%s_S3_SECRET_KEY" ( $bucket.client | replace "-" "_" | upper) }} {{- with $client := index $envAll.Values.storage.s3.clients $bucket.client }} RGW_HOST={{ $client.settings.endpoint | default (tuple "ceph_object_store" "internal" "api" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup") }} RGW_PROTO={{ $client.settings.protocol | default (tuple "ceph_object_store" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") }} {{- end }} CONNECTION_ARGS="--host=$RGW_HOST --host-bucket=$RGW_HOST" if [ "$RGW_PROTO" = "http" ]; then CONNECTION_ARGS+=" --no-ssl" else CONNECTION_ARGS+=" $S3_SSL_OPT" fi USER_AUTH_ARGS=" --access_key=$S3_ACCESS_KEY --secret_key=$S3_SECRET_KEY" echo "Creating Bucket $S3_BUCKET at $RGW_HOST" check_rgw_s3_bucket || ( create_rgw_s3_bucket && modify_bucket_acl ) {{- end }} ================================================ FILE: elasticsearch/templates/bin/_create_s3_users.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} #!/bin/bash set -e function create_s3_user () { echo "Creating s3 user and key pair" radosgw-admin user create \ --uid=${S3_USERNAME} \ --display-name=${S3_USERNAME} \ --key-type=s3 \ --access-key ${S3_ACCESS_KEY} \ --secret-key ${S3_SECRET_KEY} } function update_s3_user () { # Retrieve old access keys, if they exist old_access_keys=$(radosgw-admin user info --uid=${S3_USERNAME} \ | jq -r '.keys[].access_key' || true) if [[ ! -z ${old_access_keys} ]]; then for access_key in $old_access_keys; do # If current access key is the same as the key supplied, do nothing. if [ "$access_key" == "${S3_ACCESS_KEY}" ]; then echo "Current user and key pair exists." continue else # If keys differ, remove previous key radosgw-admin key rm --uid=${S3_USERNAME} --key-type=s3 --access-key=$access_key fi done fi # Perform one more additional check to account for scenarios where multiple # key pairs existed previously, but one existing key was the supplied key current_access_key=$(radosgw-admin user info --uid=${S3_USERNAME} \ | jq -r '.keys[].access_key' || true) # If the supplied key does not exist, modify the user if [[ -z ${current_access_key} ]]; then # Modify user with new access and secret keys echo "Updating existing user's key pair" radosgw-admin user modify \ --uid=${S3_USERNAME}\ --access-key ${S3_ACCESS_KEY} \ --secret-key ${S3_SECRET_KEY} fi } {{- range $client, $config := .Values.storage.s3.clients -}} {{- if $config.create_user | default false }} S3_USERNAME=${{ printf "%s_S3_USERNAME" ($client | replace "-" "_" | upper) }} S3_ACCESS_KEY=${{ printf "%s_S3_ACCESS_KEY" ($client | replace "-" "_" | upper) }} S3_SECRET_KEY=${{ printf "%s_S3_SECRET_KEY" ($client | replace "-" "_" | upper) }} user_exists=$(radosgw-admin user info --uid=${S3_USERNAME} || true) if [[ -z ${user_exists} ]]; then echo "Creating $S3_USERNAME" create_s3_user > /dev/null 2>&1 else echo "Updating $S3_USERNAME" update_s3_user > /dev/null 2>&1 fi {{- end }} {{- end }} ================================================ FILE: elasticsearch/templates/bin/_create_template.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e NUM_ERRORS=0 {{ range $name, $object := .Values.conf.api_objects }} {{ if not (empty $object) }} echo "creating {{$name}}" error=$(curl ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ -X{{ $object.method | default "PUT" | upper }} \ "${ELASTICSEARCH_ENDPOINT}/{{ $object.endpoint }}" \ -H 'Content-Type: application/json' -d '{{ $object.body | toJson }}' | jq -r '.error') if [ $error == "null" ]; then echo "Object {{$name}} was created." else echo "Error when creating object {{$name}}: $(echo $error | jq -r)" NUM_ERRORS=$(($NUM_ERRORS+1)) fi {{ end }} {{ end }} if [ $NUM_ERRORS -gt 0 ]; then exit 1 else echo "leaving normally" fi ================================================ FILE: elasticsearch/templates/bin/_curator.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec {{ .Values.conf.curator.executable }} --config /etc/config/config.yml /etc/config/action_file.yml ================================================ FILE: elasticsearch/templates/bin/_elasticsearch.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} set -e COMMAND="${@:-start}" function initiate_keystore () { elasticsearch-keystore create {{- if .Values.conf.elasticsearch.snapshots.enabled }} {{- range $client, $settings := .Values.storage.s3.clients -}} {{- $access_key := printf "%s_S3_ACCESS_KEY" ( $client | replace "-" "_" | upper) }} {{- $secret_key := printf "%s_S3_SECRET_KEY" ( $client | replace "-" "_" | upper) }} echo ${{$access_key}} | elasticsearch-keystore add -xf s3.client.{{ $client }}.access_key echo ${{$secret_key}} | elasticsearch-keystore add -xf s3.client.{{ $client }}.secret_key {{- end }} {{- end }} {{- if .Values.manifests.certificates }} {{- $alias := .Values.secrets.tls.elasticsearch.elasticsearch.internal }} JAVA_KEYTOOL_PATH=/usr/share/elasticsearch/jdk/bin/keytool TRUSTSTORE_PATH=/usr/share/elasticsearch/config/elasticsearch-java-truststore ${JAVA_KEYTOOL_PATH} -importcert -alias {{$alias}} -keystore ${TRUSTSTORE_PATH} -trustcacerts -noprompt -file ${JAVA_KEYSTORE_CERT_PATH} -storepass ${ELASTICSEARCH_PASSWORD} ${JAVA_KEYTOOL_PATH} -storepasswd -keystore ${TRUSTSTORE_PATH} -new ${ELASTICSEARCH_PASSWORD} -storepass ${ELASTICSEARCH_PASSWORD} {{- end }} } function start () { initiate_keystore exec /usr/local/bin/docker-entrypoint.sh elasticsearch } function stop () { kill -TERM 1 } function wait_to_join() { # delay 5 seconds before the first check sleep 5 joined=$(curl -s ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" "${ELASTICSEARCH_ENDPOINT}/_cat/nodes" | grep -w $NODE_NAME || true ) i=0 while [ -z "$joined" ]; do sleep 5 joined=$(curl -s ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" "${ELASTICSEARCH_ENDPOINT}/_cat/nodes" | grep -w $NODE_NAME || true ) i=$((i+1)) # Waiting for up to 60 minutes if [ $i -gt 720 ]; then break fi done } function allocate_data_node () { echo "Node ${NODE_NAME} has started. Waiting to rejoin the cluster." wait_to_join echo "Re-enabling Replica Shard Allocation" curl -s ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" -XPUT -H 'Content-Type: application/json' \ "${ELASTICSEARCH_ENDPOINT}/_cluster/settings" -d "{ \"persistent\": { \"cluster.routing.allocation.enable\": null } }" } function start_master_node () { initiate_keystore if [ ! -f {{ $envAll.Values.conf.elasticsearch.config.path.data }}/cluster-bootstrap.txt ]; then {{ if empty $envAll.Values.conf.elasticsearch.config.cluster.initial_master_nodes -}} {{- $_ := set $envAll.Values "__eligible_masters" ( list ) }} {{- range $podInt := until ( atoi (print $envAll.Values.pod.replicas.master ) ) }} {{- $eligibleMaster := printf "elasticsearch-master-%s" (toString $podInt) }} {{- $__eligible_masters := append $envAll.Values.__eligible_masters $eligibleMaster }} {{- $_ := set $envAll.Values "__eligible_masters" $__eligible_masters }} {{- end -}} {{- $masters := include "helm-toolkit.utils.joinListWithComma" $envAll.Values.__eligible_masters -}} echo {{$masters}} >> {{ $envAll.Values.conf.elasticsearch.config.path.data }}/cluster-bootstrap.txt exec /usr/local/bin/docker-entrypoint.sh elasticsearch -Ecluster.initial_master_nodes={{$masters}} {{- end }} else exec /usr/local/bin/docker-entrypoint.sh elasticsearch fi } function start_data_node () { initiate_keystore allocate_data_node & /usr/local/bin/docker-entrypoint.sh elasticsearch & function drain_data_node () { # Implement the Rolling Restart Protocol Described Here: # https://www.elastic.co/guide/en/elasticsearch/reference/7.x/restart-cluster.html#restart-cluster-rolling echo "Disabling Replica Shard Allocation" curl -s ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" -XPUT -H 'Content-Type: application/json' \ "${ELASTICSEARCH_ENDPOINT}/_cluster/settings" -d "{ \"persistent\": { \"cluster.routing.allocation.enable\": \"primaries\" } }" # If version < 7.6 use _flush/synced; otherwise use _flush # https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-synced-flush-api.html#indices-synced-flush-api version=$(curl -s ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" "${ELASTICSEARCH_ENDPOINT}/" | jq -r .version.number) if [[ $version =~ "7.1" ]]; then action="_flush/synced" else action="_flush" fi curl -s ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" -XPOST "${ELASTICSEARCH_ENDPOINT}/$action" # TODO: Check the response of synced flush operations to make sure there are no failures. # Synced flush operations that fail due to pending indexing operations are listed in the response body, # although the request itself still returns a 200 OK status. If there are failures, reissue the request. # (The only side effect of not doing so is slower start up times. See flush documentation linked above) echo "Node ${NODE_NAME} is ready to shutdown" echo "Killing Elasticsearch background processes" jobs -p | xargs -t -r kill -TERM wait # remove the trap handler trap - TERM EXIT HUP INT echo "Node ${NODE_NAME} shutdown is complete" exit 0 } trap drain_data_node TERM EXIT HUP INT wait } $COMMAND ================================================ FILE: elasticsearch/templates/bin/_helm-tests.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex function create_test_index () { index_result=$(curl ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ -XPUT "${ELASTICSEARCH_ENDPOINT}/test_index?pretty" -H 'Content-Type: application/json' -d' { "settings" : { "index" : { "number_of_shards" : 3, "number_of_replicas" : 2 } } } ' | grep -o '"acknowledged" *: *true') if [ -n "$index_result" ]; then echo "PASS: Test index created!"; else echo "FAIL: Test index not created!"; exit 1; fi } function remove_test_index () { echo "Deleting index created for service testing" curl ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ -XDELETE "${ELASTICSEARCH_ENDPOINT}/test_index" } remove_test_index || true create_test_index remove_test_index ================================================ FILE: elasticsearch/templates/bin/_verify-repositories.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{ $envAll := . }} set -ex function verify_snapshot_repository() { curl ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ -XPOST "${ELASTICSEARCH_ENDPOINT}/_snapshot/$1/_verify" } repositories=$(curl ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ "${ELASTICSEARCH_ENDPOINT}/_snapshot" | jq -r 'keys | @sh') repositories=$(echo $repositories | sed "s/'//g") # Strip single quotes from jq output for repository in $repositories; do error=$(verify_snapshot_repository $repository | jq -r '.error' ) if [ $error == "null" ]; then echo "$repository is verified." else echo "Error for $repository: $(echo $error | jq -r)" exit 1; fi done ================================================ FILE: elasticsearch/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "elasticsearch" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: elasticsearch/templates/configmap-bin-curator.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin_curator }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: elastic-curator-bin data: curator.sh: | {{ tuple "bin/_curator.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: elasticsearch/templates/configmap-bin-elasticsearch.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin_elasticsearch }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: elasticsearch-bin data: apache.sh: | {{ tuple "bin/_apache.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} elasticsearch.sh: | {{ tuple "bin/_elasticsearch.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} helm-tests.sh: | {{ tuple "bin/_helm-tests.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ceph-admin-keyring.sh: | {{ tuple "bin/_ceph-admin-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} create-s3-bucket.sh: | {{ tuple "bin/_create_s3_buckets.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} create-s3-user.sh: | {{ tuple "bin/_create_s3_users.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} create_template.sh: | {{ tuple "bin/_create_template.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} verify-repositories.sh: | {{ tuple "bin/_verify-repositories.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: elasticsearch/templates/configmap-etc-curator.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc_curator }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: elastic-curator-etc type: Opaque data: action_file.yml: {{ toYaml .Values.conf.curator.action_file | b64enc }} config.yml: {{ toYaml .Values.conf.curator.config | b64enc }} {{- end }} ================================================ FILE: elasticsearch/templates/configmap-etc-elasticsearch.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc_elasticsearch }} {{- $envAll := . }} {{- if .Values.conf.elasticsearch.snapshots.enabled }} {{- range $client, $config := $envAll.Values.storage.s3.clients }} {{- $settings := $config.settings }} {{- $endpoint := $settings.endpoint | default (tuple "ceph_object_store" "internal" "api" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup") }} {{- $_ := set $settings "endpoint" $endpoint }} {{- $protocol := $settings.protocol | default (tuple "ceph_object_store" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") }} {{- $_ := set $settings "protocol" $protocol }} {{- $_:= set $envAll.Values.conf.elasticsearch.config.s3.client $client $settings }} {{- end -}} {{- end -}} {{- if empty .Values.conf.elasticsearch.config.discovery.seed_hosts -}} {{- $discovery_svc := tuple "elasticsearch" "discovery" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" -}} {{- $_:= set .Values.conf.elasticsearch.config.discovery "seed_hosts" $discovery_svc -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: elasticsearch-etc type: Opaque data: elasticsearch.yml: {{ toYaml .Values.conf.elasticsearch.config | b64enc }} # NOTE(portdirect): this must be last, to work round helm ~2.7 bug. {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.httpd "key" "httpd.conf" "format" "Secret") | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.log4j2 "key" "log4j2.properties" "format" "Secret") | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.jvm_options "key" "jvm.options" "format" "Secret") | indent 2 }} {{- end }} ================================================ FILE: elasticsearch/templates/cron-job-curator.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_curator }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $serviceAccountName := "elastic-curator" }} {{ tuple $envAll "curator" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: elastic-curator annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "elasticsearch" "curator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: schedule: {{ .Values.jobs.curator.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.curator.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.curator.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "elasticsearch" "curator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "elasticsearch" "curator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ dict "envAll" $envAll "application" "curator" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure initContainers: {{ tuple $envAll "curator" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: curator {{ tuple $envAll "curator" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.curator | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "curator" "container" "curator" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - /tmp/curator.sh env: - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: ELASTICSEARCH_URL valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_URL volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-curator mountPath: /etc/config - name: elastic-curator-bin mountPath: /tmp/curator.sh subPath: curator.sh readOnly: true - name: elastic-curator-etc mountPath: /etc/config/config.yml subPath: config.yml readOnly: true - name: elastic-curator-etc mountPath: /etc/config/action_file.yml subPath: action_file.yml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/etc/elasticsearch/certs" "certs" tuple "ca.crt" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-curator emptyDir: {} - name: elastic-curator-bin configMap: name: elastic-curator-bin defaultMode: 0555 - name: elastic-curator-etc secret: secretName: elastic-curator-etc defaultMode: 0444 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- end }} ================================================ FILE: elasticsearch/templates/cron-job-verify-repositories.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and (.Values.manifests.cron_verify_repositories) (.Values.conf.elasticsearch.snapshots.enabled) }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $serviceAccountName := "verify-repositories" }} {{ tuple $envAll "verify_repositories" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: elasticsearch-verify-repositories annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "elasticsearch" "verify-repositories" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: schedule: {{ .Values.jobs.verify_repositories.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.verify_repositories.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.verify_repositories.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "elasticsearch" "verify-repositories" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "elasticsearch-verify-repositories" "containerNames" (list "elasticsearch-verify-repositories" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "elasticsearch" "verify-repositories" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ dict "envAll" $envAll "application" "verify_repositories" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure initContainers: {{ tuple $envAll "verify_repositories" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: elasticsearch-verify-repositories {{ tuple $envAll "snapshot_repository" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.snapshot_repository | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "verify_repositories" "container" "elasticsearch_verify_repositories" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - /tmp/verify-repositories.sh env: - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: ELASTICSEARCH_ENDPOINT value: {{ printf "%s://%s" (tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") (tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") }} {{- if .Values.manifests.certificates }} - name: CACERT_OPTION value: "--cacert /etc/elasticsearch/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-bin mountPath: /tmp/verify-repositories.sh subPath: verify-repositories.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/etc/elasticsearch/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} volumes: - name: pod-tmp emptyDir: {} - name: elasticsearch-bin configMap: name: elasticsearch-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- end }} ================================================ FILE: elasticsearch/templates/deployment-client.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "readinessProbeTemplate" }} {{- $probePort := tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $probeUser := .Values.endpoints.elasticsearch.auth.admin.username }} {{- $probePass := .Values.endpoints.elasticsearch.auth.admin.password }} {{- $authHeader := printf "%s:%s" $probeUser $probePass | b64enc }} httpGet: path: /_cluster/health scheme: {{ tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} port: {{ $probePort }} httpHeaders: - name: Authorization value: Basic {{ $authHeader }} {{- end }} {{- define "livenessProbeTemplate" }} {{- $probePort := tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} tcpSocket: port: {{ $probePort }} {{- end }} {{- if .Values.manifests.deployment_client }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $s3UserSecret := .Values.secrets.rgw.elasticsearch }} {{- $mounts_elasticsearch := .Values.pod.mounts.elasticsearch.elasticsearch }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "elasticsearch-client" }} {{ tuple $envAll "elasticsearch_client" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: elasticsearch-client annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "elasticsearch" "client" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.client }} selector: matchLabels: {{ tuple $envAll "elasticsearch" "client" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "elasticsearch" "client" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "elasticsearch-client" "containerNames" (list "elasticsearch-client" "init" "memory-map-increase" "apache-proxy") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "client" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "elasticsearch" "client" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.client.node_selector_key }}: {{ .Values.labels.client.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.client.timeout | default "600" }} initContainers: {{ tuple $envAll "elasticsearch_client" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: memory-map-increase {{ tuple $envAll "memory_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.client | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "client" "container" "memory_map_increase" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - sysctl - -w - vm.max_map_count={{ .Values.conf.init.max_map_count }} containers: - name: apache-proxy {{ tuple $envAll "apache_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.apache_proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "client" "container" "apache_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/apache.sh - start ports: - name: {{ tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} containerPort: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 env: - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: ELASTICSEARCH_LOGGING_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_LOGGING_USERNAME - name: ELASTICSEARCH_LOGGING_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_LOGGING_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-bin mountPath: /tmp/apache.sh subPath: apache.sh readOnly: true - name: elasticsearch-etc mountPath: /usr/local/apache2/conf/httpd.conf subPath: httpd.conf readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/etc/elasticsearch/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} - name: elasticsearch-client {{ tuple $envAll "elasticsearch" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.client | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "client" "container" "elasticsearch_client" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/elasticsearch.sh - start lifecycle: preStop: exec: command: - /tmp/elasticsearch.sh - stop ports: - name: transport containerPort: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" . "component" "elasticsearch" "container" "elasticsearch-client" "type" "liveness" "probeTemplate" (include "livenessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "elasticsearch" "container" "elasticsearch-client" "type" "readiness" "probeTemplate" (include "readinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: NODE_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: node.roles value: "[ingest]" - name: HTTP_ENABLE value: "true" - name: DISCOVERY_SERVICE value: {{ tuple "elasticsearch" "discovery" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: ES_JAVA_OPTS value: "{{ .Values.conf.elasticsearch.env.java_opts.client }}" {{- if .Values.manifests.certificates }} - name: JAVA_KEYSTORE_CERT_PATH value: "/usr/share/elasticsearch/config/ca.crt" - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD {{- end }} {{- if .Values.conf.elasticsearch.snapshots.enabled }} {{- if .Values.manifests.object_bucket_claim }} {{- include "helm-toolkit.snippets.rgw_s3_bucket_user_env_vars_rook" . | indent 12 }} {{- else }} {{- include "helm-toolkit.snippets.rgw_s3_user_env_vars" . | indent 12 }} {{- end }} {{- end }} {{- if .Values.pod.env.client }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.client | indent 12 }} {{- end }} {{- if .Values.pod.env.secrets }} {{ tuple $envAll .Values.pod.env.secrets | include "helm-toolkit.utils.to_k8s_env_secret_vars" | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-logs mountPath: {{ .Values.conf.elasticsearch.config.path.logs }} - name: elasticsearch-bin mountPath: /tmp/elasticsearch.sh subPath: elasticsearch.sh readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/log4j2.properties subPath: log4j2.properties readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/jvm.options subPath: jvm.options readOnly: true - name: storage mountPath: {{ .Values.conf.elasticsearch.config.path.data }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/usr/share/elasticsearch/config" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_elasticsearch.volumeMounts }}{{ toYaml $mounts_elasticsearch.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: elasticsearch-logs emptyDir: {} - name: elasticsearch-bin configMap: name: elasticsearch-bin defaultMode: 0555 - name: elasticsearch-etc secret: secretName: elasticsearch-etc defaultMode: 0444 - name: storage emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_elasticsearch.volumes }}{{ toYaml $mounts_elasticsearch.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: elasticsearch/templates/deployment-gateway.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.network.remote_clustering.enabled }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $s3UserSecret := .Values.secrets.rgw.elasticsearch }} {{- $mounts_elasticsearch := .Values.pod.mounts.elasticsearch.elasticsearch }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "elasticsearch-remote-gateway" }} {{ tuple $envAll "elasticsearch_gateway" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: elasticsearch-gateway annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "elasticsearch" "gateway" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} replicas: {{ .Values.pod.replicas.gateway }} selector: matchLabels: {{ tuple $envAll "elasticsearch" "gateway" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "elasticsearch" "gateway" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "elasticsearch-gateway" "containerNames" (list "elasticsearch-remote-gateway") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "gateway" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "elasticsearch" "gateway" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.gateway.node_selector_key }}: {{ .Values.labels.gateway.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.client.timeout | default "600" }} initContainers: {{ tuple $envAll "elasticsearch" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: memory-map-increase {{ tuple $envAll "memory_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.client | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "gateway" "container" "memory_map_increase" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - sysctl - -w - vm.max_map_count={{ .Values.conf.init.max_map_count }} containers: - name: elasticsearch-gateway {{ tuple $envAll "elasticsearch" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.gateway | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "gateway" "container" "elasticsearch_gateway" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/elasticsearch.sh - start lifecycle: preStop: exec: command: - /tmp/elasticsearch.sh - stop ports: - name: transport containerPort: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} livenessProbe: tcpSocket: port: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 readinessProbe: tcpSocket: port: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: NODE_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: node.roles value: "[ingest]" - name: HTTP_ENABLE value: "false" - name: DISCOVERY_SERVICE value: {{ tuple "elasticsearch" "discovery" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: ES_JAVA_OPTS value: "{{ .Values.conf.elasticsearch.env.java_opts.client }}" {{- if .Values.manifests.certificates }} - name: JAVA_KEYSTORE_CERT_PATH value: "/usr/share/elasticsearch/config/ca.crt" - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD {{- end }} {{- if .Values.conf.elasticsearch.snapshots.enabled }} {{- if .Values.manifests.object_bucket_claim }} {{- include "helm-toolkit.snippets.rgw_s3_bucket_user_env_vars_rook" . | indent 12 }} {{- else }} {{- include "helm-toolkit.snippets.rgw_s3_user_env_vars" . | indent 12 }} {{- end }} {{- end }} {{- if .Values.pod.env.gateway }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.gateway | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-logs mountPath: {{ .Values.conf.elasticsearch.config.path.logs }} - name: elasticsearch-bin mountPath: /tmp/elasticsearch.sh subPath: elasticsearch.sh readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/log4j2.properties subPath: log4j2.properties readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/jvm.options subPath: jvm.options readOnly: true - name: storage mountPath: {{ .Values.conf.elasticsearch.config.path.data }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/usr/share/elasticsearch/config" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_elasticsearch.volumeMounts }}{{ toYaml $mounts_elasticsearch.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: elasticsearch-logs emptyDir: {} - name: elasticsearch-bin configMap: name: elasticsearch-bin defaultMode: 0555 - name: elasticsearch-etc secret: secretName: elasticsearch-etc defaultMode: 0444 - name: storage emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_elasticsearch.volumes }}{{ toYaml $mounts_elasticsearch.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: elasticsearch/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: elasticsearch/templates/ingress-elasticsearch.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.elasticsearch.ingress.public }} {{- $envAll := . -}} {{- $port := tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "elasticsearch" "backendServiceType" "elasticsearch" "backendPort" $port -}} {{- $secretName := $envAll.Values.secrets.tls.elasticsearch.elasticsearch.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.elasticsearch.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: elasticsearch/templates/job-elasticsearch-template.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_elasticsearch_templates }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $mounts_elasticsearch_templates := .Values.pod.mounts.elasticsearch_templates.elasticsearch_templates }} {{- $mounts_elasticsearch_templates_init := .Values.pod.mounts.elasticsearch_templates.init_container }} {{- $serviceAccountName := "create-elasticsearch-templates" }} {{ tuple $envAll "elasticsearch_templates" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: create-elasticsearch-templates labels: {{ tuple $envAll "elasticsearch" "create-templates" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: backoffLimit: {{ .Values.jobs.create_elasticsearch_templates.backoffLimit }} template: metadata: labels: {{ tuple $envAll "elasticsearch" "create-templates" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "create-elasticsearch-templates" "containerNames" (list "create-elasticsearch-templates" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "create_template" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "elasticsearch_templates" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: create-elasticsearch-templates {{ tuple $envAll "elasticsearch_templates" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.elasticsearch_templates | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "create_template" "container" "create_elasticsearch_template" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: ELASTICSEARCH_ENDPOINT value: {{ printf "%s://%s" (tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") (tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") }} {{- if .Values.manifests.certificates }} - name: CACERT_OPTION value: "--cacert /etc/elasticsearch/certs/ca.crt" {{- end }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD command: - /tmp/create_template.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-bin mountPath: /tmp/create_template.sh subPath: create_template.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/etc/elasticsearch/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_elasticsearch_templates.volumeMounts }}{{ toYaml $mounts_elasticsearch_templates.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: elasticsearch-bin configMap: name: elasticsearch-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_elasticsearch_templates.volumes }}{{ toYaml $mounts_elasticsearch_templates.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: elasticsearch/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "elasticsearch" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: elasticsearch/templates/job-s3-bucket.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and (.Values.manifests.job_s3_bucket) (.Values.conf.elasticsearch.snapshots.enabled) }} {{- $esBucket := .Values.conf.elasticsearch.snapshots.bucket }} {{- $s3BucketJob := dict "envAll" . "serviceName" "elasticsearch" "s3Bucket" $esBucket -}} {{- if .Values.manifests.certificates }} {{- $_ := set $s3BucketJob "tlsCertificateSecret" .Values.secrets.tls.elasticsearch.elasticsearch.internal -}} {{- $_ := set $s3BucketJob "tlsCertificatePath" "/etc/elasticsearch/certs/ca.crt" -}} {{- end }} {{ $s3BucketJob | include "helm-toolkit.manifests.job_s3_bucket" }} {{- end -}} ================================================ FILE: elasticsearch/templates/job-s3-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and (.Values.manifests.job_s3_user) (.Values.conf.elasticsearch.snapshots.enabled) }} {{- $s3UserJob := dict "envAll" . "serviceName" "elasticsearch" -}} {{ $s3UserJob | include "helm-toolkit.manifests.job_s3_user" }} {{- end }} ================================================ FILE: elasticsearch/templates/monitoring/prometheus/exporter-deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.deployment_exporter .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $serviceAccountName := "prometheus-elasticsearch-exporter" }} {{ tuple $envAll "prometheus_elasticsearch_exporter" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: prometheus-elasticsearch-exporter labels: {{ tuple $envAll "prometheus-elasticsearch-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.prometheus_elasticsearch_exporter }} selector: matchLabels: {{ tuple $envAll "prometheus-elasticsearch-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "prometheus-elasticsearch-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "prometheus-elasticsearch-exporter" "containerNames" (list "elasticsearch-exporter" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "exporter" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.exporter.node_selector_key }}: {{ .Values.labels.exporter.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.prometheus_elasticsearch_exporter.timeout | default "30" }} initContainers: {{ tuple $envAll "prometheus_elasticsearch_exporter" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: elasticsearch-exporter {{ tuple $envAll "prometheus_elasticsearch_exporter" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "exporter" "container" "elasticsearch_exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - "elasticsearch_exporter" - '--es.uri=$(ELASTICSEARCH_URI)' - '--web.telemetry-path={{ .Values.endpoints.prometheus_elasticsearch_exporter.path.default }}' - '--web.listen-address=:{{ .Values.endpoints.prometheus_elasticsearch_exporter.port.metrics.default }}' - '--es.timeout={{ .Values.conf.prometheus_elasticsearch_exporter.es.timeout }}' - '--log.format={{ .Values.conf.prometheus_elasticsearch_exporter.log.format }}' - '--log.level={{ .Values.conf.prometheus_elasticsearch_exporter.log.level }}' {{- if .Values.conf.prometheus_elasticsearch_exporter.es.all }} - '--es.all' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.indices }} - '--es.indices' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.indices_settings }} - '--es.indices_settings' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.indices_mappings }} - '--es.indices_mappings' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.aliases }} - '--es.aliases' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.shards }} - '--es.shards' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.snapshots }} - '--collector.snapshots' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.cluster_settings }} - '--collector.clustersettings' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.slm }} - '--collector.slm' {{- end }} {{- if .Values.conf.prometheus_elasticsearch_exporter.es.data_stream }} - '--es.data_stream' {{- end }} {{- if .Values.manifests.certificates }} - '--es.ca=/tmp/elasticsearch/certs/ca.crt' {{- else }} - '--es.ssl-skip-verify' {{- end }} env: - name: ELASTICSEARCH_URI valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_URI ports: - name: metrics containerPort: {{ tuple "prometheus_elasticsearch_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "prometheus_elasticsearch_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 volumeMounts: - name: pod-tmp mountPath: /tmp {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/tmp/elasticsearch/certs" "certs" tuple "ca.crt" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: elasticsearch/templates/monitoring/prometheus/exporter-network-policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.network_policy_exporter .Values.monitoring.prometheus.enabled -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "prometheus-elasticsearch-exporter" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: elasticsearch/templates/monitoring/prometheus/exporter-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.service_exporter .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.elasticsearch_exporter }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "prometheus_elasticsearch_exporter" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "prometheus-elasticsearch-exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: ports: - name: metrics port: {{ tuple "prometheus_elasticsearch_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "prometheus-elasticsearch-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: elasticsearch/templates/network-policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "elasticsearch" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: elasticsearch/templates/object-bucket-claim.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and (.Values.manifests.object_bucket_claim) (.Values.conf.elasticsearch.snapshots.enabled) }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: "elasticsearch-dependencies-objectbucket" namespace: {{ .Release.Namespace }} rules: - apiGroups: - "objectbucket.io" verbs: - get - list resources: - objectbuckets --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: "elasticsearch-dependencies-objectbucket" namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: "elasticsearch-dependencies-objectbucket" subjects: - kind: ServiceAccount name: create-elasticsearch-templates namespace: {{ .Release.Namespace }} - kind: ServiceAccount name: verify-repositories namespace: {{ .Release.Namespace }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: "cluster-elasticsearch-dependencies-objectbucket" rules: - apiGroups: - 'objectbucket.io' resources: - objectbuckets verbs: - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: "cluster-elasticsearch-dependencies-objectbucket" subjects: - kind: ServiceAccount name: create-elasticsearch-templates namespace: {{ .Release.Namespace }} - kind: ServiceAccount name: verify-repositories namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: "cluster-elasticsearch-dependencies-objectbucket" apiGroup: rbac.authorization.k8s.io {{- range $bucket := .Values.storage.s3.buckets }} # When using this Rook CRD, not only bucket will be created, # but also a secret containing the credentials to access the bucket. --- apiVersion: objectbucket.io/v1alpha1 kind: ObjectBucketClaim metadata: name: {{ $bucket.name }} spec: bucketName: {{ $bucket.name }} storageClassName: {{ $bucket.storage_class }} ... {{- end -}} {{- end -}} ================================================ FILE: elasticsearch/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.helm_tests }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.Release.Name}}-test" labels: {{ tuple $envAll "elasticsearch" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "elasticsearch-test" "containerNames" (list "init" "elasticsearch-helm-tests") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: elasticsearch-helm-tests {{ tuple $envAll "helm_tests" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "helm_tests" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/helm-tests.sh env: - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: ELASTICSEARCH_ENDPOINT value: {{ printf "%s://%s" (tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") (tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") }} {{- if .Values.manifests.certificates }} - name: CACERT_OPTION value: "--cacert /etc/elasticsearch/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-bin mountPath: /tmp/helm-tests.sh subPath: helm-tests.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/etc/elasticsearch/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} volumes: - name: pod-tmp emptyDir: {} - name: elasticsearch-bin configMap: name: elasticsearch-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} ================================================ FILE: elasticsearch/templates/secret-elasticsearch.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_elasticsearch }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.elasticsearch.user }} {{- $elasticsearch_user := .Values.endpoints.elasticsearch.auth.admin.username }} {{- $elasticsearch_password := .Values.endpoints.elasticsearch.auth.admin.password }} {{- $elasticsearch_host := tuple "elasticsearch" "internal" "http" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} {{- $elasticsearch_scheme := tuple "elasticsearch" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $elasticsearch_uri := printf "%s://%s:%s@%s" $elasticsearch_scheme $elasticsearch_user $elasticsearch_password $elasticsearch_host }} {{- $elasticsearch_url := printf "%s://%s" $elasticsearch_scheme $elasticsearch_host }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: ELASTICSEARCH_USERNAME: {{ .Values.endpoints.elasticsearch.auth.admin.username | b64enc }} ELASTICSEARCH_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.admin.password | b64enc }} ELASTICSEARCH_LOGGING_USERNAME: {{ .Values.endpoints.elasticsearch.auth.logging.username | b64enc }} ELASTICSEARCH_LOGGING_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.logging.password | b64enc }} ELASTICSEARCH_URI: {{ $elasticsearch_uri | b64enc }} ELASTICSEARCH_URL: {{ $elasticsearch_url | b64enc }} BIND_DN: {{ .Values.endpoints.ldap.auth.admin.bind | b64enc }} BIND_PASSWORD: {{ .Values.endpoints.ldap.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: elasticsearch/templates/secret-environment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_environment .Values.pod.env.secrets }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "env-secret" | quote }} type: Opaque data: {{- range $key, $value := .Values.pod.env.secrets }} {{ $key | upper }}: {{ $value | b64enc }} {{- end }} {{- end }} ================================================ FILE: elasticsearch/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "elasticsearch" "backendService" "elasticsearch" ) }} {{- end }} ================================================ FILE: elasticsearch/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: elasticsearch/templates/secret-s3-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_s3 }} {{ include "helm-toolkit.snippets.rgw_s3_secret_creds" . }} {{- end }} ================================================ FILE: elasticsearch/templates/service-data.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_data }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "elasticsearch" "data" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: transport port: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "elasticsearch" "data" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: elasticsearch/templates/service-discovery.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_discovery }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "elasticsearch" "discovery" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: transport port: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "elasticsearch" "master" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: elasticsearch/templates/service-gateway.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.network.remote_clustering.enabled }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "elasticsearch" "gateway" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: transport port: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} nodePort: {{ .Values.network.remote_clustering.node_port.port }} selector: {{ tuple $envAll "elasticsearch" "gateway" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} type: NodePort {{- end }} ================================================ FILE: elasticsearch/templates/service-ingress-elasticsearch.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.elasticsearch.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "elasticsearch" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: elasticsearch/templates/service-logging.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_logging }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "elasticsearch" "default" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: {{ tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} port: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.network.elasticsearch.node_port.enabled }} nodePort: {{ .Values.network.elasticsearch.node_port.port }} {{- end }} selector: {{ tuple $envAll "elasticsearch" "client" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if .Values.network.elasticsearch.node_port.enabled }} type: NodePort {{- end }} {{- end }} ================================================ FILE: elasticsearch/templates/statefulset-data.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset_data }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $s3UserSecret := .Values.secrets.rgw.elasticsearch }} {{- $mounts_elasticsearch := .Values.pod.mounts.elasticsearch.elasticsearch }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "elasticsearch-data" }} {{ tuple $envAll "elasticsearch_data" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: elasticsearch-data annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "elasticsearch" "data" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_statefulset" | indent 2 }} serviceName: {{ tuple "elasticsearch" "data" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} podManagementPolicy: "Parallel" replicas: {{ .Values.pod.replicas.data }} selector: matchLabels: {{ tuple $envAll "elasticsearch" "data" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "elasticsearch" "data" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "elasticsearch-data" "containerNames" (list "elasticsearch-data" "init" "memory-map-increase") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} {{- if and .Values.manifests.secret_s3 .Values.conf.elasticsearch.snapshots.enabled }} secret-s3-user-hash: {{ tuple "secret-s3-user.yaml" . | include "helm-toolkit.utils.hash" }} {{- end }} spec: {{ dict "envAll" $envAll "application" "data" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "elasticsearch" "data" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.data.node_selector_key }}: {{ .Values.labels.data.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.data.timeout | default "600" }} initContainers: {{ tuple $envAll "elasticsearch_data" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: memory-map-increase {{ tuple $envAll "memory_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.data | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "data" "container" "memory_map_increase" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - sysctl - -w - vm.max_map_count={{ .Values.conf.init.max_map_count }} - name: elasticsearch-perms {{ tuple $envAll "elasticsearch" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "data" "container" "elasticsearch_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - "1000:1000" - {{ .Values.conf.elasticsearch.config.path.data }} volumeMounts: - name: storage mountPath: {{ .Values.conf.elasticsearch.config.path.data }} containers: - name: elasticsearch-data {{ tuple $envAll "elasticsearch" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.data | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "data" "container" "elasticsearch_data" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/elasticsearch.sh - start_data_node ports: - name: transport containerPort: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: NODE_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: ELASTICSEARCH_ENDPOINT value: {{ printf "%s://%s" (tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") (tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") }} {{- if .Values.manifests.certificates }} - name: CACERT_OPTION value: "--cacert /usr/share/elasticsearch/config/ca.crt" - name: JAVA_KEYSTORE_CERT_PATH value: "/usr/share/elasticsearch/config/ca.crt" {{- end }} - name: node.roles value: "[data]" - name: HTTP_ENABLE value: "false" - name: ES_JAVA_OPTS value: "{{ .Values.conf.elasticsearch.env.java_opts.data }}" - name: DISCOVERY_SERVICE value: {{ tuple "elasticsearch" "discovery" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- if .Values.conf.elasticsearch.snapshots.enabled }} {{- if .Values.manifests.object_bucket_claim }} {{- include "helm-toolkit.snippets.rgw_s3_bucket_user_env_vars_rook" . | indent 12 }} {{- else }} {{- include "helm-toolkit.snippets.rgw_s3_user_env_vars" . | indent 12 }} {{- end }} {{- end }} {{- if .Values.pod.env.data }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.data | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-logs mountPath: {{ .Values.conf.elasticsearch.config.path.logs }} - name: elasticsearch-bin mountPath: /tmp/elasticsearch.sh subPath: elasticsearch.sh readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/log4j2.properties subPath: log4j2.properties readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/jvm.options subPath: jvm.options readOnly: true - name: storage mountPath: {{ .Values.conf.elasticsearch.config.path.data }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/usr/share/elasticsearch/config" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_elasticsearch.volumeMounts }}{{ toYaml $mounts_elasticsearch.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: elasticsearch-logs emptyDir: {} - name: elasticsearch-bin configMap: name: elasticsearch-bin defaultMode: 0555 - name: elasticsearch-etc secret: secretName: elasticsearch-etc defaultMode: 0444 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_elasticsearch.volumes }}{{ toYaml $mounts_elasticsearch.volumes | indent 8 }}{{ end }} {{- if not .Values.storage.data.enabled }} - name: storage emptyDir: {} {{- else }} volumeClaimTemplates: - metadata: name: storage spec: accessModes: {{ .Values.storage.data.pvc.access_mode }} resources: requests: storage: {{ .Values.storage.data.requests.storage }} storageClassName: {{ .Values.storage.data.storage_class }} {{- end }} {{- end }} ================================================ FILE: elasticsearch/templates/statefulset-master.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset_master }} {{- $envAll := . }} {{- $mounts_elasticsearch := .Values.pod.mounts.elasticsearch.elasticsearch }} {{- $serviceAccountName := "elasticsearch-master" }} {{ tuple $envAll "elasticsearch_master" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: elasticsearch-master annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "elasticsearch" "master" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: {{ tuple "elasticsearch" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} podManagementPolicy: "Parallel" replicas: {{ .Values.pod.replicas.master }} selector: matchLabels: {{ tuple $envAll "elasticsearch" "master" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_statefulset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "elasticsearch" "master" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc-elasticsearch.yaml" . | include "helm-toolkit.utils.hash" }} {{- if and .Values.manifests.secret_s3 .Values.conf.elasticsearch.snapshots.enabled }} secret-s3-user-hash: {{ tuple "secret-s3-user.yaml" . | include "helm-toolkit.utils.hash" }} {{- end }} {{ dict "envAll" $envAll "podName" "elasticsearch-master" "containerNames" (list "elasticsearch-master" "init" "memory-map-increase") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "master" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "elasticsearch" "master" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.master.timeout | default "600" }} nodeSelector: {{ .Values.labels.master.node_selector_key }}: {{ .Values.labels.master.node_selector_value | quote }} initContainers: {{ tuple $envAll "elasticsearch_master" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: memory-map-increase {{ tuple $envAll "memory_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.master | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "master" "container" "memory_map_increase" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - sysctl - -w - vm.max_map_count={{ .Values.conf.init.max_map_count }} - name: elasticsearch-perms {{ tuple $envAll "elasticsearch" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "master" "container" "elasticsearch_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - "1000:1000" - {{ .Values.conf.elasticsearch.config.path.data }} volumeMounts: - name: storage mountPath: {{ .Values.conf.elasticsearch.config.path.data }} containers: - name: elasticsearch-master {{ dict "envAll" $envAll "application" "master" "container" "elasticsearch_master" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll "elasticsearch" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.master | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/elasticsearch.sh - start_master_node lifecycle: preStop: exec: command: - /tmp/elasticsearch.sh - stop ports: - name: transport containerPort: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "elasticsearch" "internal" "discovery" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: NODE_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: node.roles value: "[master]" - name: HTTP_ENABLE value: "false" - name: DISCOVERY_SERVICE value: {{ tuple "elasticsearch" "discovery" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: ES_JAVA_OPTS value: "{{ .Values.conf.elasticsearch.env.java_opts.master }}" {{- if .Values.manifests.certificates }} - name: JAVA_KEYSTORE_CERT_PATH value: "/usr/share/elasticsearch/config/ca.crt" - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.secrets.elasticsearch.user }} key: ELASTICSEARCH_PASSWORD {{- end }} {{- if .Values.conf.elasticsearch.snapshots.enabled }} {{- if .Values.manifests.object_bucket_claim }} {{- include "helm-toolkit.snippets.rgw_s3_bucket_user_env_vars_rook" . | indent 12 }} {{- else }} {{- include "helm-toolkit.snippets.rgw_s3_user_env_vars" . | indent 12 }} {{- end }} {{- end }} {{- if .Values.pod.env.master }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.master | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: elasticsearch-logs mountPath: {{ .Values.conf.elasticsearch.config.path.logs }} - name: elasticsearch-bin mountPath: /tmp/elasticsearch.sh subPath: elasticsearch.sh readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/log4j2.properties subPath: log4j2.properties readOnly: true - name: elasticsearch-etc mountPath: /usr/share/elasticsearch/config/jvm.options subPath: jvm.options readOnly: true - name: storage mountPath: {{ .Values.conf.elasticsearch.config.path.data }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal "path" "/usr/share/elasticsearch/config" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_elasticsearch.volumeMounts }}{{ toYaml $mounts_elasticsearch.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: elasticsearch-logs emptyDir: {} - name: elasticsearch-bin configMap: name: elasticsearch-bin defaultMode: 0555 - name: elasticsearch-etc secret: secretName: elasticsearch-etc defaultMode: 0444 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.elasticsearch.elasticsearch.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_elasticsearch.volumes }}{{ toYaml $mounts_elasticsearch.volumes | indent 8 }}{{ end }} {{- if not .Values.storage.master.enabled }} - name: storage emptyDir: {} {{- else }} volumeClaimTemplates: - metadata: name: storage spec: accessModes: {{ .Values.storage.master.pvc.access_mode }} resources: requests: storage: {{ .Values.storage.master.requests.storage }} storageClassName: {{ .Values.storage.master.storage_class }} {{- end }} {{- end }} ================================================ FILE: elasticsearch/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for elasticsearch # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: apache_proxy: docker.io/library/httpd:2.4 memory_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble elasticsearch: docker.elastic.co/elasticsearch/elasticsearch:8.19.9 curator: docker.io/untergeek/curator:8.0.10 ceph_key_placement: quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407 s3_bucket: quay.io/airshipit/ceph-daemon:ubuntu_jammy_20.2.1-1-20260407 s3_user: quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407 helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble prometheus_elasticsearch_exporter: quay.io/prometheuscommunity/elasticsearch-exporter:v1.9.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy snapshot_repository: quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407 elasticsearch_templates: docker.io/linuxserver/yq:latest image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: client: node_selector_key: openstack-control-plane node_selector_value: enabled data: node_selector_key: openstack-control-plane node_selector_value: enabled exporter: node_selector_key: openstack-control-plane node_selector_value: enabled master: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled gateway: node_selector_key: openstack-control-plane node_selector_value: enabled dependencies: dynamic: common: local_image_registry: jobs: - elasticsearch-image-repo-sync services: - endpoint: node service: local_image_registry static: curator: services: - endpoint: internal service: elasticsearch - endpoint: data service: elasticsearch - endpoint: discovery service: elasticsearch jobs: - elasticsearch-register-snapshot-repository elasticsearch_client: services: - endpoint: discovery service: elasticsearch jobs: null elasticsearch_gateway: services: - endpoint: discovery service: elasticsearch elasticsearch_data: services: - endpoint: internal service: elasticsearch - endpoint: discovery service: elasticsearch jobs: null elasticsearch_master: services: null jobs: null elasticsearch_templates: services: - endpoint: internal service: elasticsearch jobs: - elasticsearch-s3-bucket image_repo_sync: services: - endpoint: internal service: local_image_registry prometheus_elasticsearch_exporter: services: - endpoint: internal service: elasticsearch snapshot_repository: services: - endpoint: internal service: elasticsearch jobs: - elasticsearch-s3-bucket verify_repositories: services: null jobs: - create-elasticsearch-templates s3_user: services: - endpoint: internal service: ceph_object_store s3_bucket: jobs: - elasticsearch-s3-user tests: services: null jobs: - create-elasticsearch-templates pod: env: client: null data: null master: null gateway: null secrets: null security_context: exporter: pod: runAsUser: 99 container: elasticsearch_exporter: allowPrivilegeEscalation: false readOnlyRootFilesystem: true client: pod: runAsUser: 0 container: memory_map_increase: privileged: true readOnlyRootFilesystem: true apache_proxy: readOnlyRootFilesystem: false elasticsearch_client: runAsUser: 1000 runAsGroup: 1000 readOnlyRootFilesystem: false master: pod: runAsUser: 0 container: memory_map_increase: privileged: true readOnlyRootFilesystem: true elasticsearch_perms: readOnlyRootFilesystem: true elasticsearch_master: runAsUser: 1000 runAsGroup: 1000 readOnlyRootFilesystem: false snapshot_repository: pod: runAsUser: 0 container: register_snapshot_repository: readOnlyRootFilesystem: true test: pod: runAsUser: 0 container: helm_test: readOnlyRootFilesystem: true data: pod: runAsUser: 0 container: memory_map_increase: privileged: true readOnlyRootFilesystem: true elasticsearch_perms: readOnlyRootFilesystem: true elasticsearch_data: runAsUser: 1000 runAsGroup: 1000 # NOTE: This was changed from true to false to account for # recovery scenarios when the data pods are unexpectedly lost due to # node outages and shard/index recovery is required readOnlyRootFilesystem: false gateway: pod: runAsUser: 0 container: memory_map_increase: privileged: true readOnlyRootFilesystem: true apache_proxy: readOnlyRootFilesystem: false elasticsearch_gateway: runAsUser: 1000 runAsGroup: 1000 readOnlyRootFilesystem: false curator: pod: runAsUser: 0 container: curator: readOnlyRootFilesystem: true verify_repositories: pod: runAsUser: 0 container: elasticsearch_verify_repositories: readOnlyRootFilesystem: true create_template: pod: runAsUser: 0 container: create_elasticsearch_template: readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: master: 3 data: 3 client: 3 gateway: 3 lifecycle: upgrades: statefulsets: pod_replacement_strategy: RollingUpdate deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: master: timeout: 600 data: timeout: 1200 client: timeout: 600 prometheus_elasticsearch_exporter: timeout: 600 probes: elasticsearch: elasticsearch-client: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 liveness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 10 mounts: elasticsearch: elasticsearch: elasticsearch_templates: elasticsearch_templates: resources: enabled: false apache_proxy: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" client: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" master: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" data: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" prometheus_elasticsearch_exporter: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" gateway: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: curator: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" elasticsearch_templates: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" snapshot_repository: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" storage_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" s3_bucket: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" s3_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network_policy: elasticsearch: ingress: - {} egress: - {} prometheus-elasticsearch-exporter: ingress: - {} egress: - {} secrets: rgw: elasticsearch: elasticsearch-s3-user-creds elasticsearch: user: elasticsearch-user-secrets oci_image_registry: elasticsearch: elasticsearch-oci-image-registry-key tls: elasticsearch: elasticsearch: public: elasticsearch-tls-public internal: elasticsearch-tls-api jobs: curator: cron: "* */6 * * *" history: success: 3 failed: 1 verify_repositories: cron: "*/30 * * * *" history: success: 3 failed: 1 create_elasticsearch_templates: backoffLimit: 6 conf: httpd: | ServerRoot "/usr/local/apache2" Listen 80 LoadModule allowmethods_module modules/mod_allowmethods.so LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule slotmem_shm_module modules/mod_slotmem_shm.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule rewrite_module modules/mod_rewrite.so User daemon Group daemon AllowOverride none Require all denied Require all denied ErrorLog /dev/stderr LogLevel warn LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout common CustomLog /dev/stdout combined CustomLog /dev/stdout proxy env=forwarded AllowOverride None Options None Require all granted RequestHeader unset Proxy early Include conf/extra/proxy-html.conf ProxyPass http://localhost:{{ tuple "elasticsearch" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ ProxyPassReverse http://localhost:{{ tuple "elasticsearch" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ AuthName "Elasticsearch" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user # Restrict access to the Elasticsearch Update By Query API Endpoint to prevent modification of indexed documents Require all denied # Restrict access to the Elasticsearch Delete By Query API Endpoint to prevent deletion of indexed documents Require all denied log4j2: | status = error appender.console.type = Console appender.console.name = console appender.console.layout.type = PatternLayout appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker%m%n rootLogger.level = info rootLogger.appenderRef.console.ref = console jvm_options: | -Xms1g -Xmx1g -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.io.tmpdir=${ES_TMPDIR} {{- if .Values.manifests.certificates }} -Djavax.net.ssl.trustStore=/usr/share/elasticsearch/config/elasticsearch-java-truststore -Djavax.net.ssl.trustStorePassword={{ .Values.endpoints.elasticsearch.auth.admin.password }} {{- end }} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=data -XX:ErrorFile=/usr/share/elasticsearch/logs/hs_err_pid%p.log 8:-XX:+PrintGCDetails 8:-XX:+PrintGCDateStamps 8:-XX:+PrintTenuringDistribution 8:-XX:+PrintGCApplicationStoppedTime 8:-Xloggc:logs/gc.log 8:-XX:+UseGCLogFileRotation 8:-XX:NumberOfGCLogFiles=32 8:-XX:GCLogFileSize=64m 8-13:-XX:+UseConcMarkSweepGC 8-13:-XX:CMSInitiatingOccupancyFraction=75 8-13:-XX:+UseCMSInitiatingOccupancyOnly 9-:-Xlog:gc*,gc+age=trace,safepoint:file=/usr/share/elasticsearch/logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m 9-:-Djava.locale.providers=COMPAT 10-:-XX:UseAVX=2 init: max_map_count: 262144 ceph: admin_keyring: null curator: executable: /curator/curator action_file: {} # Remember, leave a key empty if there is no value. None will be a string, # not a Python "NoneType" # # Also remember that all examples have 'disable_action' set to True. If you # want to use this action as a template, be sure to set this to False after # copying it. # # NOTE(srwilkers): The list of actions below is kept empty, and should be # driven purely by overrides. As these items are injected as pure YAML, # the desired configuration should include all fields as to avoid unwanted # merges with a set of dummy default values. The supplied values can be # used as an example # actions: # 1: # action: delete_indices # description: >- # "Delete indices older than 7 days" # options: # timeout_override: # continue_if_exception: False # ignore_empty_list: True # disable_action: True # filters: # - filtertype: pattern # kind: prefix # value: logstash- # - filtertype: age # source: name # direction: older # timestring: '%Y.%m.%d' # unit: days # unit_count: 7 # 2: # action: delete_indices # description: >- # "Delete indices by age if available disk space is # less than 80% total disk" # options: # timeout_override: 600 # continue_if_exception: False # ignore_empty_list: True # disable_action: True # filters: # - filtertype: pattern # kind: prefix # value: logstash- # - filtertype: space # source: creation_date # use_age: True # # This space assumes the default PVC size of 5Gi times three data # # replicas. This must be adjusted if changed due to Curator being # # unable to calculate percentages of total disk space # disk_space: 12 # 3: # action: snapshot # description: >- # "Snapshot indices older than one day" # options: # repository: logstash_snapshots # # Leaving this blank results in the default name format # name: # wait_for_completion: True # max_wait: 3600 # wait_interval: 10 # timeout_override: 600 # ignore_empty_list: True # continue_if_exception: False # disable_action: True # filters: # - filtertype: age # source: name # direction: older # timestring: '%Y.%m.%d' # unit: days # unit_count: 1 # 4: # action: delete_snapshots # description: >- # "Delete snapshots older than 30 days" # options: # repository: logstash_snapshots # disable_action: True # timeout_override: 600 # ignore_empty_list: True # filters: # - filtertype: pattern # kind: prefix # value: curator- # exclude: # - filtertype: age # source: creation_date # direction: older # unit: days # unit_count: 30 config: # Remember, leave a key empty if there is no value. None will be a string, # not a Python "NoneType" elasticsearch: client: hosts: ${ELASTICSEARCH_URL} request_timeout: 60 other_settings: username: ${ELASTICSEARCH_USERNAME} password: ${ELASTICSEARCH_PASSWORD} logging: loglevel: INFO logformat: json blacklist: ['elastic_transport', 'urllib3'] elasticsearch: config: xpack: security: enabled: false bootstrap: # As far as we run the pod as non-root, we can't make locking memory unlimited. # configure the memory locking limits on host itself of disable swap completely. memory_lock: false cluster: name: elasticsearch discovery: # NOTE(srwilkers): This gets configured dynamically via endpoint lookups seed_hosts: null network: host: 0.0.0.0 s3: client: {} path: data: /data logs: /logs snapshots: enabled: false env: java_opts: client: "-Xms256m -Xmx256m" data: "-Xms256m -Xmx256m" master: "-Xms256m -Xmx256m" prometheus_elasticsearch_exporter: es: timeout: 30s all: true indices: true indices_settings: true indices_mappings: true aliases: false shards: true snapshots: true cluster_settings: true slm: true data_stream: false log: format: logfmt level: info api_objects: {} # Fill this map with API objects to create once Elasticsearch is deployed # name: # This name can be completely arbitrary # method: # Defaults to PUT # endpoint: # Path for the request # body: # Body of the request in yaml (Converted to Json in Template) # Example: ILM Policy # ilm_policy: # endpoint: _ilm/policy/delete_all_indexes # body: # policy: # phases: # delete: # min_age: 14d # actions: # delete: {} endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false elasticsearch: username: elasticsearch password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null elasticsearch: name: elasticsearch namespace: null auth: admin: username: admin password: changeme logging: username: remote password: changeme hosts: data: elasticsearch-data default: elasticsearch-logging discovery: elasticsearch-discovery gateway: elasticsaerch-gateway public: elasticsearch host_fqdn_override: default: null path: default: null scheme: default: http gateway: tcp port: client: default: 9200 http: default: 80 discovery: default: 9300 prometheus_elasticsearch_exporter: namespace: null hosts: default: elasticsearch-exporter host_fqdn_override: default: null path: default: /metrics scheme: default: 'http' port: metrics: default: 9108 ldap: hosts: default: ldap auth: admin: bind: "cn=admin,dc=cluster,dc=local" password: password host_fqdn_override: default: null path: default: "/ou=People,dc=cluster,dc=local" scheme: default: ldap port: ldap: default: 389 ceph_object_store: name: radosgw namespace: null hosts: default: ceph-rgw public: radosgw host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 8088 public: 80 monitoring: prometheus: enabled: false elasticsearch_exporter: scrape: true network: elasticsearch: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30920 remote_clustering: enabled: false node_port: port: 30930 storage: data: enabled: true pvc: name: pvc-elastic access_mode: ["ReadWriteOnce"] requests: storage: 5Gi storage_class: general master: enabled: true pvc: name: pvc-elastic access_mode: ["ReadWriteOnce"] requests: storage: 1Gi storage_class: general s3: clients: {} # These values configure the s3 clients section of elasticsearch.yml # See: https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-client.html # default: # auth: # # Values under auth are written to the Secret $client-s3-user-secret # # and the access & secret keys are added to the elasticsearch keystore # username: elasticsearch # access_key: "elastic_access_key" # secret_key: "elastic_secret_key" # settings: # # Configure Client Settings here (https://www.elastic.co/guide/en/elasticsearch/plugins/current/repository-s3-client.html) # # endpoint: Defaults to the ceph-rgw endpoint # # protocol: Defaults to http # path_style_access: true # Required for ceph-rgw S3 API # create_user: true # Attempt to create the user at the ceph_object_store endpoint # backup: # auth: # username: elasticsearch # access_key: "backup_access_key" # secret_key: "backup_secret_key" # settings: # endpoint: s3.example.com # Specify your own s3 endpoint (defaults to the ceph_object_store endpoint) # path_style_access: false # create_user: false buckets: {} # List of buckets to create (if required). # (The client field references one of the clients defined above) # - name: elasticsearch-bucket # client: default # options: # list of extra options for s3cmd # - --region="default:osh-infra" # # SSL connection option for s3cmd # ssl_connecton_option: --ca-certs={path to mounted ca.crt} # - name: backup-bucket # client: backup # options: # list of extra options for s3cmd # - --region="default:backup" # # SSL connection option for s3cmd # ssl_connecton_option: --ca-certs={path to mounted ca.crt} manifests: certificates: false configmap_bin_curator: false configmap_bin_elasticsearch: true configmap_etc_curator: false configmap_etc_elasticsearch: true configmap_etc_templates: true cron_curator: false cron_verify_repositories: true deployment_client: true ingress: true job_elasticsearch_templates: true job_image_repo_sync: true job_snapshot_repository: true job_s3_user: true job_s3_bucket: true helm_tests: true secret_elasticsearch: true secret_s3: true monitoring: prometheus: configmap_bin_exporter: true deployment_exporter: true network_policy_exporter: false service_exporter: true network_policy: false secret_ingress_tls: true secret_registry: true service_data: true service_discovery: true service_ingress: true service_logging: true statefulset_data: true statefulset_master: true object_bucket_claim: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: etcd/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v3.4.3 description: OpenStack-Helm etcd name: etcd version: 2025.2.0 home: https://coreos.com/etcd/ icon: https://raw.githubusercontent.com/CloudCoreo/etcd-cluster/master/images/icon.png sources: - https://github.com/coreos/etcd/ - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: etcd/templates/bin/_etcd-db-compact.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x export ETCDCTL_API=3 {{- if .Values.jobs.db_compact.command_timeout }} COMMAND_TIMEOUT='--command-timeout={{ .Values.jobs.db_compact.command_timeout }}' {{- else }} COMMAND_TIMEOUT='' {{- end }} ENDPOINTS=$(etcdctl member list --endpoints=http://${ETCD_SERVICE_HOST}:${ETCD_SERVICE_PORT} ${COMMAND_TIMEOUT}| cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcdctl --endpoints=${ENDPOINTS} endpoint status --write-out="table" ${COMMAND_TIMEOUT} rev=$(etcdctl --endpoints=http://${ETCD_SERVICE_HOST}:${ETCD_SERVICE_PORT} endpoint status --write-out="json" ${COMMAND_TIMEOUT}| egrep -o '"revision":[0-9]*' | egrep -o '[0-9].*') compact_result=$(etcdctl compact --physical=true --endpoints=${ENDPOINTS} $rev ${COMMAND_TIMEOUT} 2>&1 > /dev/null) compact_res=$? if [[ $compact_res -ne 0 ]]; then match_pattern=$(echo ${compact_result} | egrep '(mvcc: required revision has been compacted.*$)') match_pattern_res=$? if [[ $match_pattern_res -eq 0 ]]; then exit 0 else echo "Failed to compact database: $compact_result" exit $compact_res fi else etcdctl defrag --endpoints=${ENDPOINTS} ${COMMAND_TIMEOUT} etcdctl --endpoints=${ENDPOINTS} endpoint status --write-out="table" ${COMMAND_TIMEOUT} fi ================================================ FILE: etcd/templates/bin/_etcd-healthcheck.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x export ETCDCTL_API=3 ETCD_CLIENT_PORT={{ tuple "etcd" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} DISCOVERY_DOMAIN={{ tuple "etcd" "discovery" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} etcdctl endpoint health --endpoints=${POD_NAME}.${DISCOVERY_DOMAIN}:${ETCD_CLIENT_PORT} ================================================ FILE: etcd/templates/bin/_etcd.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex active_members_present() { res=1 for endpoint in $(echo $ETCD_ENDPOINTS | tr ',' '\n'); do if etcdctl endpoint health --endpoints=$endpoint >/dev/null 2>&1; then res=$? if [[ "$res" == 0 ]]; then break fi fi done echo $res } ETCD_REPLICAS={{ .Values.pod.replicas.etcd }} PEER_PREFIX_NAME={{- printf "%s-%s" .Release.Name "etcd" }} DISCOVERY_DOMAIN={{ tuple "etcd" "discovery" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} ETCD_PEER_PORT=2380 ETCD_CLIENT_PORT={{ tuple "etcd" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} ETCD_PROTOCOL={{ tuple "etcd" "internal" "client" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} PEERS="${PEER_PREFIX_NAME}-0=${ETCD_PROTOCOL}://${PEER_PREFIX_NAME}-0.${DISCOVERY_DOMAIN}:${ETCD_PEER_PORT}" ETCD_ENDPOINTS="${ETCD_PROTOCOL}://${PEER_PREFIX_NAME}-0.${DISCOVERY_DOMAIN}:${ETCD_PEER_PORT}" if [[ ${ETCD_REPLICAS} -gt 1 ]] ; then for i in $(seq 1 $(( ETCD_REPLICAS - 1 ))); do PEERS="$PEERS,${PEER_PREFIX_NAME}-${i}=${ETCD_PROTOCOL}://${PEER_PREFIX_NAME}-${i}.${DISCOVERY_DOMAIN}:${ETCD_PEER_PORT}" ETCD_ENDPOINTS="${ETCD_ENDPOINTS},${ETCD_PROTOCOL}://${PEER_PREFIX_NAME}-${i}.${DISCOVERY_DOMAIN}:${ETCD_PEER_PORT}" done fi ADVERTISE_PEER_URL="${ETCD_PROTOCOL}://${HOSTNAME}.${DISCOVERY_DOMAIN}:${ETCD_PEER_PORT}" ADVERTISE_CLIENT_URL="${ETCD_PROTOCOL}://${HOSTNAME}.${DISCOVERY_DOMAIN}:${ETCD_CLIENT_PORT}" ETCD_INITIAL_CLUSTER_STATE=new if [[ -z "$(ls -A $ETCD_DATA_DIR)" ]]; then echo "State directory $ETCD_DATA_DIR is empty." if [[ $(active_members_present) -eq 0 ]]; then ETCD_INITIAL_CLUSTER_STATE=existing member_id=$(etcdctl --endpoints=${ETCD_ENDPOINTS} member list | grep -w ${ADVERTISE_CLIENT_URL} | awk -F "," '{ print $1 }') if [[ -n "$member_id" ]]; then echo "Current node is a member of cluster, member_id: ${member_id}" echo "Rejoining..." echo "Removing member from the cluster" etcdctl member remove "$member_id" --endpoints=${ETCD_ENDPOINTS} etcdctl member add ${ADVERTISE_CLIENT_URL} --peer-urls=${ADVERTISE_PEER_URL} --endpoints=${ETCD_ENDPOINTS} fi else echo "Do not have active members. Starting initial cluster state." fi fi exec etcd \ --name ${HOSTNAME} \ --listen-peer-urls ${ETCD_PROTOCOL}://0.0.0.0:${ETCD_PEER_PORT} \ --listen-client-urls ${ETCD_PROTOCOL}://0.0.0.0:${ETCD_CLIENT_PORT} \ --advertise-client-urls ${ADVERTISE_CLIENT_URL} \ --initial-advertise-peer-urls ${ADVERTISE_PEER_URL} \ --initial-cluster ${PEERS} \ --initial-cluster-state ${ETCD_INITIAL_CLUSTER_STATE} ================================================ FILE: etcd/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $configMapBinName := printf "%s-%s" $envAll.Release.Name "etcd-bin" }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapBinName }} data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} etcd.sh: | {{ tuple "bin/_etcd.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- if .Values.manifests.cron_job_db_compact }} etcd-db-compact.sh: | {{ tuple "bin/_etcd-db-compact.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} etcd-healthcheck.sh: | {{ tuple "bin/_etcd-healthcheck.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: etcd/templates/cron-job-db-compact.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_db_compact }} {{- $envAll := . }} {{- $configMapBinName := printf "%s-%s" $envAll.Release.Name "etcd-bin" }} {{- $serviceAccountName := "etcd-db-compact" }} {{ tuple $envAll "db_compact" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: etcd-db-compaction annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.db_compact.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.db_compact.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.db_compact.history.failed }} {{- if .Values.jobs.db_compact.starting_deadline }} startingDeadlineSeconds: {{ .Values.jobs.db_compact.starting_deadline }} {{- end }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "etcd" "db-compact" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "etcd" "db-compact" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ dict "envAll" $envAll "application" "etcd_db_compact" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "db_compact" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: etcd-db-compact {{ tuple $envAll "etcd_db_compact" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_compact | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "etcd_db_compact" "container" "etcd_db_compact" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - /tmp/etcd-db-compact.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcd-bin mountPath: /tmp/etcd-db-compact.sh subPath: etcd-db-compact.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: etcd-bin configMap: name: {{ $configMapBinName | quote }} defaultMode: 0555 {{- end }} ================================================ FILE: etcd/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: etcd/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "etcd" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: etcd/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: etcd/templates/service-discovery.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.service_discovery }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "etcd" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: client port: {{ tuple "etcd" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: client - name: peer port: {{ tuple "etcd_discovery" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: peer publishNotReadyAddresses: true clusterIP: None selector: {{ tuple $envAll "etcd" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: etcd/templates/service.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "etcd" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: sessionAffinity: ClientIP ports: - name: client port: {{ tuple "etcd" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: client - name: peer port: {{ tuple "etcd_discovery" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP targetPort: peer selector: {{ tuple $envAll "etcd" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: etcd/templates/statefulset.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- define "etcdProbeTemplate" }} exec: command: - /tmp/etcd-healthcheck.sh {{- end }} {{- if .Values.manifests.statefulset }} {{- $envAll := . }} {{- $rcControllerName := printf "%s-%s" $envAll.Release.Name "etcd" }} {{- $configMapBinName := printf "%s-%s" $envAll.Release.Name "etcd-bin" }} {{ tuple $envAll "etcd" $rcControllerName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ $rcControllerName | quote }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "etcd" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: podManagementPolicy: "Parallel" serviceName: "{{ tuple "etcd" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}" replicas: {{ .Values.pod.replicas.etcd }} selector: matchLabels: {{ tuple $envAll "etcd" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "etcd" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "etcd" "containerNames" (list "init" "etcd") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $rcControllerName | quote }} {{ dict "envAll" $envAll "application" "etcd" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "etcd" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value }} initContainers: {{ tuple $envAll "etcd" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: etcd {{ tuple $envAll "etcd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "etcd" "container" "etcd" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" . "component" "etcd" "container" "etcd" "type" "readiness" "probeTemplate" (include "etcdProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "etcd" "container" "etcd" "type" "liveness" "probeTemplate" (include "etcdProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.etcd | indent 12 }} - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name command: - /tmp/etcd.sh ports: - containerPort: {{ tuple "etcd" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: client protocol: TCP - containerPort: {{ tuple "etcd_discovery" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: peer protocol: TCP volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcd-bin mountPath: /tmp/etcd.sh subPath: etcd.sh readOnly: true - name: etcd-data mountPath: /var/lib/etcd - name: etcd-bin mountPath: /tmp/etcd-healthcheck.sh subPath: etcd-healthcheck.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: etcd-bin configMap: name: {{ $configMapBinName | quote }} defaultMode: 0555 {{- if not .Values.volume.enabled }} - name: etcd-data emptyDir: {} {{- end }} {{- end }} {{- if .Values.volume.enabled }} volumeClaimTemplates: - metadata: name: etcd-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: {{ .Values.volume.size }} {{- if ne .Values.volume.class_name "default" }} storageClassName: {{ .Values.volume.class_name }} {{- end }} {{- end }} ================================================ FILE: etcd/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for etcd. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- images: tags: etcd: 'registry.k8s.io/etcd-amd64:3.4.3' dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 etcd_db_compact: 'registry.k8s.io/etcd-amd64:3.4.3' pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled dependencies: dynamic: common: local_image_registry: jobs: - etcd-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry etcd: jobs: null db_compact: services: - endpoint: internal service: etcd pod: env: etcd: ETCD_DATA_DIR: /var/lib/etcd ETCD_INITIAL_CLUSTER_TOKEN: etcd-cluster-1 security_context: etcd: pod: runAsUser: 65534 container: etcd: runAsUser: 0 readOnlyRootFilesystem: false etcd_db_compact: pod: runAsUser: 65534 runAsNonRoot: true allowPrivilegeEscalation: false container: etcd_db_compact: allowPrivilegeEscalation: false capabilities: drop: - ALL probes: etcd: etcd: readiness: enabled: True params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 1 liveness: enabled: True params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 1 affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: etcd: 1 lifecycle: upgrades: deployments: pod_replacement_strategy: RollingUpdate revision_history: 3 rolling_update: max_surge: 3 max_unavailable: 1 resources: jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_compact: requests: memory: "128Mi" cpu: "100m" secrets: oci_image_registry: etcd: etcd-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false etcd: username: etcd password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null etcd: name: etcd hosts: default: etcd discovery: etcd-discovery host_fqdn_override: default: null path: default: null scheme: default: 'http' port: client: default: 2379 etcd_discovery: name: etcd-discovery hosts: default: etcd-discovery host_fqdn_override: default: null path: default: null scheme: default: 'http' port: client: default: 2380 volume: enabled: false class_name: general size: 5Gi jobs: db_compact: cron: "1 */2 * * *" starting_deadline: 600 # Timeout have to be set the same format # as it is for etcdctl 120s, 1m etc. command_timeout: 120s history: success: 3 failed: 1 manifests: configmap_bin: true statefulset: true job_image_repo_sync: true secret_registry: true service: true service_discovery: true cron_job_db_compact: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: fluentbit/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v0.14.2 description: OpenStack-Helm Fluentbit name: fluentbit version: 2025.2.0 home: https://www.fluentbit.io/ sources: - https://github.com/fluent/fluentbit - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit/ version: ">= 0.1.0" ... ================================================ FILE: fluentbit/templates/bin/_fluent-bit.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex if [ -d "/var/log/journal" ]; then export JOURNAL_PATH="/var/log/journal" else export JOURNAL_PATH="/run/log/journal" fi exec /fluent-bit/bin/fluent-bit -c /fluent-bit/etc/fluent-bit.conf ================================================ FILE: fluentbit/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: fluentbit-bin data: fluent-bit.sh: | {{ tuple "bin/_fluent-bit.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: fluentbit/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: fluentbit-etc type: Opaque data: fluent-bit.conf: {{ .Values.conf.fluentbit.template | b64enc }} parsers.conf: {{ .Values.conf.parsers.template | b64enc }} {{- end }} ================================================ FILE: fluentbit/templates/daemonset-fluent-bit.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset_fluentbit }} {{- $envAll := . }} {{- $mounts_fluentbit := .Values.pod.mounts.fluentbit.fluentbit }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "fluentbit" }} {{ tuple $envAll "fluentbit" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - namespaces - nodes - pods - services - replicationcontrollers - limitranges verbs: - get - list - watch - apiGroups: - apps resources: - statefulsets - daemonsets - deployments - replicasets verbs: - get - list - watch --- apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentbit annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "fluentbit" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "fluentbit" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "fluentbit" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "fluentbit" "daemon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "fluentbit" "containerNames" (list "fluentbit") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "fluentbit" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.fluentbit.enabled }} {{ tuple $envAll "fluentbit" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ else }} nodeSelector: {{ .Values.labels.fluentbit.node_selector_key }}: {{ .Values.labels.fluentbit.node_selector_value | quote }} {{ end }} hostNetwork: true hostPID: true dnsPolicy: {{ .Values.pod.dns_policy }} initContainers: {{ tuple $envAll "fluentbit" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: fluentbit {{ tuple $envAll "fluentbit" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.fluentbit | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "fluentbit" "container" "fluentbit" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/fluent-bit.sh env: - name: FLUENTD_HOST value: {{ tuple "fluentd" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" | quote }} - name: FLUENTD_PORT value: {{ tuple "fluentd" "internal" "service" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: fluentbit-bin mountPath: /tmp/fluent-bit.sh subPath: fluent-bit.sh readOnly: true - name: varlog mountPath: /var/log readOnly: true - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: fluentbit-etc mountPath: /fluent-bit/etc/fluent-bit.conf subPath: fluent-bit.conf readOnly: true - name: fluentbit-etc mountPath: /fluent-bit/etc/parsers.conf subPath: parsers.conf readOnly: true {{ if $mounts_fluentbit.volumeMounts }}{{ toYaml $mounts_fluentbit.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers - name: fluentbit-bin configMap: name: fluentbit-bin defaultMode: 0555 - name: fluentbit-etc secret: secretName: fluentbit-etc defaultMode: 0444 {{ if $mounts_fluentbit.volumes }}{{ toYaml $mounts_fluentbit.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: fluentbit/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: fluentbit/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "fluentbit" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: fluentbit/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: fluentbit/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for fluentbit # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- release_group: null labels: fluentbit: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: fluentbit: docker.io/fluent/fluent-bit:0.14.2 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync dependencies: dynamic: common: local_image_registry: jobs: - fluentbit-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry conf: fluentbit: template: | [SERVICE] Daemon false Flush 30 Log_Level info Parsers_File parsers.conf [INPUT] Buffer_Chunk_Size 1M Buffer_Max_Size 1M Mem_Buf_Limit 5MB Name tail Path /var/log/kern.log Tag kernel [INPUT] Buffer_Chunk_Size 1M Buffer_Max_Size 1M Mem_Buf_Limit 5MB Name tail Parser docker Path /var/log/containers/*.log Tag kube.* [INPUT] Buffer_Chunk_Size 1M Buffer_Max_Size 1M Mem_Buf_Limit 5MB Name tail Path /var/log/libvirt/libvirtd.log Tag libvirt [INPUT] Buffer_Chunk_Size 1M Buffer_Max_Size 1M Mem_Buf_Limit 5MB Name tail Path /var/log/libvirt/qemu/*.log Tag qemu [INPUT] Buffer_Chunk_Size 1M Buffer_Max_Size 1M Mem_Buf_Limit 5MB Name systemd Path ${JOURNAL_PATH} Systemd_Filter _SYSTEMD_UNIT=kubelet.service Tag journal.* [INPUT] Buffer_Chunk_Size 1M Buffer_Max_Size 1M Mem_Buf_Limit 5MB Name systemd Path ${JOURNAL_PATH} Systemd_Filter _SYSTEMD_UNIT=docker.service Tag journal.* [FILTER] Interval 1s Match ** Name throttle Rate 1000 Window 300 [FILTER] Match libvirt Name record_modifier Record hostname ${HOSTNAME} [FILTER] Match qemu Name record_modifier Record hostname ${HOSTNAME} [FILTER] Match kernel Name record_modifier Record hostname ${HOSTNAME} [FILTER] Match journal.** Name modify Rename _BOOT_ID BOOT_ID Rename _CAP_EFFECTIVE CAP_EFFECTIVE Rename _CMDLINE CMDLINE Rename _COMM COMM Rename _EXE EXE Rename _GID GID Rename _HOSTNAME HOSTNAME Rename _MACHINE_ID MACHINE_ID Rename _PID PID Rename _SYSTEMD_CGROUP SYSTEMD_CGROUP Rename _SYSTEMD_SLICE SYSTEMD_SLICE Rename _SYSTEMD_UNIT SYSTEMD_UNIT Rename _TRANSPORT TRANSPORT Rename _UID UID [OUTPUT] Match **.fluentd** Name null [FILTER] Match kube.* Merge_JSON_Log true Name kubernetes [OUTPUT] Host ${FLUENTD_HOST} Match * Name forward Port ${FLUENTD_PORT} parsers: template: | [PARSER] Decode_Field_As escaped_utf8 log Format json Name docker Time_Format %Y-%m-%dT%H:%M:%S.%L Time_Keep true Time_Key time secrets: oci_image_registry: fluentbit: fluentbit-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false fluentbit: username: fluentbit password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: default: http port: service: default: 24224 metrics: default: 24220 pod: security_context: fluentbit: pod: runAsUser: 65534 container: fluentbit: runAsUser: 0 readOnlyRootFilesystem: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname dns_policy: "ClusterFirstWithHostNet" lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate fluentbit: enabled: true min_ready_seconds: 0 max_unavailable: 1 resources: enabled: false fluentbit: limits: memory: '400Mi' cpu: '400m' requests: memory: '100Mi' cpu: '100m' tolerations: fluentbit: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/control-plane operator: Exists - key: node-role.kubernetes.io/node operator: Exists mounts: fluentbit: fluentbit: manifests: configmap_bin: true configmap_etc: true daemonset_fluentbit: true job_image_repo_sync: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: fluentd/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.10.1 description: OpenStack-Helm Fluentd name: fluentd version: 2025.2.0 home: https://www.fluentd.org/ sources: - https://github.com/fluent/fluentd - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit/ version: ">= 0.1.0" ... ================================================ FILE: fluentd/templates/bin/_fluentd.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { chmod 1777 /tmp exec fluentd -c /fluentd/etc/main.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: fluentd/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.Release.Name "fluentd-bin" | quote }} data: fluentd.sh: | {{ tuple "bin/_fluentd.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: fluentd/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "fluentd_main" }} {{- $path := .Values.conf.fluentd.path}} {{- range $name, $conf := .Values.conf.fluentd.conf }} {{ printf "%s %s/%s.conf" "@include" $path $name | indent 4}} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{ $envAll := .}} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "fluentd-etc" | quote }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} type: Opaque stringData: main.conf: | {{- template "fluentd_main" . }} data: {{- range $name, $config := .Values.conf.fluentd.conf }} {{- $filename := printf "%s.conf" $name}} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" $config "key" $filename "format" "Secret") | indent 2 }} {{- end }} {{- end }} ================================================ FILE: fluentd/templates/daemonset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "probeTemplate" }} tcpSocket: port: {{ tuple "fluentd" "internal" "service" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $config_path := .Values.conf.fluentd.path }} {{- $mounts_fluentd := .Values.pod.mounts.fluentd.fluentd }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.fluentd }} {{- $kafkaBroker := tuple "kafka" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- $kafkaBrokerPort := tuple "kafka" "internal" "broker" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $kafkaBrokerURI := printf "%s" $kafkaBroker }} {{- $rcControllerName := printf "%s-%s" $envAll.Release.Name "fluentd" }} {{ tuple $envAll "fluentd" $rcControllerName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $rcControllerName | quote }} subjects: - kind: ServiceAccount name: {{ $rcControllerName | quote }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $rcControllerName | quote }} apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $rcControllerName | quote }} rules: - apiGroups: - "" resources: - namespaces - nodes - pods - services - replicationcontrollers - limitranges verbs: - get - list - watch - apiGroups: - apps resources: - statefulsets - daemonsets - deployments - replicasets verbs: - get - list - watch --- apiVersion: apps/v1 kind: DaemonSet metadata: name: {{ $rcControllerName | quote }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "fluentd" "internal" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{ tuple $envAll "fluentd" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} selector: matchLabels: {{ tuple $envAll "fluentd" "internal" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "fluentd" "internal" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_pod_annotations" | indent 8 }} {{- end }} {{ dict "envAll" $envAll "podName" "fluentd" "containerNames" (list "fluentd" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "fluentd" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $rcControllerName | quote }} {{ if $envAll.Values.pod.tolerations.fluentd.enabled }} {{ tuple $envAll "fluentd" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.fluentd.node_selector_key }}: {{ .Values.labels.fluentd.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.fluentd.timeout | default "30" }} initContainers: {{ tuple $envAll "fluentd" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: fluentd {{ tuple $envAll "fluentd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.fluentd | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "fluentd" "container" "fluentd" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/fluentd.sh - start ports: - name: forward containerPort: {{ tuple "fluentd" "internal" "service" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: metrics containerPort: {{ tuple "fluentd" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" . "component" "fluentd" "container" "fluentd" "type" "readiness" "probeTemplate" (include "probeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "fluentd" "container" "fluentd" "type" "liveness" "probeTemplate" (include "probeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: FLUENTD_PORT value: {{ tuple "fluentd" "internal" "service" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ELASTICSEARCH_HOST value: {{ tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" | quote }} - name: ELASTICSEARCH_PORT value: {{ tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ELASTICSEARCH_SCHEME value: {{ tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | quote }} - name: KAFKA_BROKER value: {{ $kafkaBrokerURI }} {{- if .Values.pod.env.fluentd.vars }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.fluentd.vars | indent 12 }} {{- end }} {{- if .Values.pod.env.fluentd.secrets }} {{ tuple $envAll .Values.pod.env.fluentd.secrets | include "helm-toolkit.utils.to_k8s_env_secret_vars" | indent 12 }} {{- end }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "elasticsearch-user" | quote }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "elasticsearch-user" | quote }} key: ELASTICSEARCH_PASSWORD {{- if .Values.manifests.secret_kafka }} - name: KAFKA_USERNAME valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "kafka-user" | quote }} key: KAFKA_USERNAME - name: KAFKA_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "kafka-user" | quote }} key: KAFKA_PASSWORD {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: varlog mountPath: /var/log - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: pod-etc-fluentd mountPath: /fluentd/etc - name: fluentd-etc mountPath: {{ printf "%s/%s.conf" $config_path "main" }} subPath: {{ printf "%s.conf" "main"}} readOnly: true {{- range $name, $config := .Values.conf.fluentd.conf }} - name: fluentd-etc mountPath: {{ printf "%s/%s.conf" $config_path $name }} subPath: {{ printf "%s.conf" $name }} readOnly: true {{- end }} - name: fluentd-bin mountPath: /tmp/fluentd.sh subPath: fluentd.sh readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.elasticsearch.auth.admin.secret.tls.internal "path" "/etc/elasticsearch/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_fluentd.volumeMounts }}{{ toYaml $mounts_fluentd.volumeMounts | indent 12 }}{{- end }} volumes: - name: pod-tmp emptyDir: {} - name: varlog hostPath: path: /var/log - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers - name: pod-etc-fluentd emptyDir: {} {{ if and (.Values.manifests.secret_fluentd_env) (.Values.pod.env.fluentd.secrets) }} - name: {{ printf "%s-%s" $envAll.Release.Name "env-secret" | quote }} secret: secretName: {{ printf "%s-%s" $envAll.Release.Name "env-secret" | quote }} defaultMode: 0444 {{- end }} - name: fluentd-etc secret: secretName: {{ printf "%s-%s" $envAll.Release.Name "fluentd-etc" | quote }} defaultMode: 0444 - name: fluentd-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "fluentd-bin" | quote }} defaultMode: 0555 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.elasticsearch.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_fluentd.volumes }}{{ toYaml $mounts_fluentd.volumes | indent 8 }}{{- end }} {{- end }} ================================================ FILE: fluentd/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: fluentd/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "fluentd" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: fluentd/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{ $netpol_opts := dict "envAll" . "name" "application" "label" "fluentd" }} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: fluentd/templates/secret-elasticsearch-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_elasticsearch }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "elasticsearch-user" | quote }} type: Opaque data: ELASTICSEARCH_USERNAME: {{ .Values.endpoints.elasticsearch.auth.admin.username | b64enc }} ELASTICSEARCH_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: fluentd/templates/secret-fluentd.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and (.Values.manifests.secret_fluentd_env) (.Values.pod.env.fluentd.secrets) }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "env-secret" | quote }} type: Opaque data: {{ range $key, $value := .Values.pod.env.fluentd.secrets }} {{$key | upper}}: {{ $value | b64enc }} {{- end }} {{- end }} ================================================ FILE: fluentd/templates/secret-kafka-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_kafka }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "kafka-user" | quote }} type: Opaque data: KAFKA_USERNAME: {{ .Values.endpoints.kafka.auth.admin.username | b64enc }} KAFKA_PASSWORD: {{ .Values.endpoints.kafka.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: fluentd/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: fluentd/templates/service-fluentd.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_fluentd }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "fluentd" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: forward port: {{ tuple "fluentd" "internal" "service" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.fluentd.node_port.enabled }} nodePort: {{ .Values.network.fluentd.node_port.port }} {{ end }} selector: {{ tuple $envAll "fluentd" "internal" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.fluentd.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: fluentd/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for fluentd. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- release_group: null labels: fluentd: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: fluentd: quay.io/airshipit/fluentd:latest-debian dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync dependencies: dynamic: common: local_image_registry: jobs: - fluentd-image-repo-sync services: - endpoint: node service: local_image_registry static: fluentd: services: null image_repo_sync: services: - endpoint: internal service: local_image_registry conf: fluentd: path: /fluentd/etc conf: input: | bind 0.0.0.0 port "#{ENV['FLUENTD_PORT']}" @type forward time_format %Y-%m-%dT%H:%M:%S.%NZ @type json path /var/log/containers/*.log read_from_head true tag kubernetes.* @type tail @type relabel @label @output output: | secrets: oci_image_registry: fluentd: fluentd-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false fluentd: username: fluentd password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null elasticsearch: namespace: null name: elasticsearch auth: admin: username: admin password: changeme secret: tls: internal: elasticsearch-tls-api hosts: data: elasticsearch-data default: elasticsearch-logging discovery: elasticsearch-discovery public: elasticsearch host_fqdn_override: default: null path: default: null scheme: default: http port: http: default: 80 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: default: http port: service: default: 24224 metrics: default: 24231 kafka: namespace: null name: kafka auth: admin: username: admin password: changeme hosts: default: kafka-broker public: kafka host_fqdn_override: default: null path: default: null scheme: default: kafka port: broker: default: 9092 public: 80 monitoring: prometheus: enabled: true fluentd: scrape: true port: 24231 network: fluentd: node_port: enabled: false port: 32329 network_policy: fluentd: ingress: - {} egress: - {} pod: env: fluentd: vars: null secrets: null tolerations: fluentd: enabled: false security_context: fluentd: pod: runAsUser: 0 container: fluentd: allowPrivilegeEscalation: false readOnlyRootFilesystem: true lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate fluentd: enabled: true min_ready_seconds: 0 max_unavailable: 1 termination_grace_period: fluentd: timeout: 30 resources: enabled: false fluentd: limits: memory: '1024Mi' cpu: '2000m' requests: memory: '128Mi' cpu: '500m' mounts: fluentd: fluentd: probes: fluentd: fluentd: readiness: enabled: true params: initialDelaySeconds: 90 timeoutSeconds: 30 liveness: enabled: true params: initialDelaySeconds: 180 timeoutSeconds: 30 manifests: configmap_bin: true configmap_etc: true daemonset: true job_image_repo_sync: true network_policy: false secret_elasticsearch: true secret_fluentd_env: true secret_kafka: false secret_registry: true service_fluentd: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: freezer/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 name: freezer description: OpenStack Freezer Backup and Restore Service platform type: application version: 2025.2.0 appVersion: v1.0.0 home: https://docs.openstack.org/freezer/latest icon: https://www.openstack.org/software/images/mascots/freezer.png sources: - https://opendev.org/openstack/freezer - https://opendev.org/openstack/freezer-api keywords: - openstack - backup - restore - helm maintainers: - name: OpenStack Helm Team email: openstack-helm@lists.openstack.org annotations: "helm.sh/hook-weight": "-5" dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: freezer/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: freezer/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex freezer-manage --config-file /etc/freezer/freezer.conf db sync ================================================ FILE: freezer/templates/bin/_freezer-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec freezer-api --config-file /etc/freezer/freezer.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: freezer/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: freezer-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} freezer-api.sh: | {{ tuple "bin/_freezer-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- end }} ================================================ FILE: freezer/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.freezer.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.freezer.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.freezer.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.freezer.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.freezer.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.freezer.keystone_authtoken "region_name" .Values.endpoints.identity.auth.freezer.region_name -}} {{- end -}} {{- if empty .Values.conf.freezer.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.freezer.keystone_authtoken "project_name" .Values.endpoints.identity.auth.freezer.project_name -}} {{- end -}} {{- if empty .Values.conf.freezer.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.freezer.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.freezer.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.freezer.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.freezer.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.freezer.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.freezer.keystone_authtoken.username -}} {{- $_ := set .Values.conf.freezer.keystone_authtoken "username" .Values.endpoints.identity.auth.freezer.username -}} {{- end -}} {{- if empty .Values.conf.freezer.keystone_authtoken.password -}} {{- $_ := set .Values.conf.freezer.keystone_authtoken "password" .Values.endpoints.identity.auth.freezer.password -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.freezer.database.connection)) (empty .Values.conf.freezer.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "freezer" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set .Values.conf.freezer.database "connection" -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: freezer-etc type: Opaque data: freezer.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.freezer | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} {{- end }} ... ================================================ FILE: freezer/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "probeTemplate" }} {{- $health_path := tuple "backup" "healthcheck" "internal" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} httpGet: scheme: {{ tuple "backup" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: {{ $health_path }} port: {{ tuple "backup" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_freezer_api := .Values.pod.mounts.freezer_api.freezer_api }} {{- $mounts_freezer_api_init := .Values.pod.mounts.freezer_api.init_container }} {{- $serviceAccountName := "freezer-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: freezer-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "freezer_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "freezer-api" "containerNames" (list "init" "freezer-api") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "freezer" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "freezer_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "freezer_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.freezer.enabled }} {{ tuple $envAll "freezer" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_freezer_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: freezer-api {{ tuple $envAll "freezer_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "freezer" "container" "freezer_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "freezer_api" "type" "readiness" "probeTemplate" (include "probeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "freezer_api" "type" "liveness" "probeTemplate" (include "probeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/freezer-api.sh - start env: {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/freezer/certs/ca.crt" {{- end }} lifecycle: preStop: exec: command: - /tmp/freezer-api.sh - stop ports: - name: freezer-api containerPort: {{ tuple "backup" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: oslo-lock-path mountPath: {{ .Values.conf.freezer.oslo_concurrency.lock_path }} - name: freezer-bin mountPath: /tmp/freezer-api.sh subPath: freezer-api.sh readOnly: true - name: freezer-etc mountPath: /etc/freezer/freezer.conf subPath: freezer.conf readOnly: true - name: freezer-etc mountPath: /etc/freezer/api-paste.ini subPath: api-paste.ini readOnly: true - name: freezer-etc mountPath: /etc/freezer/logging.conf subPath: logging.conf readOnly: true - name: freezer-etc mountPath: /etc/freezer/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_freezer_api.volumeMounts }}{{ toYaml $mounts_freezer_api.volumeMounts | indent 12 }}{{ end }} {{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.backup.api.internal "path" "/etc/freezer/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: oslo-lock-path emptyDir: {} - name: freezer-bin configMap: name: freezer-bin defaultMode: 0555 - name: freezer-etc secret: secretName: freezer-etc defaultMode: 0444 {{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.backup.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_freezer_api.volumes }}{{ toYaml $mounts_freezer_api.volumes | indent 8 }} {{ end }} {{- end }} ================================================ FILE: freezer/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: freezer/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "backup" "backendPort" "f-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: freezer/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "freezer" "keystoneUser" .Values.bootstrap.ks_user -}} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: freezer/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "freezer" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: freezer/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "freezer" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: freezer/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "freezer" "podVolMounts" .Values.pod.mounts.freezer_db_sync.freezer_db_sync.volumeMounts "podVols" .Values.pod.mounts.freezer_db_sync.freezer_db_sync.volumes -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: freezer/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "freezer" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: freezer/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksEndpointsJob := dict "envAll" . "serviceName" "freezer" "serviceTypes" ( tuple "backup" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksEndpointsJob "tlsSecret" .Values.secrets.tls.backup.api.internal -}} {{- end -}} {{- $_ := set $ksEndpointsJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $ksEndpointsJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksEndpointsJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: freezer/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "freezer" "serviceTypes" ( tuple "backup" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.backup.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: freezer/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "freezer" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.backup.api.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.freezer.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: freezer/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: freezer-api labels: {{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{- if .Values.pod.lifecycle.disruption_budget.api.min_available }} minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} {{- else }} maxUnavailable: {{ .Values.pod.lifecycle.disruption_budget.api.max_unavailable | default 1 }} {{- end }} selector: matchLabels: {{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ... ================================================ FILE: freezer/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "freezer" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: freezer/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "freezer" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: freezer/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "backup" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: f-api port: {{ tuple "backup" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: freezer/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "backup" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: freezer/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- release_uuid: null labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: pull_policy: IfNotPresent tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy freezer_db_sync: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy freezer_api: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 local_registry: active: false exclude: - dep_check - image_repo_sync endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default interface: internal freezer: role: admin,service region_name: RegionOne username: freezer password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 backup: name: freezer hosts: default: freezer-api internal: freezer-api public: freezer host_fqdn_override: default: null path: default: / healthcheck: /healthcheck scheme: default: http port: api: default: 9090 public: 80 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct secretNamespace: openstack freezer: username: freezer password: password secret: freezer-db-password secretNamespace: openstack hosts: default: mariadb host_fqdn_override: default: null path: /freezer scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, will be set to a random value # if not specified. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 secrets: identity: admin: freezer-keystone-admin freezer: freezer-keystone-user oslo_db: admin: freezer-db-admin freezer: freezer-db-user tls: backup: api: public: freezer-tls-public internal: freezer-tls-internal nginx: freezer-tls-nginx nginx_cluster: freezer-tls-nginx-cluster bootstrap: enabled: false ks_user: freezer script: "" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30090 dependencies: dynamic: common: local_image_registry: jobs: - freezer-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - freezer-db-sync - freezer-ks-user - freezer-ks-endpoints services: - endpoint: internal service: oslo_db - endpoint: internal service: identity bootstrap: services: - endpoint: internal service: identity - endpoint: internal service: backup db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - freezer-db-init services: - endpoint: internal service: oslo_db db_drop: services: - endpoint: internal service: oslo_db ks_user: services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_endpoints: jobs: - freezer-ks-service services: - endpoint: internal service: identity pod: probes: rpc_timeout: 60 rpc_retries: 2 api: freezer_api: liveness: enabled: True params: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 readiness: enabled: True params: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 security_context: freezer: pod: runAsUser: 42424 container: freezer_api: runAsUser: 0 affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: freezer: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule disruption_budget: api: min_available: 0 replicas: api: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 max_unavailable: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" mounts: freezer_api: init_container: null freezer_api: volumeMounts: volumes: freezer_bootstrap: init_container: null freezer_bootstrap: volumeMounts: volumes: freezer_db_sync: init_container: null freezer_db_sync: volumeMounts: volumes: conf: freezer: DEFAULT: debug: true log_config_append: /etc/freezer/logging.conf bind_host: 0.0.0.0 bind_port: 9090 paste_deploy: config_file: api-paste.ini database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" oslo_policy: policy_file: /etc/freezer/policy.yaml oslo_concurrency: lock_path: /var/lock storage: backend: sqlalchemy driver: sqlalchemy keystone_authtoken: auth_version: v3 auth_type: password # region_name: RegionOne # project_domain_name: service # project_name: service # user_domain_name: service # username: freezer # password: password # auth_url: http://keystone-api.openstack.svc.cluster.local:5000/v3 # auth_uri: http://keystone-api.openstack.svc.cluster.local:5000/v3 logging: loggers: keys: - root - freezer handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: "null" logger_freezer: level: INFO handlers: - stdout qualname: freezer logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" paste: app:api_versions: paste.app_factory: freezer_api.api.versions:api_versions app:appv1: paste.app_factory: freezer_api.service:freezer_appv1_factory app:appv2: paste.app_factory: freezer_api.service:freezer_appv2_factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:healthcheck: paste.filter_factory: oslo_middleware:Healthcheck.factory backends: disable_by_file disable_by_file_path: /etc/freezer/healthcheck_disable filter:context: paste.filter_factory: freezer_api.api.common.middleware:ContextMiddleware.factory filter:versionsNegotiator: paste.filter_factory: freezer_api.api.versions:VersionNegotiator.factory filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware:HTTPProxyToWSGI.factory pipeline:main: pipeline: healthcheck http_proxy_to_wsgi versionsNegotiator authtoken context backupapp pipeline:unauthenticated_freezer_api: pipeline: http_proxy_to_wsgi healthcheck freezer_app composite:backupapp: paste.composite_factory: freezer_api.service:root_app_factory /: api_versions /v1: appv1 /v2: appv2 tls: identity: false oslo_db: false manifests: certificates: false configmap_bin: true configmap_etc: true deployment_api: true ingress_api: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true pdb_api: true secret_db: true secret_keystone: true service_api: true service_ingress_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: glance/.helmignore ================================================ values_overrides ================================================ FILE: glance/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Glance name: glance version: 2025.2.0 home: https://docs.openstack.org/glance/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Glance/OpenStack_Project_Glance_vertical.png sources: - https://opendev.org/openstack/glance - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: glance/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cd /tmp/images {{ range .Values.bootstrap.structured.images }} openstack image show {{ .name | quote }} || \ { curl --fail -sSL -O {{ .source_url }}{{ .image_file }}; \ openstack image create {{ .name | quote }} \ {{ if .id -}} --id {{ .id }} {{ end -}} \ --min-disk {{ .min_disk }} \ --disk-format {{ .image_type }} \ --file {{ .image_file }} \ {{ if .properties -}} {{ range $key, $value := .properties }}--property {{$key}}={{$value}} {{ end }}{{ end -}} \ --container-format {{ .container_format | quote }} \ {{ if .private -}} --private {{- else -}} --public {{- end -}}; } {{ end }} {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: glance/templates/bin/_ceph-admin-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat > /etc/ceph/ceph.client.admin.keyring << EOF [client.admin] {{- if .Values.conf.ceph.admin_keyring }} key = {{ .Values.conf.ceph.admin_keyring }} {{- else }} key = $(cat /tmp/client-keyring) {{- end }} EOF exit 0 ================================================ FILE: glance/templates/bin/_ceph-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat > /etc/ceph/ceph.client.${RBD_STORE_USER}.keyring < /tmp/nginx.conf cat /tmp/nginx.conf nginx -t -c /tmp/nginx.conf exec nginx -c /tmp/nginx.conf } stop () { nginx -s stop } $COMMAND ================================================ FILE: glance/templates/bin/_storage-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x if [ "x$STORAGE_BACKEND" == "xrbd" ]; then SECRET=$(mktemp --suffix .yaml) KEYRING=$(mktemp --suffix .keyring) function cleanup { rm -f "${SECRET}" "${KEYRING}" } trap cleanup EXIT fi SCHEME={{ tuple "object_store" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} if [[ "$SCHEME" == "https" && -f /etc/ssl/certs/openstack-helm.crt ]]; then export CURL_CA_BUNDLE="/etc/ssl/certs/openstack-helm.crt" fi set -ex if [ "x$STORAGE_BACKEND" == "xpvc" ]; then echo "No action required." elif [ "x$STORAGE_BACKEND" == "xswift" ]; then : ${OS_INTERFACE:="internal"} OS_TOKEN="$(openstack token issue -f value -c id)" OS_PROJECT_ID="$(openstack project show service -f value -c id)" OS_SWIFT_ENDPOINT_PREFIX="$(openstack endpoint list --service swift --interface ${OS_INTERFACE} --region ${OS_REGION_NAME} -f value -c URL | awk -F '$' '{ print $1 }')" OS_SWIFT_SCOPED_ENDPOINT="${OS_SWIFT_ENDPOINT_PREFIX}${OS_PROJECT_ID}" curl --fail -i -X POST "${OS_SWIFT_SCOPED_ENDPOINT}" \ -H "X-Auth-Token: ${OS_TOKEN}" \ -H "X-Account-Meta-Temp-URL-Key: ${SWIFT_TMPURL_KEY}" elif [ "x$STORAGE_BACKEND" == "xrbd" ]; then ceph -s function ensure_pool () { ceph osd pool stats "$1" || ceph osd pool create "$1" "$2" local test_version if [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -ge 12 ]]; then ceph osd pool application enable $1 $3 fi ceph osd pool set "$1" size "${RBD_POOL_REPLICATION}" --yes-i-really-mean-it ceph osd pool set "$1" crush_rule "${RBD_POOL_CRUSH_RULE}" } ensure_pool "${RBD_POOL_NAME}" "${RBD_POOL_CHUNK_SIZE}" "${RBD_POOL_APP_NAME}" if USERINFO=$(ceph auth get "client.${RBD_POOL_USER}"); then echo "Cephx user client.${RBD_POOL_USER} already exist." echo "Update its cephx caps" ceph auth caps client.${RBD_POOL_USER} \ mon "profile rbd" \ osd "profile rbd pool=${RBD_POOL_NAME}" ceph auth get client.${RBD_POOL_USER} -o ${KEYRING} else #NOTE(JCL): Restrict Glance user to only what is needed. MON Read only and RBD access to the Glance Pool ceph auth get-or-create "client.${RBD_POOL_USER}" \ mon "profile rbd" \ osd "profile rbd pool=${RBD_POOL_NAME}" \ -o "${KEYRING}" fi ENCODED_KEYRING=$(sed -n 's/^[[:blank:]]*key[[:blank:]]\+=[[:blank:]]\(.*\)/\1/p' "${KEYRING}" | base64 -w0) cat > "${SECRET}" <= 0.1.0" ... ================================================ FILE: gnocchi/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: gnocchi/templates/bin/_ceph-admin-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat < /etc/ceph/ceph.client.admin.keyring [client.admin] {{- if .Values.conf.ceph.admin_keyring }} key = {{ .Values.conf.ceph.admin_keyring }} {{- else }} key = $(cat /tmp/client-keyring) {{- end }} EOF exit 0 ================================================ FILE: gnocchi/templates/bin/_ceph-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat < /etc/ceph/ceph.client.{{ .Values.conf.gnocchi.storage.ceph_username }}.keyring [client.{{ .Values.conf.gnocchi.storage.ceph_username }}] {{- if .Values.conf.gnocchi.storage.provided_keyring }} key = {{ .Values.conf.gnocchi.storage.provided_keyring }} {{- else }} key = $(cat /tmp/client-keyring) {{- end }} EOF exit 0 ================================================ FILE: gnocchi/templates/bin/_clean-secrets.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec kubectl delete secret \ --namespace ${NAMESPACE} \ --ignore-not-found=true \ ${RBD_POOL_SECRET} ================================================ FILE: gnocchi/templates/bin/_db-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp pgsql_superuser_cmd () { DB_COMMAND="$1" if [[ ! -z $2 ]]; then EXPORT PGDATABASE=$2 fi if [[ ! -z "${ROOT_DB_PASS}" ]]; then export PGPASSWORD="${ROOT_DB_PASS}" fi psql \ -h ${DB_FQDN} \ -p ${DB_PORT} \ -U ${ROOT_DB_USER} \ --command="${DB_COMMAND}" unset PGPASSWORD } if [[ ! -v ROOT_DB_CONNECTION ]]; then echo "environment variable ROOT_DB_CONNECTION not set" exit 1 else echo "Got DB root connection" fi if [[ -v OPENSTACK_CONFIG_FILE ]]; then if [[ ! -v OPENSTACK_CONFIG_DB_SECTION ]]; then echo "Environment variable OPENSTACK_CONFIG_DB_SECTION not set" exit 1 elif [[ ! -v OPENSTACK_CONFIG_DB_KEY ]]; then echo "Environment variable OPENSTACK_CONFIG_DB_KEY not set" exit 1 fi echo "Using ${OPENSTACK_CONFIG_FILE} as db config source" echo "Trying to load db config from ${OPENSTACK_CONFIG_DB_SECTION}:${OPENSTACK_CONFIG_DB_KEY}" DB_CONN=$(awk -v key=$OPENSTACK_CONFIG_DB_KEY "/^\[${OPENSTACK_CONFIG_DB_SECTION}\]/{f=1} f==1&&/^$OPENSTACK_CONFIG_DB_KEY/{print \$3;exit}" "${OPENSTACK_CONFIG_FILE}") echo "Found DB connection: $DB_CONN" elif [[ -v DB_CONNECTION ]]; then DB_CONN=${DB_CONNECTION} echo "Got config from DB_CONNECTION env var" else echo "Could not get dbconfig" exit 1 fi ROOT_DB_PROTO="$(echo $ROOT_DB_CONNECTION | grep '//' | sed -e's,^\(.*://\).*,\1,g')" ROOT_DB_URL="$(echo $ROOT_DB_CONNECTION | sed -e s,$ROOT_DB_PROTO,,g)" ROOT_DB_USER="$(echo $ROOT_DB_URL | grep @ | cut -d@ -f1 | cut -d: -f1)" ROOT_DB_PASS="$(echo $ROOT_DB_URL | grep @ | cut -d@ -f1 | cut -d: -f2)" DB_FQDN="$(echo $ROOT_DB_URL | sed -e s,$ROOT_DB_USER:$ROOT_DB_PASS@,,g | cut -d/ -f1 | cut -d: -f1)" DB_PORT="$(echo $ROOT_DB_URL | sed -e s,$ROOT_DB_USER:$ROOT_DB_PASS@,,g | cut -d/ -f1 | cut -d: -f2)" DB_NAME="$(echo $ROOT_DB_URL | sed -e s,$ROOT_DB_USER:$ROOT_DB_PASS@,,g | cut -d/ -f2 | cut -d? -f1)" DB_PROTO="$(echo $DB_CONN | grep '//' | sed -e's,^\(.*://\).*,\1,g')" DB_URL="$(echo $DB_CONN | sed -e s,$DB_PROTO,,g)" DB_USER="$( echo $DB_URL | grep @ | cut -d@ -f1 | cut -d: -f1)" DB_PASS="$( echo $DB_URL | grep @ | cut -d@ -f1 | cut -d: -f2)" #create db pgsql_superuser_cmd "SELECT 1 FROM pg_database WHERE datname = '$DB_NAME'" | grep -q 1 || pgsql_superuser_cmd "CREATE DATABASE $DB_NAME" #create db user pgsql_superuser_cmd "SELECT * FROM pg_roles WHERE rolname = '$DB_USER';" | tail -n +3 | head -n -2 | grep -q 1 || \ pgsql_superuser_cmd "CREATE ROLE ${DB_USER} LOGIN PASSWORD '$DB_PASS';" && pgsql_superuser_cmd "ALTER USER ${DB_USER} WITH SUPERUSER" #give permissions to user pgsql_superuser_cmd "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME to $DB_USER;" ================================================ FILE: gnocchi/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec gnocchi-upgrade ================================================ FILE: gnocchi/templates/bin/_gnocchi-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars fi exec apache2 -DFOREGROUND } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: gnocchi/templates/bin/_gnocchi-metricd.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec gnocchi-metricd \ --config-file /etc/gnocchi/gnocchi.conf ================================================ FILE: gnocchi/templates/bin/_gnocchi-resources-cleaner.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex echo "Purging the deleted resources with its associated metrics which have lived more than ${DELETED_RESOURCES_TTL}" gnocchi resource batch delete "ended_at < '-${DELETED_RESOURCES_TTL}'" exit 0 ================================================ FILE: gnocchi/templates/bin/_gnocchi-statsd.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec gnocchi-statsd \ --config-file /etc/gnocchi/gnocchi.conf ================================================ FILE: gnocchi/templates/bin/_gnocchi-test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp echo "Test: list archive policies" gnocchi archive-policy list echo "Test: create metric" gnocchi metric create --archive-policy-name low METRIC_UUID=$(gnocchi metric list -c id -f value | head -1) sleep 5 echo "Test: show metric" gnocchi metric show ${METRIC_UUID} sleep 5 echo "Test: add measures" gnocchi measures add -m 2017-06-27T12:00:00@31 \ -m 2017-06-27T12:03:27@20 \ -m 2017-06-27T12:06:51@41 \ ${METRIC_UUID} sleep 15 echo "Test: show measures" gnocchi measures show ${METRIC_UUID} gnocchi measures show --aggregation min ${METRIC_UUID} echo "Test: delete metric" gnocchi metric delete ${METRIC_UUID} RESOURCE_UUID={{ uuidv4 }} echo "Test: create resource type" gnocchi resource-type create --attribute name:string --attribute host:string test echo "Test: list resource types" gnocchi resource-type list echo "Test: create resource" gnocchi resource create --attribute name:test --attribute host:testnode1 --create-metric cpu:medium --create-metric memory:low --type test ${RESOURCE_UUID} echo "Test: show resource history" gnocchi resource history --format json --details ${RESOURCE_UUID} echo "Test: delete resource" gnocchi resource delete ${RESOURCE_UUID} echo "Test: delete resource type" gnocchi resource-type delete test exit 0 ================================================ FILE: gnocchi/templates/bin/_storage-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x SECRET=$(mktemp --suffix .yaml) KEYRING=$(mktemp --suffix .keyring) function cleanup { rm -f ${SECRET} ${KEYRING} } trap cleanup EXIT set -ex ceph -s function ensure_pool () { ceph osd pool stats $1 || ceph osd pool create $1 $2 local test_version=$(ceph tell osd.* version | egrep -c "nautilus|mimic|luminous" | xargs echo) if [[ ${test_version} -gt 0 ]]; then ceph osd pool application enable $1 $3 fi } ensure_pool ${RBD_POOL_NAME} ${RBD_POOL_CHUNK_SIZE} "gnocchi-metrics" if USERINFO=$(ceph auth get client.${RBD_POOL_USER}); then echo "Cephx user client.${RBD_POOL_USER} already exist." echo "Update its cephx caps" ceph auth caps client.${RBD_POOL_USER} \ mon "profile rbd" \ osd "profile rbd pool=${RBD_POOL_NAME}" \ mgr "allow r" ceph auth get client.${RBD_POOL_USER} -o ${KEYRING} else ceph auth get-or-create client.${RBD_POOL_USER} \ mon "profile rbd" \ osd "profile rbd pool=${RBD_POOL_NAME}" \ mgr "allow r" \ -o ${KEYRING} fi ENCODED_KEYRING=$(sed -n 's/^[[:blank:]]*key[[:blank:]]\+=[[:blank:]]\(.*\)/\1/p' ${KEYRING} | base64 -w0) cat > ${SECRET} < WSGIDaemonProcess gnocchi processes=1 threads=2 user=gnocchi group=gnocchi display-name=%{GROUP} WSGIProcessGroup gnocchi WSGIScriptAlias / "/var/lib/kolla/venv/lib/python2.7/site-packages/gnocchi/rest/app.wsgi" WSGIApplicationGroup %{GLOBAL} ErrorLog /dev/stderr SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded Require all granted ceph: monitors: [] admin_keyring: null override: append: enable_paste: True paste: pipeline:main: pipeline: gnocchi+auth composite:gnocchi+noauth: use: egg:Paste#urlmap /: gnocchiversions /v1: gnocchiv1+noauth composite:gnocchi+auth: use: egg:Paste#urlmap /: gnocchiversions /v1: gnocchiv1+auth pipeline:gnocchiv1+noauth: pipeline: gnocchiv1 pipeline:gnocchiv1+auth: pipeline: keystone_authtoken gnocchiv1 app:gnocchiversions: paste.app_factory: gnocchi.rest.app:app_factory root: gnocchi.rest.VersionsController app:gnocchiv1: paste.app_factory: gnocchi.rest.app:app_factory root: gnocchi.rest.V1Controller filter:keystone_authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory oslo_config_project: gnocchi policy: admin_or_creator: 'role:admin or project_id:%(created_by_project_id)s' resource_owner: 'project_id:%(project_id)s' metric_owner: 'project_id:%(resource.project_id)s' get status: 'role:admin' create resource: '' get resource: 'rule:admin_or_creator or rule:resource_owner' update resource: 'rule:admin_or_creator' delete resource: 'rule:admin_or_creator' delete resources: 'rule:admin_or_creator' list resource: 'rule:admin_or_creator or rule:resource_owner' search resource: 'rule:admin_or_creator or rule:resource_owner' create resource type: 'role:admin' delete resource type: 'role:admin' update resource type: 'role:admin' list resource type: '' get resource type: '' get archive policy: '' list archive policy: '' create archive policy: 'role:admin' update archive policy: 'role:admin' delete archive policy: 'role:admin' create archive policy rule: 'role:admin' get archive policy rule: '' list archive policy rule: '' delete archive policy rule: 'role:admin' create metric: '' delete metric: 'rule:admin_or_creator' get metric: 'rule:admin_or_creator or rule:metric_owner' search metric: 'rule:admin_or_creator or rule:metric_owner' list metric: '' list all metric: 'role:admin' get measures: 'rule:admin_or_creator or rule:metric_owner' post measures: 'rule:admin_or_creator' gnocchi: DEFAULT: debug: false token: provider: uuid api: auth_mode: keystone # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. port: null statsd: # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. port: null metricd: workers: 1 database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" storage: driver: ceph ceph_pool: gnocchi.metrics ceph_username: gnocchi ceph_keyring: /etc/ceph/ceph.client.gnocchi.keyring ceph_conffile: /etc/ceph/ceph.conf file_basepath: /var/lib/gnocchi provided_keyring: null indexer: driver: postgresql # -- Indexer connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db (or oslo_db_postgresql). Set to null to ## disable auto-generation. url: "" keystone_authtoken: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT oslo_concurrency: lock_path: /var/lock ceph_client: configmap: ceph-etc user_secret_name: pvc-ceph-client-key secrets: identity: admin: gnocchi-keystone-admin gnocchi: gnocchi-keystone-user oslo_db: admin: gnocchi-db-admin gnocchi: gnocchi-db-user oslo_db_indexer: admin: gnocchi-db-indexer-admin gnocchi: gnocchi-db-indexer-user rbd: gnocchi-rbd-keyring tls: metric: api: public: gnocchi-tls-public bootstrap: enabled: false ks_user: gnocchi script: | openstack token issue # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 identity: name: keystone auth: admin: username: "admin" user_domain_name: "default" password: "password" project_name: "admin" project_domain_name: "default" region_name: "RegionOne" os_auth_type: "password" os_tenant_name: "admin" gnocchi: username: "gnocchi" role: "admin" password: "password" project_name: "service" region_name: "RegionOne" os_auth_type: "password" os_tenant_name: "service" user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 metric: name: gnocchi hosts: default: gnocchi-api public: gnocchi host_fqdn_override: default: null # NOTE: this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: 'http' port: api: default: 8041 public: 80 metric_statsd: name: gnocchi-statsd hosts: default: gnocchi-statsd host_fqdn_override: default: null path: default: null scheme: default: null port: statsd: default: 8125 oslo_db_postgresql: auth: admin: username: postgres password: password gnocchi: username: gnocchi password: password hosts: default: postgresql host_fqdn_override: default: null path: /gnocchi scheme: postgresql port: postgresql: default: 5432 oslo_db: auth: admin: username: root password: password gnocchi: username: gnocchi password: password hosts: default: mariadb host_fqdn_override: default: null path: /gnocchi scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 manifests: configmap_bin: true configmap_etc: true cron_job_resources_cleaner: true daemonset_metricd: true daemonset_statsd: true deployment_api: true ingress_api: true job_bootstrap: true job_clean: true job_db_drop: false job_db_init_indexer: true job_db_init: true job_image_repo_sync: true secret_db_indexer: true job_db_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_storage_init: true pdb_api: true pod_gnocchi_test: true secret_db: true secret_keystone: true secret_ingress_tls: true service_api: true service_ingress_api: true service_statsd: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: grafana/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v12.4.2 description: OpenStack-Helm Grafana name: grafana version: 2025.2.0 home: https://grafana.com/ sources: - https://github.com/grafana/grafana - https://opendev.org/openstack/openstack-helm-addons maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: grafana/templates/bin/_db-session-sync.py.tpl ================================================ #!/usr/bin/env python # Creates db and user for an OpenStack Service: # Set ROOT_DB_CONNECTION and DB_CONNECTION environment variables to contain # SQLAlchemy strings for the root connection to the database and the one you # wish the service to use. Alternatively, you can use an ini formatted config # at the location specified by OPENSTACK_CONFIG_FILE, and extract the string # from the key OPENSTACK_CONFIG_DB_KEY, in the section specified by # OPENSTACK_CONFIG_DB_SECTION. import os import sys import logging from sqlalchemy import create_engine, text # Create logger, console handler and formatter logger = logging.getLogger('OpenStack-Helm DB Init') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(filename)s - %(lineno)d - %(funcName)s - %(message)s') # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) # Get the connection string for the service db if "DB_CONNECTION" in os.environ: user_db_conn = os.environ['DB_CONNECTION'] logger.info('Got config from DB_CONNECTION env var') else: logger.critical('Could not get db config, either from config file or env var') sys.exit(1) # User DB engine try: user_engine = create_engine(user_db_conn) # Get our user data out of the user_engine database = user_engine.url.database user = user_engine.url.username password = user_engine.url.password host = user_engine.url.host port = user_engine.url.port logger.info('Got user db config') except: logger.critical('Could not get user database config') raise # Test connection try: connection = user_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1}/{2} as {3}".format( host, port, database, user)) except: logger.critical('Could not connect to database as user') raise # Create Table try: with user_engine.connect() as conn: conn.execute(text('''CREATE TABLE IF NOT EXISTS `session` ( `key` CHAR(16) NOT NULL, `data` BLOB, `expiry` INT(11) UNSIGNED NOT NULL, PRIMARY KEY (`key`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;''')) try: conn.commit() except AttributeError: pass logger.info('Created table for session cache') except Exception as e: logger.critical(f'Could not create table for session cache: {e}') raise ================================================ FILE: grafana/templates/bin/_grafana.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -exo pipefail COMMAND="${@:-start}" PORT={{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} PIDFILE=/tmp/pid DB_HOST={{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} DB_PORT={{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} MYSQL_PARAMS=" \ --defaults-file=/tmp/my.cnf \ --host=${DB_HOST} \ --port=${DB_PORT} {{- if .Values.manifests.certificates }} --ssl-verify-server-cert=false \ --ssl-ca=/etc/mysql/certs/ca.crt \ --ssl-key=/etc/mysql/certs/tls.key \ --ssl-cert=/etc/mysql/certs/tls.crt \ {{- end }} " function start () { exec /usr/share/grafana/bin/grafana server -homepath=/usr/share/grafana -config=/etc/grafana/grafana.ini --pidfile="$PIDFILE" } function run_migrator () { BACKUP_FILE=$(mktemp) LOG_FILE=$(mktemp) STOP_FLAG=$(mktemp) echo "Making sure the database is reachable...." set +e until mariadb ${MYSQL_PARAMS} grafana -e "select 1;" do echo \"Database ${DB_HOST} is not reachable. Sleeping for 10 seconds...\" sleep 10 done set -e echo "Preparing initial database backup..." mariadb-dump ${MYSQL_PARAMS} --add-drop-table --quote-names grafana > "${BACKUP_FILE}" echo "Backup SQL file ${BACKUP_FILE}" ls -lh "${BACKUP_FILE}" { # this is the background process that re-starts Grafana server # in order to process grafana database migration set +e while true do start 2>&1 | tee "$LOG_FILE" sleep 10 echo "Restarting Grafana server..." stop echo "Emptying log file..." echo > "$LOG_FILE" while [ -f ${STOP_FLAG} ] do echo "Lock file still exists - ${STOP_FLAG}..." ls -la ${STOP_FLAG} echo "Waiting for lock file to get removed..." sleep 5 done echo "Lock file is removed, proceeding with grafana re-start.." done set -e } & until cat "${LOG_FILE}" | grep -E "migrations completed" do echo "The migrations are not completed yet..." if cat "${LOG_FILE}" | grep -E "migration failed" then echo "Locking server restart by placing a flag file ${STOP_FLAG} .." touch "${STOP_FLAG}" echo "Migration failure has been detected. Stopping Grafana server..." set +e stop set -e echo "Making sure the database is reachable...." set +e until mariadb ${MYSQL_PARAMS} grafana -e "select 1;" do echo \"Database ${DB_HOST} is not reachable. Sleeping for 10 seconds...\" sleep 10 done set -e echo "Cleaning the database..." TABLES=$( mariadb ${MYSQL_PARAMS} grafana -e "show tables\G;" | grep Tables | cut -d " " -f 2 ) for TABLE in ${TABLES} do echo ${TABLE} mariadb ${MYSQL_PARAMS} grafana -e "drop table ${TABLE};" done echo "Restoring the database backup..." mariadb ${MYSQL_PARAMS} grafana < "${BACKUP_FILE}" echo "Removing lock file ${STOP_FLAG} ..." rm -f "${STOP_FLAG}" echo "${STOP_FLAG} has been removed" fi sleep 10 done stop rm -f "${BACKUP_FILE}" } function stop () { if [ -f "$PIDFILE" ]; then echo -e "Found pidfile, killing running Grafana server" kill -9 `cat $PIDFILE` rm $PIDFILE else kill -TERM 1 fi } $COMMAND ================================================ FILE: grafana/templates/bin/_selenium-tests.py.tpl ================================================ #!/usr/bin/env python3 {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} import logging import os import sys from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options {{- if .Values.selenium_v4 }} from selenium.webdriver.chrome.service import Service {{- end }} from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import NoSuchElementException # Create logger, console handler and formatter logger = logging.getLogger('Grafana Selenium Tests') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) def get_variable(env_var): if env_var in os.environ: logger.info('Found "{}"'.format(env_var)) return os.environ[env_var] else: logger.critical('Variable "{}" is not defined!'.format(env_var)) sys.exit(1) username = get_variable('GRAFANA_USER') password = get_variable('GRAFANA_PASSWORD') grafana_uri = get_variable('GRAFANA_URI') chrome_driver = '/etc/selenium/chromedriver' options = Options() options.add_argument('--headless=new') options.add_argument('--no-sandbox') options.add_argument('--window-size=1920x1080') {{- if .Values.selenium_v4 }} service = Service(executable_path=chrome_driver) browser = webdriver.Chrome(service=service, options=options) {{- else }} browser = webdriver.Chrome(chrome_driver, chrome_options=options) {{- end }} login_url = grafana_uri.rstrip('/') + '/login' logger.info("Attempting to open Grafana login page at {}".format(login_url)) try: browser.get(login_url) WebDriverWait(browser, 30).until( EC.presence_of_element_located((By.NAME, 'user')) ) WebDriverWait(browser, 30).until( EC.presence_of_element_located((By.NAME, 'password')) ) logger.info('Grafana login form is ready') except TimeoutException: logger.critical('Timed out waiting for Grafana login form') browser.quit() sys.exit(1) logger.info("Attempting to log into Grafana dashboard") try: {{- if .Values.selenium_v4 }} browser.find_element(By.NAME, 'user').send_keys(username) browser.find_element(By.NAME, 'password').send_keys(password) browser.find_element(By.CSS_SELECTOR, '[type="submit"]').click() {{- else }} browser.find_element_by_name('user').send_keys(username) browser.find_element_by_name('password').send_keys(password) browser.find_element_by_css_selector('[type="submit"]').click() {{- end }} logger.info("Successfully logged in to Grafana") except NoSuchElementException: logger.error("Failed to log in to Grafana") browser.quit() sys.exit(1) browser.quit() ================================================ FILE: grafana/templates/bin/_set-admin-password.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} echo "Attempting to update Grafana admin user password" grafana-cli --homepath "/usr/share/grafana" --config /etc/grafana/grafana.ini admin reset-admin-password ${GF_SECURITY_ADMIN_PASSWORD} if [ "$?" == 1 ]; then echo "The Grafana admin user does not exist yet, so no need to update password" exit 0; else exit 0; fi ================================================ FILE: grafana/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: grafana-bin data: db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-session-sync.py: | {{ tuple "bin/_db-session-sync.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} grafana.sh: | {{ tuple "bin/_grafana.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} selenium-tests.py: | {{ tuple "bin/_selenium-tests.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} set-admin-password.sh: | {{ tuple "bin/_set-admin-password.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: grafana/templates/configmap-dashboards.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_dashboards }} {{ range $group, $dashboards := .Values.conf.dashboards }} --- apiVersion: v1 kind: ConfigMap metadata: name: grafana-dashboards-{{$group}} data: {{ range $key, $value := $dashboards }} {{$key}}.json: {{ $value | toJson }} {{ end }} {{ end }} {{- end }} ================================================ FILE: grafana/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if and (not (kindIs "invalid" .Values.conf.grafana.database.url)) (empty .Values.conf.grafana.database.url) (not (eq .Values.conf.grafana.database.type "sqlite3") ) -}} {{- $url := tuple "oslo_db" "internal" "user" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | replace "mysql+pymysql://" "mysql://" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8" $url ) | set .Values.conf.grafana.database "url" -}} {{- $_ := tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.endpoint_host_lookup" | set .Values.conf.grafana.database "server_cert_name" -}} {{- else -}} {{- $_ := set .Values.conf.grafana.database "url" $url -}} {{- end -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: grafana-etc type: Opaque data: dashboards.yaml: {{ toYaml .Values.conf.provisioning.dashboards | b64enc }} grafana.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.grafana | b64enc }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.provisioning.datasources.template "key" "datasources.yaml" "format" "Secret") | indent 2 }} {{ if not (empty .Values.conf.ldap) }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.ldap.template "key" "ldap.toml" "format" "Secret") | indent 2 }} {{ end }} {{- end }} ================================================ FILE: grafana/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $mounts_grafana := .Values.pod.mounts.grafana.grafana }} {{- $serviceAccountName := "grafana" }} {{ tuple $envAll "grafana" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: grafana annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "grafana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.grafana }} selector: matchLabels: {{ tuple $envAll "grafana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "grafana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "grafana" "containerNames" (list "grafana" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "dashboard" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "grafana" "dashboard" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.grafana.node_selector_key }}: {{ .Values.labels.grafana.node_selector_value | quote }} initContainers: {{ tuple $envAll "grafana" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if and .Values.conf.grafana.image_rendering_sidecar.enabled .Values.conf.grafana.image_rendering_sidecar.k8s_sidecar_feature_enabled }} - name: grafana-image-renderer {{ tuple $envAll "grafana_image_renderer" | include "helm-toolkit.snippets.image" | indent 10 }} restartPolicy: Always ports: - containerPort: {{ tuple "grafana" "image_rendering" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "grafana" "image_rendering" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 15 periodSeconds: 10 {{- end }} containers: {{- if and .Values.conf.grafana.image_rendering_sidecar.enabled (not .Values.conf.grafana.image_rendering_sidecar.k8s_sidecar_feature_enabled) }} - name: grafana-image-renderer {{ tuple $envAll "grafana_image_renderer" | include "helm-toolkit.snippets.image" | indent 10 }} ports: - containerPort: {{ tuple "grafana" "image_rendering" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "grafana" "image_rendering" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 15 periodSeconds: 10 {{- end }} - name: grafana {{ tuple $envAll "grafana" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.grafana | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "dashboard" "container" "grafana" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/grafana.sh - start ports: - name: dashboard containerPort: {{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: path: /login port: {{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 30 timeoutSeconds: 30 env: - name: GF_SECURITY_ADMIN_USER valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_USERNAME - name: GF_SECURITY_ADMIN_PASSWORD valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_PASSWORD - name: PROMETHEUS_URL value: {{ tuple "monitoring" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} {{- if .Values.manifests.certificates }} - name: CACERT valueFrom: secretKeyRef: key: ca.crt name: prometheus-tls-api {{- end }} {{- if .Values.conf.grafana.image_rendering_sidecar.enabled }} - name: GF_RENDERING_SERVER_URL value: "http://localhost:{{ tuple "grafana" "image_rendering" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/render" - name: GF_RENDERING_CALLBACK_URL value: "http://localhost:{{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" {{- end }} {{- if .Values.pod.env.grafana }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.grafana | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-grafana mountPath: /etc/grafana - name: pod-screenshots-grafana mountPath: /var/lib/grafana/png - name: pod-pdf-grafana mountPath: /var/lib/grafana/pdf - name: pod-dashboards-grafana mountPath: /etc/grafana/dashboards - name: pod-provisioning-grafana mountPath: {{ .Values.conf.grafana.paths.provisioning }} - name: pod-alerting-grafana mountPath: {{ .Values.conf.grafana.paths.alerting }} - name: pod-csv-grafana mountPath: {{ .Values.conf.grafana.paths.csv }} - name: grafana-bin mountPath: /tmp/grafana.sh subPath: grafana.sh readOnly: true - name: grafana-etc mountPath: {{ .Values.conf.grafana.paths.provisioning }}/dashboards/dashboards.yaml subPath: dashboards.yaml - name: grafana-etc mountPath: {{ .Values.conf.grafana.paths.provisioning }}/datasources/datasources.yaml subPath: datasources.yaml - name: grafana-etc mountPath: /etc/grafana/grafana.ini subPath: grafana.ini - name: grafana-etc mountPath: /etc/grafana/ldap.toml subPath: ldap.toml - name: data mountPath: /var/lib/grafana/data - name: unified-storage mountPath: {{ .Values.conf.grafana.unified_storage.index_path }} {{- range $group, $dashboards := .Values.conf.dashboards }} {{- range $key, $value := $dashboards }} - name: grafana-dashboards-{{$group}} mountPath: /etc/grafana/dashboards/{{$key}}.json subPath: {{$key}}.json {{- end }} {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_grafana.volumeMounts }}{{ toYaml $mounts_grafana.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-grafana emptyDir: {} - name: pod-screenshots-grafana emptyDir: {} - name: pod-dashboards-grafana emptyDir: {} - name: pod-provisioning-grafana emptyDir: {} - name: pod-alerting-grafana emptyDir: {} - name: pod-csv-grafana emptyDir: {} - name: pod-pdf-grafana emptyDir: {} - name: grafana-bin configMap: name: grafana-bin defaultMode: 0555 - name: grafana-etc secret: secretName: grafana-etc defaultMode: 0444 {{- range $group, $dashboards := .Values.conf.dashboards }} - name: grafana-dashboards-{{$group}} configMap: name: grafana-dashboards-{{$group}} defaultMode: 0555 {{- end }} - name: data emptyDir: {} - name: unified-storage emptyDir: {} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_grafana.volumes }}{{ toYaml $mounts_grafana.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: grafana/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: grafana/templates/ingress-grafana.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.grafana.ingress.public }} {{- $envAll := . -}} {{- $ingressOpts := dict "envAll" $envAll "backendService" "grafana" "backendServiceType" "grafana" "backendPort" "dashboard" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.grafana.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: grafana/templates/job-db-init-session.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_init_session }} {{- $envAll := . }} {{- $serviceAccountName := "grafana-db-init-session" }} {{ tuple $envAll "db_init_session" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: grafana-db-init-session labels: {{ tuple $envAll "grafana" "db-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "grafana" "db-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "grafana-db-init-session" "containerNames" (list "grafana-db-init-session" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "db_init" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "db_init_session" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: grafana-db-init-session {{ tuple $envAll "db_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_init_session | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "db_init" "container" "grafana_db_init_session" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: ROOT_DB_CONNECTION valueFrom: secretKeyRef: name: {{ .Values.secrets.oslo_db_session.admin }} key: DB_CONNECTION - name: DB_CONNECTION valueFrom: secretKeyRef: name: {{ .Values.secrets.oslo_db_session.user }} key: DB_CONNECTION {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} command: - /tmp/db-init.py volumeMounts: - name: pod-tmp mountPath: /tmp - name: grafana-bin mountPath: /tmp/db-init.py subPath: db-init.py readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db_session.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: grafana-bin configMap: name: grafana-bin defaultMode: 0555 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db_session.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: grafana/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_init }} {{- $envAll := . }} {{- $serviceAccountName := "grafana-db-init" }} {{ tuple $envAll "db_init" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: grafana-db-init labels: {{ tuple $envAll "grafana" "db-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "grafana" "db-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "grafana-db-init" "containerNames" (list "grafana-db-init" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "db_init" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "db_init" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: grafana-db-init {{ tuple $envAll "db_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_init | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "db_init" "container" "grafana_db_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: ROOT_DB_CONNECTION valueFrom: secretKeyRef: name: {{ .Values.secrets.oslo_db.admin }} key: DB_CONNECTION - name: DB_CONNECTION valueFrom: secretKeyRef: name: {{ .Values.secrets.oslo_db.user }} key: DB_CONNECTION {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} command: - /tmp/db-init.py volumeMounts: - name: pod-tmp mountPath: /tmp - name: grafana-bin mountPath: /tmp/db-init.py subPath: db-init.py readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: grafana-bin configMap: name: grafana-bin defaultMode: 0555 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: grafana/templates/job-db-session-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_session_sync }} {{- $envAll := . }} {{- $serviceAccountName := "grafana-db-session-sync" }} {{ tuple $envAll "db_session_sync" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: grafana-db-session-sync labels: {{ tuple $envAll "grafana" "db-session-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "grafana" "db-session-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "grafana-db-session-sync" "containerNames" (list "grafana-db-session-sync" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "db_session_sync" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "db_session_sync" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: grafana-db-session-sync {{ tuple $envAll "grafana_db_session_sync" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_session_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "db_session_sync" "container" "grafana_db_session_sync" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: DB_CONNECTION valueFrom: secretKeyRef: name: {{ .Values.secrets.oslo_db_session.user }} key: DB_CONNECTION {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} command: - /tmp/db-session-sync.py volumeMounts: - name: pod-tmp mountPath: /tmp - name: grafana-bin mountPath: /tmp/db-session-sync.py subPath: db-session-sync.py readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db_session.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: grafana-bin configMap: name: grafana-bin defaultMode: 0555 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db_session.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: grafana/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "grafana" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: grafana/templates/job-run-migrator.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_run_migrator }} {{- $envAll := . }} {{- $mounts_grafana := .Values.pod.mounts.grafana.grafana }} {{- $serviceAccountName := "grafana-run-migrator" }} {{ tuple $envAll "run_migrator" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: ConfigMap metadata: name: prepare-grafana-migrator annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} data: prepare-grafana-migrator.sh: | #!/bin/bash set -xe cp -av /usr/share/grafana/* /usr/share/grafana-prepare/ exit 0 --- apiVersion: batch/v1 kind: Job metadata: name: grafana-run-migrator annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "grafana" "run-migrator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "grafana" "run-migrator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "grafana-run-migrator" "containerNames" (list "prepare-grafana-migrator" "grafana-run-migrator" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "run_migrator" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "run_migrator" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: prepare-grafana-migrator {{ tuple $envAll "grafana" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "run_migrator" "container" "prepare_grafana_migrator" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/prepare-grafana-migrator.sh resources: {} volumeMounts: - name: pod-tmp mountPath: /tmp - name: grafana-binary-image mountPath: /usr/share/grafana-prepare - name: prepare-grafana-migrator mountPath: /tmp/prepare-grafana-migrator.sh readOnly: true subPath: prepare-grafana-migrator.sh containers: - name: grafana-run-migrator {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.run_migrator | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "run_migrator" "container" "grafana_run_migrator" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/grafana.sh - run_migrator ports: - name: dashboard containerPort: {{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} # readinessProbe: # httpGet: # path: /login # port: {{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} # initialDelaySeconds: 30 # timeoutSeconds: 30 env: - name: GF_SECURITY_ADMIN_USER valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_USERNAME - name: GF_SECURITY_ADMIN_PASSWORD valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_PASSWORD - name: PROMETHEUS_URL value: {{ tuple "monitoring" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} {{- if .Values.manifests.certificates }} - name: CACERT valueFrom: secretKeyRef: key: ca.crt name: prometheus-tls-api {{- end }} {{- if .Values.pod.env.grafana }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.grafana | indent 12 }} {{- end }} {{- if .Values.pod.env.grafana_run_migrator }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.grafana_run_migrator | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-etc-grafana mountPath: /etc/grafana - name: pod-screenshots-grafana mountPath: /var/lib/grafana/png - name: pod-pdf-grafana mountPath: /var/lib/grafana/pdf - name: pod-dashboards-grafana mountPath: /etc/grafana/dashboards - name: pod-provisioning-grafana mountPath: {{ .Values.conf.grafana.paths.provisioning }} - name: pod-alerting-grafana mountPath: {{ .Values.conf.grafana.paths.alerting }} - name: pod-csv-grafana mountPath: {{ .Values.conf.grafana.paths.csv }} - name: grafana-binary-image mountPath: /usr/share/grafana - name: grafana-bin mountPath: /tmp/grafana.sh subPath: grafana.sh readOnly: true - name: grafana-etc mountPath: {{ .Values.conf.grafana.paths.provisioning }}/dashboards/dashboards.yaml subPath: dashboards.yaml - name: grafana-etc mountPath: {{ .Values.conf.grafana.paths.provisioning }}/datasources/datasources.yaml subPath: datasources.yaml - name: grafana-etc mountPath: /etc/grafana/grafana.ini subPath: grafana.ini - name: grafana-etc mountPath: /etc/grafana/ldap.toml subPath: ldap.toml - name: grafana-db mountPath: /tmp/my.cnf subPath: my.cnf - name: data mountPath: /var/lib/grafana/data - name: unified-storage mountPath: {{ .Values.conf.grafana.unified_storage.index_path }} {{- range $group, $dashboards := .Values.conf.dashboards }} {{- range $key, $value := $dashboards }} - name: grafana-dashboards-{{$group}} mountPath: /etc/grafana/dashboards/{{$key}}.json subPath: {{$key}}.json {{- end }} {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_grafana.volumeMounts }}{{ toYaml $mounts_grafana.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-grafana emptyDir: {} - name: pod-screenshots-grafana emptyDir: {} - name: pod-dashboards-grafana emptyDir: {} - name: pod-provisioning-grafana emptyDir: {} - name: pod-alerting-grafana emptyDir: {} - name: pod-csv-grafana emptyDir: {} - name: pod-pdf-grafana emptyDir: {} - name: grafana-binary-image emptyDir: {} - name: grafana-bin configMap: name: grafana-bin defaultMode: 0555 - name: grafana-etc secret: secretName: grafana-etc defaultMode: 0444 - name: grafana-db secret: secretName: grafana-db defaultMode: 0444 {{- range $group, $dashboards := .Values.conf.dashboards }} - name: grafana-dashboards-{{$group}} configMap: name: grafana-dashboards-{{$group}} defaultMode: 0555 {{- end }} - name: data emptyDir: {} - name: unified-storage emptyDir: {} - name: prepare-grafana-migrator configMap: defaultMode: 0555 name: prepare-grafana-migrator {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_grafana.volumes }}{{ toYaml $mounts_grafana.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: grafana/templates/job-set-admin-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_set_admin_user }} {{- $envAll := . }} {{- $serviceAccountName := "grafana-set-admin-user" }} {{ tuple $envAll "set_admin_user" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: grafana-set-admin-user labels: {{ tuple $envAll "grafana" "set-admin-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "grafana" "set-admin-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "grafana-set-admin-user" "containerNames" (list "grafana-set-admin-password" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "set_admin_user" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "set_admin_user" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: grafana-set-admin-password {{ tuple $envAll "grafana" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.set_admin_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "set_admin_user" "container" "grafana_set_admin_password" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/set-admin-password.sh env: - name: GF_SECURITY_ADMIN_USER valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_USERNAME - name: GF_SECURITY_ADMIN_PASSWORD valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: grafana-etc mountPath: /etc/grafana/grafana.ini subPath: grafana.ini - name: grafana-bin mountPath: /tmp/set-admin-password.sh subPath: set-admin-password.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-grafana emptyDir: {} - name: grafana-bin configMap: name: grafana-bin defaultMode: 0555 - name: grafana-etc secret: secretName: grafana-etc defaultMode: 0444 {{- end }} ================================================ FILE: grafana/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "grafana" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: grafana/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.helm_tests }} {{- $dashboardCount := len .Values.conf.dashboards }} {{- $envAll := . }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.Release.Name}}-test" labels: {{ tuple $envAll "grafana" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "grafana-test" "containerNames" (list "init" "grafana-selenium-tests") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: grafana-selenium-tests {{ tuple $envAll "selenium_tests" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "helm_tests" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/selenium-tests.py env: - name: GRAFANA_USER valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_USERNAME - name: GRAFANA_PASSWORD valueFrom: secretKeyRef: name: grafana-admin-creds key: GRAFANA_ADMIN_PASSWORD - name: GRAFANA_URI value: {{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} - name: CHROME_CONFIG_HOME value: /tmp/google-chrome - name: XDG_CONFIG_HOME value: /tmp/google-chrome - name: XDG_CACHE_HOME value: /tmp/google-chrome volumeMounts: - name: pod-tmp mountPath: /tmp - name: grafana-bin mountPath: /tmp/selenium-tests.py subPath: selenium-tests.py readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: grafana-bin configMap: name: grafana-bin defaultMode: 0555 {{- end }} ================================================ FILE: grafana/templates/secret-admin-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_admin_creds }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: grafana-admin-creds type: Opaque data: GRAFANA_ADMIN_PASSWORD: {{ .Values.endpoints.grafana.auth.admin.password | b64enc }} GRAFANA_ADMIN_USERNAME: {{ .Values.endpoints.grafana.auth.admin.username | b64enc }} {{- end }} ================================================ FILE: grafana/templates/secret-db-session.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db_session }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "user" }} {{- $secretName := index $envAll.Values.secrets.oslo_db_session $userClass }} {{- $connection := tuple "oslo_db_session" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: grafana/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "user" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} --- apiVersion: v1 kind: Secret metadata: name: grafana-db type: Opaque data: my.cnf: {{ tuple "secrets/_my.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} {{- end }} ================================================ FILE: grafana/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "grafana" "backendService" "grafana" ) }} {{- end }} ================================================ FILE: grafana/templates/secret-prom-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_prom_creds }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.prometheus.user }} {{- $prometheus_user := .Values.endpoints.monitoring.auth.user.username }} {{- $prometheus_password := .Values.endpoints.monitoring.auth.user.password }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: PROMETHEUS_USERNAME: {{ .Values.endpoints.monitoring.auth.user.username | b64enc }} PROMETHEUS_PASSWORD: {{ .Values.endpoints.monitoring.auth.user.password | b64enc }} {{- end }} ================================================ FILE: grafana/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: grafana/templates/secrets/_my.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.admin.username }} password = {{ .Values.endpoints.oslo_db.auth.admin.password }} ================================================ FILE: grafana/templates/service-ingress.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.grafana.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "grafana" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: grafana/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "grafana" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: dashboard port: {{ tuple "grafana" "internal" "grafana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.grafana.node_port.enabled }} nodePort: {{ .Values.network.grafana.node_port.port }} {{ end }} selector: {{ tuple $envAll "grafana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.grafana.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: grafana/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for grafana # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: grafana: docker.io/grafana/grafana:12.4.2 mariadb: quay.io/airshipit/mariadb:latest-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble grafana_db_session_sync: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble selenium_tests: quay.io/airshipit/osh-selenium:latest-ubuntu_noble image_repo_sync: quay.io/airshipit/docker:27.5.0 grafana_image_renderer: docker.io/grafana/grafana-image-renderer:5.7.3 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync # Use selenium v4 syntax selenium_v4: true labels: grafana: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled pod: env: grafana: null grafana_run_migrator: GF_DEFAULT_FORCE_MIGRATION: false security_context: dashboard: pod: runAsUser: 472 container: grafana: allowPrivilegeEscalation: false readOnlyRootFilesystem: true db_init: pod: runAsUser: 472 container: grafana_db_init_session: allowPrivilegeEscalation: false readOnlyRootFilesystem: true grafana_db_init: allowPrivilegeEscalation: false readOnlyRootFilesystem: true db_session_sync: pod: runAsUser: 472 container: grafana_db_session_sync: allowPrivilegeEscalation: false readOnlyRootFilesystem: true set_admin_user: pod: runAsUser: 472 container: grafana_set_admin_password: allowPrivilegeEscalation: false readOnlyRootFilesystem: true run_migrator: pod: runAsUser: 472 container: prepare_grafana_migrator: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: true grafana_run_migrator: runAsUser: 65534 allowPrivilegeEscalation: false readOnlyRootFilesystem: true grafana_set_admin_password: allowPrivilegeEscalation: false readOnlyRootFilesystem: true test: pod: runAsUser: 0 container: helm_tests: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: grafana: init_container: null grafana: replicas: grafana: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: grafana: timeout: 600 resources: enabled: false jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init_session: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" grafana_db_session_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" set_admin_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" run_migrator: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" grafana: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false grafana: username: grafana password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null oslo_db: namespace: null auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct user: username: grafana password: password hosts: default: mariadb host_fqdn_override: default: null path: /grafana scheme: mysql+pymysql port: mysql: default: 3306 oslo_db_session: namespace: null auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct user: username: grafana_session password: password hosts: default: mariadb host_fqdn_override: default: null path: /grafana_session scheme: mysql+pymysql port: mysql: default: 3306 grafana: name: grafana namespace: null auth: admin: username: admin password: password hosts: default: grafana-dashboard public: grafana host_fqdn_override: default: null path: default: null scheme: default: http port: grafana: default: 3000 public: 80 image_rendering: 8081 monitoring: name: prometheus namespace: null auth: user: username: admin password: changeme hosts: default: prom-metrics public: prometheus host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 80 public: 80 ldap: hosts: default: ldap auth: admin: bind_dn: "cn=admin,dc=cluster,dc=local" password: password host_fqdn_override: default: null path: default: "ou=People,dc=cluster,dc=local" scheme: default: ldap port: ldap: default: 389 dependencies: dynamic: common: local_image_registry: jobs: - grafana-image-repo-sync services: - endpoint: node service: local_image_registry static: db_init: services: - endpoint: internal service: oslo_db db_init_session: services: - endpoint: internal service: oslo_db db_session_sync: jobs: - grafana-db-init-session services: - endpoint: internal service: oslo_db grafana: jobs: - grafana-db-init - grafana-db-session-sync - grafana-set-admin-user - grafana-run-migrator services: - endpoint: internal service: oslo_db image_repo_sync: services: - endpoint: internal service: local_image_registry set_admin_user: jobs: - grafana-db-init services: - endpoint: internal service: oslo_db run_migrator: jobs: - grafana-set-admin-user services: - endpoint: internal service: oslo_db tests: services: - endpoint: internal service: grafana network: grafana: node_port: enabled: false port: 30902 ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / network_policy: grafana: ingress: - {} egress: - {} secrets: oci_image_registry: grafana: grafana-oci-image-registry-key oslo_db: admin: grafana-db-admin user: grafana-db-user oslo_db_session: admin: grafana-session-db-admin user: grafana-session-db-user tls: grafana: grafana: public: grafana-tls-public prometheus: user: prometheus-user-creds manifests: certificates: false configmap_bin: true configmap_etc: true configmap_dashboards: true deployment: true ingress: true helm_tests: true job_db_init: true job_db_init_session: true job_db_session_sync: true job_image_repo_sync: true job_set_admin_user: true job_run_migrator: true network_policy: false secret_db: true secret_db_session: true secret_admin_creds: true secret_ingress_tls: true secret_prom_creds: true secret_registry: true service: true service_ingress: true conf: ldap: config: base_dns: search: "dc=cluster,dc=local" group_search: "ou=Groups,dc=cluster,dc=local" filters: search: "(uid=%s)" group_search: "(&(objectclass=posixGroup)(memberUID=uid=%s,ou=People,dc=cluster,dc=local))" template: | verbose_logging = false [[servers]] host = "{{ tuple "ldap" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }}" port = {{ tuple "ldap" "internal" "ldap" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} use_ssl = false start_tls = false ssl_skip_verify = false bind_dn = "{{ .Values.endpoints.ldap.auth.admin.bind_dn }}" bind_password = '{{ .Values.endpoints.ldap.auth.admin.password }}' search_filter = "{{ .Values.conf.ldap.config.filters.search }}" search_base_dns = ["{{ .Values.conf.ldap.config.base_dns.search }}"] group_search_filter = "{{ .Values.conf.ldap.config.filters.group_search }}" group_search_base_dns = ["{{ .Values.conf.ldap.config.base_dns.group_search }}"] [servers.attributes] username = "uid" surname = "sn" member_of = "cn" email = "mail" [[servers.group_mappings]] group_dn = "{{.Values.endpoints.ldap.auth.admin.bind_dn }}" org_role = "Admin" [[servers.group_mappings]] group_dn = "*" org_role = "Viewer" provisioning: dashboards: apiVersion: 1 providers: - name: 'osh-infra-dashboards' orgId: 1 folder: '' type: file disableDeletion: false editable: false options: path: /etc/grafana/dashboards datasources: template: | apiVersion: 1 datasources: - name: prometheus type: prometheus access: proxy orgId: 1 editable: true basicAuth: true basicAuthUser: {{ .Values.endpoints.monitoring.auth.user.username }} secureJsonData: basicAuthPassword: {{ .Values.endpoints.monitoring.auth.user.password }} url: {{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} grafana: alerting: enabled: false unified_alerting: enabled: true image_rendering_sidecar: enabled: false # https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/ k8s_sidecar_feature_enabled: true analytics: reporting_enabled: false check_for_updates: false remote_cache: type: database auth: login_cookie_name: grafana_sess login_maximum_lifetime_duration: 24h auth.ldap: enabled: true config_file: /etc/grafana/ldap.toml paths: data: /var/lib/grafana/data plugins: /var/lib/grafana/plugins alerting: /var/lib/grafana/alerting csv: /var/lib/grafana/csv provisioning: /etc/grafana/provisioning unified_storage: index_path: /var/lib/grafana/unified-search/bleve server: protocol: http http_port: 3000 database: type: mysql # -- Database connection URL. When empty the URL is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation. url: "" security: admin_user: ${GF_SECURITY_ADMIN_USER} admin_password: ${GF_SECURITY_ADMIN_PASSWORD} cookie_secure: false cookie_username: grafana_user cookie_remember_name: grafana_remember login_remember_days: 7 dashboards: default_home_dashboard_path: /etc/grafana/dashboards/home_dashboard.json users: allow_sign_up: false allow_org_create: false auto_assign_org: true default_theme: dark log: mode: console level: info grafana_net: url: https://grafana.net dashboards: {} # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: heat/.helmignore ================================================ values_overrides ================================================ FILE: heat/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Heat name: heat version: 2025.2.0 home: https://docs.openstack.org/heat/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Heat/OpenStack_Project_Heat_vertical.png sources: - https://opendev.org/openstack/heat - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: heat/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: heat/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex heat-manage db_sync ================================================ FILE: heat/templates/bin/_heat-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars mkdir -p ${APACHE_RUN_DIR} fi {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} if [ -f /var/run/apache2/apache2.pid ]; then # Remove the stale pid for debian/ubuntu images rm -f /var/run/apache2/apache2.pid fi # Starts Apache2 exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} {{- else }} exec uwsgi --ini /etc/heat/heat-api-uwsgi.ini {{- end }} } function stop () { {{- if .Values.manifests.certificates }} {{ .Values.conf.software.apache2.binary }} -k graceful-stop {{- else }} kill -TERM 1 {{- end }} } $COMMAND ================================================ FILE: heat/templates/bin/_heat-cfn.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars mkdir -p ${APACHE_RUN_DIR} fi {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} if [ -f /var/run/apache2/apache2.pid ]; then # Remove the stale pid for debian/ubuntu images rm -f /var/run/apache2/apache2.pid fi # Starts Apache2 exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} {{- else }} exec uwsgi --ini /etc/heat/heat-api-cfn-uwsgi.ini {{- end }} } function stop () { {{- if .Values.manifests.certificates }} {{ .Values.conf.software.apache2.binary }} -k graceful-stop {{- else }} kill -TERM 1 {{- end }} } $COMMAND ================================================ FILE: heat/templates/bin/_heat-engine-cleaner.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex heat-manage service clean ================================================ FILE: heat/templates/bin/_heat-engine.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x COMMAND="${@:-start}" function start () { exec heat-engine \ --config-file /etc/heat/heat.conf \ --config-dir /etc/heat/heat.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: heat/templates/bin/_heat-purge-deleted-active.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex heat-manage purge_deleted -g minutes "$1" ================================================ FILE: heat/templates/bin/_trusts.sh.tpl ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #!/bin/bash set -ex # Get IDs for filtering OS_PROJECT_ID=$(openstack project show -f value -c id ${OS_PROJECT_NAME}) OS_USER_ID=$(openstack user show -f value -c id ${OS_USERNAME}) SERVICE_OS_TRUSTEE_ID=$(openstack user show -f value -c id --domain ${SERVICE_OS_TRUSTEE_DOMAIN} ${SERVICE_OS_TRUSTEE}) # Check if trust doesn't already exist openstack trust list -f value -c "Project ID" \ -c "Trustee User ID" -c "Trustor User ID" | \ grep "^${OS_PROJECT_ID} ${SERVICE_OS_TRUSTEE_ID} ${OS_USER_ID}$" && \ exit 0 # If there are no roles specified... if [ -z "${SERVICE_OS_ROLES}" ]; then # ...Heat will try to delegate all of the roles that user has in the # project. Let's fetch them all and use that. readarray -t roles < <(openstack role assignment list -f value \ -c "Role" --user="${OS_USERNAME}" --project="${OS_PROJECT_ID}") else # Split roles into an array IFS=',' read -r -a roles <<< "${SERVICE_OS_ROLES}" fi # Create trust between trustor and trustee SERVICE_OS_TRUST_ID=$(openstack trust create -f value -c id \ --project="${OS_PROJECT_NAME}" \ ${roles[@]/#/--role=} \ --trustee-domain="${SERVICE_OS_TRUSTEE_DOMAIN}" \ "${OS_USERNAME}" \ "${SERVICE_OS_TRUSTEE}") # Display trust openstack trust show "${SERVICE_OS_TRUST_ID}" ================================================ FILE: heat/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "orchestration" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{ dict "envAll" . "service" "cloudformation" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: heat/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: heat-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} ks-domain-user.sh: | {{- include "helm-toolkit.scripts.keystone_domain_user" . | indent 4 }} trusts.sh: | {{ tuple "bin/_trusts.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} heat-api.sh: | {{ tuple "bin/_heat-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} heat-cfn.sh: | {{ tuple "bin/_heat-cfn.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} heat-engine.sh: | {{ tuple "bin/_heat-engine.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} heat-engine-cleaner.sh: | {{ tuple "bin/_heat-engine-cleaner.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} heat-purge-deleted-active.sh: | {{ tuple "bin/_heat-purge-deleted-active.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: heat/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.heat.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.heat.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.heat.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.heat.keystone_authtoken "region_name" .Values.endpoints.identity.auth.heat.region_name -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.heat.keystone_authtoken "project_name" .Values.endpoints.identity.auth.heat.project_name -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.heat.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.heat.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.heat.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.heat.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.username -}} {{- $_ := set .Values.conf.heat.keystone_authtoken "username" .Values.endpoints.identity.auth.heat.username -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.password -}} {{- $_ := set .Values.conf.heat.keystone_authtoken "password" .Values.endpoints.identity.auth.heat.password -}} {{- end -}} {{- if empty .Values.conf.heat.trustee.region_name -}} {{- $_ := set .Values.conf.heat.trustee "region_name" .Values.endpoints.identity.auth.heat_trustee.region_name -}} {{- end -}} {{- if empty .Values.conf.heat.trustee.user_domain_name -}} {{- $_ := set .Values.conf.heat.trustee "user_domain_name" .Values.endpoints.identity.auth.heat_trustee.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.heat.trustee.username -}} {{- $_ := set .Values.conf.heat.trustee "username" .Values.endpoints.identity.auth.heat_trustee.username -}} {{- end -}} {{- if empty .Values.conf.heat.trustee.password -}} {{- $_ := set .Values.conf.heat.trustee "password" .Values.endpoints.identity.auth.heat_trustee.password -}} {{- end -}} {{- if empty .Values.conf.heat.DEFAULT.stack_user_domain_name -}} {{- $_ := set .Values.conf.heat.DEFAULT "stack_user_domain_name" .Values.endpoints.identity.auth.heat_stack_user.domain_name -}} {{- end -}} {{- if empty .Values.conf.heat.DEFAULT.stack_domain_admin -}} {{- $_ := set .Values.conf.heat.DEFAULT "stack_domain_admin" .Values.endpoints.identity.auth.heat_stack_user.username -}} {{- end -}} {{- if empty .Values.conf.heat.DEFAULT.stack_domain_admin_password -}} {{- $_ := set .Values.conf.heat.DEFAULT "stack_domain_admin_password" .Values.endpoints.identity.auth.heat_stack_user.password -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.heat.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.heat.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.heat.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.heat.database.connection)) (empty .Values.conf.heat.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "heat" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.heat.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.heat.database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.heat.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "heat" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.heat.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.heat.DEFAULT.heat_metadata_server_url -}} {{- $_ := tuple "cloudformation" "public" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | trimSuffix .Values.endpoints.cloudformation.path.default | set .Values.conf.heat.DEFAULT "heat_metadata_server_url" -}} {{- end -}} {{- if empty .Values.conf.heat.DEFAULT.heat_waitcondition_server_url -}} {{- $_ := cat (tuple "cloudformation" "public" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup") "waitcondition" | replace " " "/" | set .Values.conf.heat.DEFAULT "heat_waitcondition_server_url" -}} {{- end -}} {{- if empty .Values.conf.heat.clients_keystone.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | trimSuffix .Values.endpoints.identity.path.default | set .Values.conf.heat.clients_keystone "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.heat.trustee.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | trimSuffix .Values.endpoints.identity.path.default | set .Values.conf.heat.trustee "auth_url" -}} {{- end -}} {{- if empty .Values.conf.heat.heat_api.bind_port -}} {{- $_ := tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.heat.heat_api "bind_port" -}} {{- end -}} {{- if empty .Values.conf.heat.heat_api_cfn.bind_port -}} {{- $_ := tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.heat.heat_api_cfn "bind_port" -}} {{- end -}} {{- if empty .Values.conf.heat_api_uwsgi.uwsgi.processes -}} {{- $_ := set .Values.conf.heat_api_uwsgi.uwsgi "processes" .Values.conf.heat.heat_api.workers -}} {{- end -}} {{- if empty (index .Values.conf.heat_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.heat_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} {{- if empty .Values.conf.heat_api_cfn_uwsgi.uwsgi.processes -}} {{- $_ := set .Values.conf.heat_api_cfn_uwsgi.uwsgi "processes" .Values.conf.heat.heat_api_cfn.workers -}} {{- end -}} {{- if empty (index .Values.conf.heat_api_cfn_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.heat_api_cfn_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .deployment_name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: heat-etc type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} heat.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.heat | b64enc }} heat-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.heat_api_uwsgi | b64enc }} heat-api-cfn-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.heat_api_cfn_uwsgi | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} {{- if .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.mpm_event "key" "mpm_event.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_heat "key" "wsgi-heat.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_cfn "key" "wsgi-cnf.conf" "format" "Secret" ) | indent 2 }} {{- end }} api_audit_map.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.api_audit_map | b64enc }} {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} {{ printf "test_template_%d" $key }}: {{ $value.template | b64enc }} {{- end }} {{- end }} ================================================ FILE: heat/templates/cron-job-engine-cleaner.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_engine_cleaner }} {{- $envAll := . }} {{- $mounts_heat_engine_cleaner := .Values.pod.mounts.heat_engine_cleaner.heat_engine_cleaner }} {{- $mounts_heat_engine_cleaner_init := .Values.pod.mounts.heat_engine_cleaner.init_container }} {{- $serviceAccountName := "heat-engine-cleaner" }} {{ tuple $envAll "engine_cleaner" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.heat_engine_cleaner }} --- apiVersion: batch/v1 kind: CronJob metadata: name: heat-engine-cleaner annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.engine_cleaner.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.engine_cleaner.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.engine_cleaner.history.failed }} {{- if .Values.jobs.engine_cleaner.starting_deadline }} startingDeadlineSeconds: {{ .Values.jobs.engine_cleaner.starting_deadline }} {{- end }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "heat" "engine-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "heat-engine-cleaner" "containerNames" (list "heat-engine-cleaner" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "heat" "engine-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 12 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "heat-engine-cleaner" "containerNames" (list "heat-engine-cleaner" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 12 }} spec: {{ tuple "heat_engine_cleaner" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "heat_engine_cleaner" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "engine_cleaner" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "engine_cleaner" $mounts_heat_engine_cleaner_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: heat-engine-cleaner {{ tuple $envAll "heat_engine_cleaner" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.engine_cleaner | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "engine_cleaner" "container" "heat_engine_cleaner" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/heat/certs/ca.crt" {{- end }} command: - /tmp/heat-engine-cleaner.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: heat-bin mountPath: /tmp/heat-engine-cleaner.sh subPath: heat-engine-cleaner.sh readOnly: true - name: etcheat mountPath: /etc/heat - name: heat-etc mountPath: /etc/heat/heat.conf subPath: heat.conf readOnly: true - name: heat-etc-snippets mountPath: /etc/heat/heat.conf.d/ readOnly: true {{ if .Values.conf.heat.DEFAULT.log_config_append }} - name: heat-etc mountPath: {{ .Values.conf.heat.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.heat.DEFAULT.log_config_append }} readOnly: true {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 14 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 14 }} {{ if $mounts_heat_engine_cleaner.volumeMounts }}{{ toYaml $mounts_heat_engine_cleaner.volumeMounts | indent 14 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etcheat emptyDir: {} - name: heat-etc secret: secretName: heat-etc defaultMode: 0444 - name: heat-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} - name: heat-bin configMap: name: heat-bin defaultMode: 0555 {{ if $mounts_heat_engine_cleaner.volumes }}{{ toYaml $mounts_heat_engine_cleaner.volumes | indent 12 }}{{ end }} {{- end }} ================================================ FILE: heat/templates/cron-job-purge-deleted.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_purge_deleted }} {{- $envAll := . }} {{- $mounts_heat_purge_deleted := .Values.pod.mounts.heat_purge_deleted.heat_purge_deleted }} {{- $mounts_heat_purge_deleted_init := .Values.pod.mounts.heat_purge_deleted.init_container }} {{- $serviceAccountName := "heat-purge-deleted" }} {{ tuple $envAll "purge_deleted" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.heat_purge_deleted }} --- apiVersion: batch/v1 kind: CronJob metadata: name: heat-purge-deleted annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.purge_deleted.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.purge_deleted.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.purge_deleted.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "heat" "purge-deleted" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "heat-purge-deleted" "containerNames" (list "init" "heat-purge-deleted" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "heat" "purge-deleted" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 12 }} {{ dict "envAll" $envAll "podName" "heat-purge-deleted" "containerNames" (list "init" "heat-purge-deleted" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 12 }} spec: {{ tuple "heat_purge_deleted" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "heat_purge_deleted" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "purge_deleted" $mounts_heat_purge_deleted_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: heat-purge-deleted {{ tuple $envAll "heat_purge_deleted" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.purge_deleted | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/heat/certs/ca.crt" {{- end }} command: - /tmp/heat-purge-deleted-active.sh - {{ quote .Values.jobs.purge_deleted.purge_age }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: heat-bin mountPath: /tmp/heat-purge-deleted-active.sh subPath: heat-purge-deleted-active.sh readOnly: true - name: etcheat mountPath: /etc/heat - name: heat-etc mountPath: /etc/heat/heat.conf subPath: heat.conf readOnly: true - name: heat-etc-snippets mountPath: /etc/heat/heat.conf.d/ readOnly: true {{ if .Values.conf.heat.DEFAULT.log_config_append }} - name: heat-etc mountPath: {{ .Values.conf.heat.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.heat.DEFAULT.log_config_append }} readOnly: true {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 14 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 14 }} {{ if $mounts_heat_purge_deleted.volumeMounts }}{{ toYaml $mounts_heat_purge_deleted.volumeMounts | indent 14 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etcheat emptyDir: {} - name: heat-etc secret: secretName: heat-etc defaultMode: 0444 {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} - name: heat-bin configMap: name: heat-bin defaultMode: 0555 - name: heat-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} {{ if $mounts_heat_purge_deleted.volumes }}{{ toYaml $mounts_heat_purge_deleted.volumes | indent 12 }}{{ end }} {{- end }} ================================================ FILE: heat/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_heat_api := .Values.pod.mounts.heat_api.heat_api }} {{- $mounts_heat_api_init := .Values.pod.mounts.heat_api.init_container }} {{- $serviceAccountName := "heat-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.heat_api }} --- apiVersion: apps/v1 kind: Deployment metadata: name: heat-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "heat" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "heat" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "heat" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "heat_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "heat-api" "containerNames" (list "heat-api" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "heat_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "heat_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "heat" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "heat" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_heat_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: heat-api {{ tuple $envAll "heat_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "heat" "container" "heat_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/heat/certs/ca.crt" {{- end }} command: - /tmp/heat-api.sh - start lifecycle: preStop: exec: command: - /tmp/heat-api.sh - stop ports: - name: h-api containerPort: {{ tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: {{ tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 30 livenessProbe: httpGet: scheme: {{ tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / {{- if .Values.pod.probes.api.heat_api.liveness.port }} port: {{ .Values.pod.probes.api.heat_api.liveness.port }} {{- else }} port: {{ tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} initialDelaySeconds: 10 volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.heat.oslo_concurrency.lock_path }} - name: pod-etc-heat mountPath: /etc/heat - name: heat-bin mountPath: /tmp/heat-api.sh subPath: heat-api.sh readOnly: true - name: heat-etc mountPath: /etc/heat/heat.conf subPath: heat.conf readOnly: true - name: heat-etc-snippets mountPath: /etc/heat/heat.conf.d/ readOnly: true - name: heat-etc mountPath: /etc/heat/heat-api-uwsgi.ini subPath: heat-api-uwsgi.ini readOnly: true {{ if .Values.conf.heat.DEFAULT.log_config_append }} - name: heat-etc mountPath: {{ .Values.conf.heat.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.heat.DEFAULT.log_config_append }} readOnly: true {{ end }} - name: heat-etc mountPath: /etc/heat/api-paste.ini subPath: api-paste.ini readOnly: true - name: heat-etc mountPath: /etc/heat/policy.yaml subPath: policy.yaml readOnly: true - name: heat-etc mountPath: /etc/heat/api_audit_map.conf subPath: api_audit_map.conf readOnly: true {{- if .Values.manifests.certificates }} - name: heat-etc mountPath: {{ .Values.conf.software.apache2.site_dir }}/heat-api.conf subPath: wsgi-heat.conf readOnly: true - name: heat-etc mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf subPath: mpm_event.conf readOnly: true {{- end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_api.volumeMounts }}{{ toYaml $mounts_heat_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-heat emptyDir: {} - name: heat-bin configMap: name: heat-bin defaultMode: 0555 - name: heat-etc secret: secretName: heat-etc defaultMode: 0444 - name: heat-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_api.volumes }}{{ toYaml $mounts_heat_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: heat/templates/deployment-cfn.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_cfn }} {{- $envAll := . }} {{- $mounts_heat_cfn := .Values.pod.mounts.heat_cfn.heat_cfn }} {{- $mounts_heat_cfn_init := .Values.pod.mounts.heat_cfn.init_container }} {{- $serviceAccountName := "heat-cfn" }} {{ tuple $envAll "cfn" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.heat_cfn }} --- apiVersion: apps/v1 kind: Deployment metadata: name: heat-cfn annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "heat" "cfn" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.cfn }} selector: matchLabels: {{ tuple $envAll "heat" "cfn" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "heat" "cfn" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "heat_cfn" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "heat-cfn" "containerNames" (list "heat-cfn" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "heat_cfn" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "heat_cfn" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "heat" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "heat" "cfn" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.cfn.node_selector_key }}: {{ .Values.labels.cfn.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.cfn.timeout | default "30" }} initContainers: {{ tuple $envAll "cfn" $mounts_heat_cfn_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: heat-cfn {{ tuple $envAll "heat_cfn" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.cfn | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "heat" "container" "heat_cfn" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/heat/certs/ca.crt" {{- end }} command: - /tmp/heat-cfn.sh - start lifecycle: preStop: exec: command: - /tmp/heat-cfn.sh - stop ports: - name: h-cfn containerPort: {{ tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: {{ tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} livenessProbe: httpGet: scheme: {{ tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / {{- if .Values.pod.probes.cfn.heat_cfn.liveness.port }} port: {{ .Values.pod.probes.cfn.heat_cfn.liveness.port }} {{- else }} port: {{ tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} initialDelaySeconds: 10 volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.heat.oslo_concurrency.lock_path }} - name: pod-etc-heat mountPath: /etc/heat - name: heat-bin mountPath: /tmp/heat-cfn.sh subPath: heat-cfn.sh readOnly: true - name: heat-etc mountPath: /etc/heat/heat-api-cfn-uwsgi.ini subPath: heat-api-cfn-uwsgi.ini readOnly: true - name: heat-etc mountPath: /etc/heat/heat.conf subPath: heat.conf readOnly: true - name: heat-etc-snippets mountPath: /etc/heat/heat.conf.d/ readOnly: true {{ if .Values.conf.heat.DEFAULT.log_config_append }} - name: heat-etc mountPath: {{ .Values.conf.heat.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.heat.DEFAULT.log_config_append }} readOnly: true {{ end }} - name: heat-etc mountPath: /etc/heat/api-paste.ini subPath: api-paste.ini readOnly: true - name: heat-etc mountPath: /etc/heat/policy.yaml subPath: policy.yaml readOnly: true - name: heat-etc mountPath: /etc/heat/api_audit_map.conf subPath: api_audit_map.conf readOnly: true {{- if .Values.manifests.certificates }} - name: heat-etc mountPath: {{ .Values.conf.software.apache2.site_dir }}/heat-api-cfn.conf subPath: wsgi-cnf.conf readOnly: true - name: heat-etc mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf subPath: mpm_event.conf readOnly: true {{- end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.cloudformation.cfn.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_cfn.volumeMounts }}{{ toYaml $mounts_heat_cfn.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-heat emptyDir: {} - name: heat-bin configMap: name: heat-bin defaultMode: 0555 - name: heat-etc secret: secretName: heat-etc defaultMode: 0444 - name: heat-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.cloudformation.cfn.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_cfn.volumes }}{{ toYaml $mounts_heat_cfn.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: heat/templates/deployment-engine.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if or ( .Values.manifests.deployment_engine ) ( .Values.manifests.statefulset_engine ) }} {{- $envAll := . }} {{- $mounts_heat_engine := .Values.pod.mounts.heat_engine.heat_engine }} {{- $mounts_heat_engine_init := .Values.pod.mounts.heat_engine.init_container }} {{- $serviceAccountName := "heat-engine" }} {{ tuple $envAll "engine" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.heat_engine }} --- apiVersion: apps/v1 metadata: name: heat-engine annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "heat" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if .Values.manifests.deployment_engine }} kind: Deployment spec: {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} {{- else if .Values.manifests.statefulset_engine }} kind: StatefulSet spec: serviceName: heat-engine {{- end }} replicas: {{ .Values.pod.replicas.engine }} selector: matchLabels: {{ tuple $envAll "heat" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "heat" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if .Values.manifests.deployment_engine }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "heat_engine" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "heat-engine" "containerNames" (list "heat-engine" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{- end }} spec: {{ tuple "heat_engine" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "heat_engine" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "heat" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{- tuple $envAll "heat" "engine" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.engine.node_selector_key }}: {{ .Values.labels.engine.node_selector_value }} {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.engine.timeout | default "30" }} initContainers: {{ tuple $envAll "engine" $mounts_heat_engine_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: heat-engine {{ tuple $envAll "heat_engine" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.engine | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "heat" "container" "heat_engine" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/heat/certs/ca.crt" {{- end }} command: - /tmp/heat-engine.sh - start lifecycle: preStop: exec: command: - /tmp/heat-engine.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.heat.oslo_concurrency.lock_path }} - name: pod-etc-heat mountPath: /etc/heat - name: heat-bin mountPath: /tmp/heat-engine.sh subPath: heat-engine.sh readOnly: true - name: heat-etc mountPath: /etc/heat/heat.conf subPath: heat.conf readOnly: true - name: heat-etc-snippets mountPath: /etc/heat/heat.conf.d/ readOnly: true {{ if .Values.conf.heat.DEFAULT.log_config_append }} - name: heat-etc mountPath: {{ .Values.conf.heat.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.heat.DEFAULT.log_config_append }} readOnly: true {{ end }} - name: heat-etc mountPath: /etc/heat/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_engine.volumeMounts }}{{ toYaml $mounts_heat_engine.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-heat emptyDir: {} - name: heat-bin configMap: name: heat-bin defaultMode: 0555 - name: heat-etc secret: secretName: heat-etc defaultMode: 0444 - name: heat-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_engine.volumes }}{{ toYaml $mounts_heat_engine.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: heat/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: heat/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "orchestration" "backendPort" "h-api" -}} {{- $secretName := $envAll.Values.secrets.tls.orchestration.api.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.orchestration.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: heat/templates/ingress-cfn.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_cfn .Values.network.cfn.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "cfn" "backendServiceType" "cloudformation" "backendPort" "h-cfn" -}} {{- $secretName := $envAll.Values.secrets.tls.cloudformation.cfn.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.cloudformation.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: heat/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.bootstrap" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "heat" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.heat.DEFAULT.log_config_append -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} {{- end -}} {{- $_ := set $bootstrapJob "jobAnnotations" (include "metadata.annotations.job.bootstrap" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: heat/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "heat" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: heat/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "heat" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: heat/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "heat" "podVolMounts" .Values.pod.mounts.heat_db_sync.heat_db_sync.volumeMounts "podVols" .Values.pod.mounts.heat_db_sync.heat_db_sync.volumes -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: heat/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "heat" -}} {{- $_ := $imageRepoSyncJob "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: heat/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "heat" "serviceTypes" ( tuple "orchestration" "cloudformation" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: heat/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "heat" "serviceTypes" ( tuple "orchestration" "cloudformation" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: heat/templates/job-ks-user-domain.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user_domain }} {{- $envAll := . }} {{- $serviceAccountName := "heat-ks-user-domain" }} {{ tuple $envAll "ks_user" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: heat-domain-ks-user labels: {{ tuple $envAll "heat" "ks-user-domain" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-delete-policy": before-hook-creation {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "heat" "ks-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "heat-domain-ks-user" "containerNames" (list "heat-ks-domain-user" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "ks_user" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "ks_user" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: heat-ks-domain-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "ks_user" "container" "heat_ks_domain_user" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ks-domain-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ks-user-sh mountPath: /tmp/ks-domain-user.sh subPath: ks-domain-user.sh readOnly: true {{ dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (or .Values.manifests.certificates .Values.tls.identity) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "heat" - name: SERVICE_OS_REGION_NAME valueFrom: secretKeyRef: name: {{ .Values.secrets.identity.heat_stack_user }} key: OS_REGION_NAME - name: SERVICE_OS_DOMAIN_NAME valueFrom: secretKeyRef: name: {{ .Values.secrets.identity.heat_stack_user }} key: OS_DOMAIN_NAME - name: SERVICE_OS_USERNAME valueFrom: secretKeyRef: name: {{ .Values.secrets.identity.heat_stack_user }} key: OS_USERNAME - name: SERVICE_OS_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.secrets.identity.heat_stack_user }} key: OS_PASSWORD - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.heat_stack_user.role | quote }} volumes: - name: pod-tmp emptyDir: {} - name: ks-user-sh configMap: name: heat-bin defaultMode: 0555 {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: heat/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "heat" "serviceUsers" (tuple "heat" "heat_trustee") -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: heat/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "heat" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $rmqUserJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $rmqUserJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{- if .Values.pod.tolerations.heat.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: heat/templates/job-trusts.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} {{- $mounts_heat_trusts := .Values.pod.mounts.heat_trusts.heat_trusts }} {{- $mounts_heat_trusts_init := .Values.pod.mounts.heat_trusts.init_container }} {{- $serviceAccountName := "heat-trusts" }} {{ tuple $envAll "trusts" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: heat-trusts labels: {{ tuple $envAll "heat" "trusts" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-delete-policy": before-hook-creation {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "heat" "trusts" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "heat-trusts" "containerNames" (list "heat-trusts" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "heat_trusts" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "heat_trusts" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "trusts" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "trusts" $mounts_heat_trusts_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: heat-trusts {{ tuple $envAll "ks_service" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.trusts | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "trusts" "container" "heat_trusts" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - bash - /tmp/trusts.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: heat-bin mountPath: /tmp/trusts.sh subPath: trusts.sh readOnly: true {{ dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_trusts.volumeMounts }}{{ toYaml $mounts_heat_trusts.volumeMounts | indent 12 }}{{ end }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (or .Values.manifests.certificates .Values.tls.identity) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_ROLES value: {{ .Values.conf.heat.DEFAULT.trusts_delegated_roles }} - name: SERVICE_OS_TRUSTEE value: {{ .Values.endpoints.identity.auth.heat_trustee.username }} - name: SERVICE_OS_TRUSTEE_DOMAIN value: {{ .Values.endpoints.identity.auth.heat_trustee.user_domain_name }} volumes: - name: pod-tmp emptyDir: {} - name: heat-bin configMap: name: heat-bin defaultMode: 0555 {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_trusts.volumes }}{{ toYaml $mounts_heat_trusts.volumes | indent 8 }}{{ end }} ================================================ FILE: heat/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "heat" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: heat/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: heat-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "heat" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: heat/templates/pdb-cfn.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_cfn }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: heat-cfn spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.cfn.min_available }} selector: matchLabels: {{ tuple $envAll "heat" "cfn" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: heat/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.heat_tests.heat_tests }} {{- $mounts_tests_init := .Values.pod.mounts.heat_tests.init_container }} {{- $serviceAccountName := print $envAll.deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.deployment_name "-test" }} labels: {{ tuple $envAll "heat" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.heat.enabled }} {{ tuple $envAll "heat" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} restartPolicy: Never {{ tuple "heat_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "heat_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: {{ .deployment_name }}-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: heat-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" $envAll.Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: {{ .deployment_name }}-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.deployment_name}} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: heat-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: heat-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} - name: heat-etc mountPath: {{ $value.name }} subPath: {{ printf "test_template_%d" $key }} readOnly: true {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" $envAll.Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: heat-etc secret: secretName: heat-etc defaultMode: 0444 - name: heat-bin configMap: name: heat-bin defaultMode: 0555 - name: rally-db emptyDir: {} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: heat/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "heat" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: heat/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "orchestration" ) }} {{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendService" "cfn" "backendServiceType" "cloudformation" ) }} {{- end }} ================================================ FILE: heat/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "heat" "heat_trustee" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} --- apiVersion: v1 kind: Secret metadata: name: {{ $envAll.Values.secrets.identity.heat_stack_user }} annotations: {{ tuple "identity" "heat_stack_user" $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: OS_AUTH_URL: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} OS_REGION_NAME: {{ .Values.endpoints.identity.auth.heat_stack_user.region_name | b64enc }} OS_DOMAIN_NAME: {{ .Values.endpoints.identity.auth.heat_stack_user.domain_name | b64enc }} OS_USERNAME: {{ .Values.endpoints.identity.auth.heat_stack_user.username | b64enc }} OS_PASSWORD: {{ .Values.endpoints.identity.auth.heat_stack_user.password | b64enc }} {{- end }} ================================================ FILE: heat/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "heat" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: heat/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: heat/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "orchestration" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: h-api port: {{ tuple "orchestration" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "heat" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: heat/templates/service-cfn.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_cfn }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "cloudformation" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: h-cfn port: {{ tuple "cloudformation" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.cfn.node_port.enabled }} nodePort: {{ .Values.network.cfn.node_port.port }} {{ end }} selector: {{ tuple $envAll "heat" "cfn" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.cfn.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: heat/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "orchestration" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: heat/templates/service-ingress-cfn.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_cfn .Values.network.cfn.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "cloudformation" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: heat/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for heat. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled cfn: node_selector_key: openstack-control-plane node_selector_value: enabled engine: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble heat_db_sync: quay.io/airshipit/heat:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble heat_api: quay.io/airshipit/heat:2025.1-ubuntu_noble heat_cfn: quay.io/airshipit/heat:2025.1-ubuntu_noble heat_engine: quay.io/airshipit/heat:2025.1-ubuntu_noble heat_engine_cleaner: quay.io/airshipit/heat:2025.1-ubuntu_noble heat_purge_deleted: quay.io/airshipit/heat:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync jobs: engine_cleaner: cron: "*/5 * * * *" starting_deadline: 600 history: success: 3 failed: 1 purge_deleted: cron: "20 */24 * * *" purge_age: 60 history: success: 3 failed: 1 conf: rally_tests: run_tempest: false tests: HeatStacks.create_update_delete_stack: - args: template_path: /tmp/rally-jobs/random_strings.yaml updated_template_path: /tmp/rally-jobs/updated_random_strings_replace.yaml runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 HeatStacks.create_check_delete_stack: - args: template_path: /tmp/rally-jobs/random_strings.yaml runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 HeatStacks.create_and_delete_stack: - args: template_path: /tmp/rally-jobs/resource_group_with_constraint.yaml runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 HeatStacks.create_and_list_stack: - args: template_path: /tmp/rally-jobs/default.yaml runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 HeatStacks.create_snapshot_restore_delete_stack: - args: template_path: /tmp/rally-jobs/random_strings.yaml runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 HeatStacks.create_stack_and_list_output: - args: template_path: /tmp/rally-jobs/resource_group_with_outputs.yaml runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 HeatStacks.create_stack_and_list_output_via_API: - args: template_path: /tmp/rally-jobs/resource_group_with_outputs.yaml runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 templates: - name: /tmp/rally-jobs/default.yaml template: | heat_template_version: 2014-10-16 - name: /tmp/rally-jobs/random_strings.yaml template: | heat_template_version: 2014-10-16 description: Test template for rally create-update-delete scenario resources: test_string_one: type: OS::Heat::RandomString properties: length: 20 test_string_two: type: OS::Heat::RandomString properties: length: 20 - name: /tmp/rally-jobs/resource_group_with_constraint.yaml template: | heat_template_version: 2013-05-23 description: Template for testing caching. parameters: count: type: number default: 40 delay: type: number default: 0.1 resources: rg: type: OS::Heat::ResourceGroup properties: count: get_param: count resource_def: type: OS::Heat::TestResource properties: constraint_prop_secs: get_param: delay - name: /tmp/rally-jobs/resource_group_with_outputs.yaml template: | heat_template_version: 2013-05-23 parameters: attr_wait_secs: type: number default: 0.5 resources: rg: type: OS::Heat::ResourceGroup properties: count: 10 resource_def: type: OS::Heat::TestResource properties: attr_wait_secs: get_param: attr_wait_secs outputs: val1: value: get_attr: - rg - resource.0.output val2: value: get_attr: - rg - resource.1.output val3: value: get_attr: - rg - resource.2.output val4: value: get_attr: - rg - resource.3.output val5: value: get_attr: - rg - resource.4.output val6: value: get_attr: - rg - resource.5.output val7: value: get_attr: - rg - resource.6.output val8: value: get_attr: - rg - resource.7.output val9: value: get_attr: - rg - resource.8.output val10: value: get_attr: - rg - resource.9.output - name: /tmp/rally-jobs/updated_random_strings_replace.yaml template: | heat_template_version: 2014-10-16 description: | Test template for create-update-delete-stack scenario in rally. The template deletes one resource from the stack defined by random-strings.yaml.template and re-creates it with the updated parameters (so-called update-replace). That happens because some parameters cannot be changed without resource re-creation. The template allows to measure performance of update-replace operation. resources: test_string_one: type: OS::Heat::RandomString properties: length: 20 test_string_two: type: OS::Heat::RandomString properties: length: 40 paste: pipeline:heat-api: pipeline: cors request_id faultwrap http_proxy_to_wsgi versionnegotiation osprofiler authurl authtoken audit context apiv1app pipeline:heat-api-standalone: pipeline: cors request_id faultwrap http_proxy_to_wsgi versionnegotiation authurl authpassword context apiv1app pipeline:heat-api-custombackend: pipeline: cors request_id faultwrap versionnegotiation context custombackendauth apiv1app pipeline:heat-api-cfn: pipeline: cors http_proxy_to_wsgi cfnversionnegotiation osprofiler ec2authtoken authtoken audit context apicfnv1app pipeline:heat-api-cfn-standalone: pipeline: cors http_proxy_to_wsgi cfnversionnegotiation ec2authtoken context apicfnv1app app:apiv1app: paste.app_factory: heat.common.wsgi:app_factory heat.app_factory: heat.api.openstack.v1:API app:apicfnv1app: paste.app_factory: heat.common.wsgi:app_factory heat.app_factory: heat.api.cfn.v1:API filter:versionnegotiation: paste.filter_factory: heat.common.wsgi:filter_factory heat.filter_factory: heat.api.openstack:version_negotiation_filter filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: heat filter:faultwrap: paste.filter_factory: heat.common.wsgi:filter_factory heat.filter_factory: heat.api.openstack:faultwrap_filter filter:cfnversionnegotiation: paste.filter_factory: heat.common.wsgi:filter_factory heat.filter_factory: heat.api.cfn:version_negotiation_filter filter:context: paste.filter_factory: heat.common.context:ContextMiddleware_filter_factory filter:ec2authtoken: paste.filter_factory: heat.api.aws.ec2token:EC2Token_filter_factory filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware:HTTPProxyToWSGI.factory filter:authurl: paste.filter_factory: heat.common.auth_url:filter_factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:authpassword: paste.filter_factory: heat.common.auth_password:filter_factory filter:custombackendauth: paste.filter_factory: heat.common.custom_backend_auth:filter_factory filter:audit: paste.filter_factory: keystonemiddleware.audit:filter_factory audit_map_file: /etc/heat/api_audit_map.conf filter:request_id: paste.filter_factory: oslo_middleware.request_id:RequestId.factory filter:osprofiler: paste.filter_factory: osprofiler.web:WsgiMiddleware.factory policy: {} heat: DEFAULT: log_config_append: /etc/heat/logging.conf num_engine_workers: 1 trusts_delegated_roles: "" host: heat-engine keystone_authtoken: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT service_type: orchestration database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" trustee: auth_type: password auth_version: v3 heat_api: # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. bind_port: null workers: 1 heat_api_cfn: # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. bind_port: null workers: 1 paste_deploy: api_paste_config: /etc/heat/api-paste.ini clients: endpoint_type: internalURL clients_heat: endpoint_type: publicURL clients_keystone: endpoint_type: internalURL oslo_messaging_notifications: driver: messagingv2 oslo_middleware: enable_proxy_headers_parsing: true oslo_messaging_rabbit: rabbit_ha_queues: True oslo_policy: policy_file: /etc/heat/policy.yaml oslo_concurrency: lock_path: /var/lock api_audit_map: DEFAULT: target_endpoint_type: None path_keywords: stacks: stack resources: resource preview: None detail: None abandon: None snapshots: snapshot restore: None outputs: output metadata: server signal: None events: event template: None template_versions: template_version functions: None validate: None resource_types: resource_type build_info: None actions: None software_configs: software_config software_deployments: software_deployment services: None service_endpoints: orchestration:service/orchestration logging: loggers: keys: - root - heat handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_heat: level: INFO handlers: - stdout qualname: heat logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" rabbitmq: # NOTE(rk760n): adding rmq policy to mirror messages from notification queues and set expiration time for the ones policies: - vhost: "heat" name: "ha_ttl_heat" definition: # mirror messges to other nodes in rmq cluster ha-mode: "all" ha-sync-mode: "automatic" # 70s message-ttl: 70000 priority: 0 apply-to: all pattern: '^(?!(amq\.|reply_)).*' heat_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "heat-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/heat-wsgi-api stats: 0.0.0.0:1717 stats-http: true heat_api_cfn_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "heat-api-cfn:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/heat-wsgi-api-cfn stats: 0.0.0.0:1717 stats-http: true network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30004 cfn: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30800 bootstrap: enabled: true ks_user: admin script: | #NOTE(portdirect): The Orchestration service automatically assigns the # 'heat_stack_user' role to users that it creates during stack deployment. # By default, this role restricts API operations. To avoid conflicts, do # not add this role to actual users. openstack role create --or-show heat_stack_user dependencies: dynamic: common: local_image_registry: jobs: - heat-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - heat-db-sync - heat-rabbit-init - heat-ks-user - heat-domain-ks-user - heat-ks-endpoints - heat-bootstrap services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: identity cfn: jobs: - heat-db-sync - heat-rabbit-init - heat-ks-user - heat-domain-ks-user - heat-ks-endpoints - heat-bootstrap services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: identity db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - heat-db-init services: - endpoint: internal service: oslo_db bootstrap: services: - endpoint: internal service: identity engine: jobs: - heat-db-sync - heat-rabbit-init - heat-ks-user - heat-domain-ks-user - heat-ks-endpoints - heat-bootstrap services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: identity engine_cleaner: jobs: - heat-db-sync - heat-ks-user - heat-domain-ks-user - heat-ks-endpoints services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: identity purge_deleted: jobs: - heat-db-sync - heat-ks-user - heat-domain-ks-user - heat-ks-endpoints services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: identity ks_endpoints: jobs: - heat-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - endpoint: internal service: oslo_messaging trusts: jobs: - heat-ks-user - heat-domain-ks-user services: - endpoint: internal service: identity image_repo_sync: services: - endpoint: internal service: local_image_registry tests: services: - endpoint: internal service: identity - endpoint: internal service: orchestration # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: heat-keystone-admin heat: heat-keystone-user heat_trustee: heat-keystone-trustee heat_stack_user: heat-keystone-stack-user test: heat-keystone-test oslo_db: admin: heat-db-admin heat: heat-db-user oslo_messaging: admin: heat-rabbitmq-admin heat: heat-rabbitmq-user tls: orchestration: api: public: heat-tls-public internal: heat-tls-api cloudformation: cfn: public: cloudformation-tls-public internal: heat-tls-cfn oci_image_registry: heat: heat-oci-image-registry # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false heat: username: heat password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default heat: role: admin region_name: RegionOne username: heat password: password project_name: service user_domain_name: service project_domain_name: service heat_trustee: role: admin region_name: RegionOne username: heat-trust password: password project_name: service user_domain_name: service project_domain_name: service heat_stack_user: role: admin region_name: RegionOne username: heat-domain password: password domain_name: heat test: role: admin region_name: RegionOne username: heat-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 orchestration: name: heat hosts: default: heat-api public: heat host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: '/v1/%(project_id)s' scheme: default: 'http' service: 'http' port: api: default: 8004 public: 80 service: 8004 cloudformation: name: heat-cfn hosts: default: heat-cfn public: cloudformation host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: /v1 scheme: default: 'http' service: 'http' port: api: default: 8000 public: 80 service: 8000 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct heat: username: heat password: password hosts: default: mariadb host_fqdn_override: default: null path: /heat scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct heat: username: heat password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /heat scheme: rabbit port: amqp: default: 5672 http: default: 15672 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 pod: security_context: heat: pod: runAsUser: 42424 container: heat_api: readOnlyRootFilesystem: true allowPrivilegeEscalation: false heat_cfn: readOnlyRootFilesystem: true allowPrivilegeEscalation: false heat_engine: readOnlyRootFilesystem: true allowPrivilegeEscalation: false trusts: pod: runAsUser: 42424 container: heat_trusts: readOnlyRootFilesystem: true allowPrivilegeEscalation: false ks_user: pod: runAsUser: 42424 container: heat_ks_domain_user: readOnlyRootFilesystem: true allowPrivilegeEscalation: false engine_cleaner: pod: runAsUser: 42424 container: heat_engine_cleaner: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: heat: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: heat_api: init_container: null heat_api: volumeMounts: volumes: heat_cfn: init_container: null heat_cfn: volumeMounts: volumes: heat_engine: init_container: null heat_engine: volumeMounts: volumes: heat_bootstrap: init_container: null heat_bootstrap: volumeMounts: volumes: heat_trusts: init_container: null heat_trusts: volumeMounts: volumes: heat_engine_cleaner: init_container: null heat_engine_cleaner: volumeMounts: volumes: heat_purge_deleted: init_container: null heat_purge_deleted: volumeMounts: volumes: heat_tests: init_container: null heat_tests: volumeMounts: volumes: heat_db_sync: heat_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/heat/heat.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: heat_api: [] heat_cfn: [] heat_engine: [] heat_engine_cleaner: [] heat_purge_deleted: [] heat_db_sync: [] replicas: api: 1 cfn: 1 engine: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 cfn: min_available: 0 termination_grace_period: api: timeout: 30 cfn: timeout: 30 engine: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" cfn: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" engine: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" trusts: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" engine_cleaner: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" purge_deleted: requests: memory: "124Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" probes: api: heat_api: liveness: port: 1717 cfn: heat_cfn: liveness: port: 1717 network_policy: heat: ingress: - {} egress: - {} tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false configmap_bin: true configmap_etc: true cron_job_engine_cleaner: true cron_job_purge_deleted: true deployment_api: true deployment_cfn: true deployment_engine: true ingress_api: true ingress_cfn: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user_domain: true job_ks_user_trustee: true job_ks_user: true job_rabbit_init: true pdb_api: true pdb_cfn: true pod_rally_test: true network_policy: false secret_db: true secret_ingress_tls: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_api: true service_cfn: true service_ingress_api: true service_ingress_cfn: true statefulset_engine: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: helm-toolkit/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Helm-Toolkit name: helm-toolkit version: 2025.2.0 home: https://docs.openstack.org/openstack-helm icon: https://www.openstack.org/themes/openstack/images/project-mascots/OpenStack-Helm/OpenStack_Project_OpenStackHelm_vertical.png sources: - https://opendev.org/openstack/openstack-helm - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: [] ... ================================================ FILE: helm-toolkit/templates/endpoints/_authenticated_endpoint_uri_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves database, or basic auth, style endpoints values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: auth: admin: username: root password: password service_username: username: username password: password hosts: default: mariadb host_fqdn_override: default: null path: /dbname scheme: mysql+pymysql port: mysql: default: 3306 usage: | {{ tuple "oslo_db" "internal" "service_username" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} return: | mysql+pymysql://serviceuser:password@mariadb.default.svc.cluster.local:3306/dbname */}} {{- define "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $userclass := index . 2 -}} {{- $port := index . 3 -}} {{- $context := index . 4 -}} {{- $endpointScheme := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $userMap := index $context.Values.endpoints ( $type | replace "-" "_" ) "auth" $userclass }} {{- $endpointUser := index $userMap "username" }} {{- $endpointPass := index $userMap "password" | urlquery }} {{- $endpointHost := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{- $endpointPort := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $endpointPath := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} {{- printf "%s://%s:%s@%s:%s%s" $endpointScheme $endpointUser $endpointPass $endpointHost $endpointPort $endpointPath -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_authenticated_transport_endpoint_uri_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves endpoint string suitible for use with oslo.messaging transport url See: https://docs.openstack.org/oslo.messaging/latest/reference/transport.html#oslo_messaging.TransportURL examples: - values: | endpoints: cluster_domain_suffix: cluster.local oslo_messaging: auth: cinder: username: cinder password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /cinder scheme: rabbit port: amqp: default: 5672 usage: | {{ tuple "oslo_messaging" "internal" "cinder" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" }} return: | rabbit://cinder:password@rabbitmq-rabbitmq-0.rabbitmq.default.svc.cluster.local:5672,cinder:password@rabbitmq-rabbitmq-1.rabbitmq.default.svc.cluster.local:5672/cinder - values: | endpoints: cluster_domain_suffix: cluster.local oslo_messaging: auth: cinder: username: cinder password: password statefulset: null hosts: default: rabbitmq host_fqdn_override: default: null path: /cinder scheme: rabbit port: amqp: default: 5672 usage: | {{ tuple "oslo_messaging" "internal" "cinder" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" }} return: | rabbit://cinder:password@rabbitmq.default.svc.cluster.local:5672/cinder - values: | endpoints: cluster_domain_suffix: cluster.local oslo_messaging: auth: cinder: username: cinder password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: rabbitmq.openstackhelm.org path: /cinder scheme: rabbit port: amqp: default: 5672 usage: | {{ tuple "oslo_messaging" "internal" "cinder" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" }} return: | rabbit://cinder:password@rabbitmq.openstackhelm.org:5672/cinder */}} {{- define "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $userclass := index . 2 -}} {{- $port := index . 3 -}} {{- $context := index . 4 -}} {{- $endpointScheme := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $userMap := index $context.Values.endpoints ( $type | replace "-" "_" ) "auth" $userclass }} {{- $ssMap := index $context.Values.endpoints ( $type | replace "-" "_" ) "statefulset" | default false}} {{- $hostFqdnOverride := index $context.Values.endpoints ( $type | replace "-" "_" ) "host_fqdn_override" }} {{- $endpointUser := index $userMap "username" }} {{- $endpointPass := index $userMap "password" | urlquery }} {{- $endpointHostSuffix := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{- $endpointPort := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $local := dict "endpointCredsAndHosts" list -}} {{- if not (or (index $hostFqdnOverride $endpoint | default ( index $hostFqdnOverride "default" ) ) ( not $ssMap ) ) }} {{- $endpointHostPrefix := $ssMap.name }} {{- range $podInt := until ( atoi (print $ssMap.replicas ) ) }} {{- $endpointCredAndHost := printf "%s:%s@%s-%d.%s:%s" $endpointUser $endpointPass $endpointHostPrefix $podInt $endpointHostSuffix $endpointPort }} {{- $_ := set $local "endpointCredsAndHosts" ( append $local.endpointCredsAndHosts $endpointCredAndHost ) }} {{- end }} {{- else }} {{- $endpointHost := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{- $endpointCredAndHost := printf "%s:%s@%s:%s" $endpointUser $endpointPass $endpointHost $endpointPort }} {{- $_ := set $local "endpointCredsAndHosts" ( append $local.endpointCredsAndHosts $endpointCredAndHost ) }} {{- end }} {{- $endpointCredsAndHosts := include "helm-toolkit.utils.joinListWithComma" $local.endpointCredsAndHosts }} {{- $endpointPath := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} {{- printf "%s://%s%s" $endpointScheme $endpointCredsAndHosts $endpointPath }} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_endpoint_host_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves either the fully qualified hostname, of if defined in the host field IPv4 for an endpoint. examples: - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: mariadb host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.endpoint_host_lookup" }} return: | mariadb.default.svc.cluster.local - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: host: mariadb host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.endpoint_host_lookup" }} return: | mariadb.default.svc.cluster.local - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: 127.0.0.1 host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.endpoint_host_lookup" }} return: | 127.0.0.1 - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: host: 127.0.0.1 host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.endpoint_host_lookup" }} return: | 127.0.0.1 */}} {{- define "helm-toolkit.endpoints.endpoint_host_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- $endpointScheme := $endpointMap.scheme }} {{- $_ := set $context.Values "__endpointHost" ( index $endpointMap.hosts $endpoint | default $endpointMap.hosts.default ) }} {{- if kindIs "map" $context.Values.__endpointHost }} {{- $_ := set $context.Values "__endpointHost" ( index $context.Values.__endpointHost "host" ) }} {{- end }} {{- $endpointHost := $context.Values.__endpointHost }} {{- if regexMatch "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+" $endpointHost }} {{- $endpointHostname := printf "%s" $endpointHost }} {{- printf "%s" $endpointHostname -}} {{- else }} {{- $endpointHostname := tuple $type $endpoint $context | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- printf "%s" $endpointHostname -}} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_endpoint_port_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves the port for an endpoint values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: port: mysql: default: 3306 usage: | {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} return: | 3306 */}} {{- define "helm-toolkit.endpoints.endpoint_port_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $port := index . 2 -}} {{- $context := index . 3 -}} {{- $typeYamlSafe := $type | replace "-" "_" }} {{- $endpointMap := index $context.Values.endpoints $typeYamlSafe }} {{- $endpointPortMAP := index $endpointMap.port $port }} {{- $endpointPort := index $endpointPortMAP $endpoint | default ( index $endpointPortMAP "default" ) }} {{- printf "%1.f" $endpointPort -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_endpoint_token_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Gets the token for an endpoint values: | endpoints: keystone: auth: admin: token: zh78JzXgw6YUKy2e usage: | {{ tuple "keystone" "admin" . | include "helm-toolkit.endpoints.endpoint_token_lookup" }} return: | zh78JzXgw6YUKy2e */}} {{- define "helm-toolkit.endpoints.endpoint_token_lookup" -}} {{- $type := index . 0 -}} {{- $userName := index . 1 -}} {{- $context := index . 2 -}} {{- $serviceToken := index $context.Values.endpoints ( $type | replace "-" "_" ) "auth" $userName "token" }} {{- printf "%s" $serviceToken -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_host_and_port_endpoint_uri_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves 'hostname:port' for an endpoint, or several hostname:port pairs for statefulset e.g 'hostname1:port1,hostname2:port2,hostname3:port3', examples: - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: mariadb host_fqdn_override: default: null port: mysql: default: 3306 usage: | {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} return: | mariadb.default.svc.cluster.local:3306 - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: 127.0.0.1 host_fqdn_override: default: null port: mysql: default: 3306 usage: | {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} return: | 127.0.0.1:3306 - values: | endpoints: oslo_cache: hosts: default: memcached host_fqdn_override: default: null statefulset: name: openstack-memcached-memcached replicas: 3 port: memcache: default: 11211 usage: | {{ tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} return: | openstack-memcached-memcached-0:11211,openstack-memcached-memcached-1:11211,openstack-memcached-memcached-2:11211 */}} {{- define "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $port := index . 2 -}} {{- $context := index . 3 -}} {{- $ssMap := index $context.Values.endpoints ( $type | replace "-" "_" ) "statefulset" | default false -}} {{- $local := dict "endpointHosts" list -}} {{- $endpointPort := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.endpoint_port_lookup" -}} {{- if $ssMap -}} {{- $endpointHostPrefix := $ssMap.name -}} {{- $endpointHostSuffix := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{- range $podInt := until ( atoi (print $ssMap.replicas ) ) -}} {{- $endpointHostname := printf "%s-%d.%s:%s" $endpointHostPrefix $podInt $endpointHostSuffix $endpointPort -}} {{- $_ := set $local "endpointHosts" ( append $local.endpointHosts $endpointHostname ) -}} {{- end -}} {{- else -}} {{- $endpointHostname := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" -}} {{- $_ := set $local "endpointHosts" ( append $local.endpointHosts (printf "%s:%s" $endpointHostname $endpointPort) ) -}} {{- end -}} {{ include "helm-toolkit.utils.joinListWithComma" $local.endpointHosts }} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_hostname_fqdn_endpoint_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves the fully qualified hostname for an endpoint examples: - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: mariadb host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} return: | mariadb.default.svc.cluster.local - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: mariadb host_fqdn_override: default: mariadb.openstackhelm.openstack.org usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} return: | mariadb.openstackhelm.openstack.org - values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: mariadb host_fqdn_override: default: host: mariadb.openstackhelm.openstack.org usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} return: | mariadb.openstackhelm.openstack.org */}} {{- define "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- $endpointHostNamespaced := tuple $type $endpoint $context | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $endpointClusterHostname := printf "%s.svc.%s" $endpointHostNamespaced $context.Values.endpoints.cluster_domain_suffix }} {{- $_ := set $context.Values "__FQDNendpointHostDefault" ( index $endpointMap.host_fqdn_override "default" | default "" ) }} {{- if kindIs "map" $context.Values.__FQDNendpointHostDefault }} {{- $_ := set $context.Values "__FQDNendpointHostDefault" ( index $context.Values.__FQDNendpointHostDefault "host" ) }} {{- end }} {{- if kindIs "map" (index $endpointMap.host_fqdn_override $endpoint) }} {{- $endpointHostname := index $endpointMap.host_fqdn_override $endpoint "host" | default $context.Values.__FQDNendpointHostDefault | default $endpointClusterHostname }} {{- printf "%s" $endpointHostname -}} {{- else }} {{- $endpointHostname := index $endpointMap.host_fqdn_override $endpoint | default $context.Values.__FQDNendpointHostDefault | default $endpointClusterHostname }} {{- printf "%s" $endpointHostname -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_hostname_namespaced_endpoint_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves the namespace scoped hostname for an endpoint values: | endpoints: oslo_db: hosts: default: mariadb host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} return: | mariadb.default */}} {{- define "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- $namespace := $endpointMap.namespace | default $context.Release.Namespace }} {{- $endpointHost := tuple $type $endpoint $context | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $endpointClusterHostname := printf "%s.%s" $endpointHost $namespace }} {{- printf "%s" $endpointClusterHostname -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_hostname_namespaced_endpoint_namespace_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves the namespace scoped hostname for an endpoint values: | endpoints: oslo_db: hosts: default: mariadb host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_namespace_lookup" }} return: | default */}} {{- define "helm-toolkit.endpoints.hostname_namespaced_endpoint_namespace_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- $namespace := $endpointMap.namespace | default $context.Release.Namespace }} {{- printf "%s" $namespace -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_hostname_short_endpoint_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves the short hostname for an endpoint examples: - values: | endpoints: oslo_db: hosts: default: mariadb host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} return: | mariadb - values: | endpoints: oslo_db: hosts: default: host: mariadb host_fqdn_override: default: null usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} return: | mariadb */}} {{- define "helm-toolkit.endpoints.hostname_short_endpoint_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- $endpointScheme := $endpointMap.scheme }} {{- $_ := set $context.Values "__endpointHost" ( index $endpointMap.hosts $endpoint | default $endpointMap.hosts.default ) }} {{- if kindIs "map" $context.Values.__endpointHost }} {{- $_ := set $context.Values "__endpointHost" ( index $context.Values.__endpointHost "host" ) }} {{- end }} {{- $endpointHost := $context.Values.__endpointHost }} {{- if regexMatch "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+" $endpointHost }} {{- printf "%s" $type -}} {{- else }} {{- $endpointHostname := printf "%s" $endpointHost }} {{- printf "%s" $endpointHostname -}} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_keystone_endpoint_name_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves the service name for an service type values: | endpoints: identity: name: keystone usage: | {{ tuple identity . | include "keystone_endpoint_name_lookup" }} return: | "keystone" */}} {{- define "helm-toolkit.endpoints.keystone_endpoint_name_lookup" -}} {{- $type := index . 0 -}} {{- $context := index . 1 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- $endpointName := index $endpointMap "name" }} {{- $endpointName | quote -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_keystone_endpoint_path_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # FIXME(portdirect): it appears the port input here serves no purpose, # and should be removed. In addition this function is bugged, do we use it? {{/* abstract: | Resolves the path for an endpoint values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: path: default: /dbname port: mysql: default: 3306 usage: | {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} return: | /dbname */}} {{- define "helm-toolkit.endpoints.keystone_endpoint_path_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $port := index . 2 -}} {{- $context := index . 3 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- if kindIs "string" $endpointMap.path }} {{- printf "%s" $endpointMap.path | default "" -}} {{- else -}} {{- $endpointPath := index $endpointMap.path $endpoint | default $endpointMap.path.default | default "" }} {{- printf "%s" $endpointPath -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_keystone_endpoint_scheme_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # FIXME(portdirect): it appears the port input here serves no purpose, # and should be removed. In addition this function is bugged, do we use it? {{/* abstract: | Resolves the scheme for an endpoint values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: scheme: default: mysql+pymysql port: mysql: default: 3306 usage: | {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} return: | mysql+pymysql */}} # This function returns the scheme for a service, it takes an tuple # input in the form: service-type, endpoint-class, port-name. eg: # { tuple "etcd" "internal" "client" . | include "helm-toolkit.endpoints.keystone_scheme_lookup" } # will return the scheme setting for this particular endpoint. In other words, for most endpoints # it will return either 'http' or 'https' {{- define "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $port := index . 2 -}} {{- $context := index . 3 -}} {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }} {{- if kindIs "string" $endpointMap.scheme }} {{- printf "%s" $endpointMap.scheme | default "http" -}} {{- else -}} {{- $endpointScheme := index $endpointMap.scheme $endpoint | default $endpointMap.scheme.default | default "http" }} {{- printf "%s" $endpointScheme -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_keystone_endpoint_uri_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | This function helps resolve uri style endpoints. It will omit the port for http when 80 is used, and 443 in the case of https. values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: mariadb host_fqdn_override: default: null path: /dbname scheme: mysql+pymysql port: mysql: default: 3306 usage: | {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} return: | mysql+pymysql://mariadb.default.svc.cluster.local:3306/dbname */}} {{- define "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $port := index . 2 -}} {{- $context := index . 3 -}} {{- $endpointScheme := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $endpointHost := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{- $endpointPort := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $endpointPath := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} {{- if or ( and ( eq $endpointScheme "http" ) ( eq $endpointPort "80" ) ) ( and ( eq $endpointScheme "https" ) ( eq $endpointPort "443" ) ) -}} {{- printf "%s://%s%s" $endpointScheme $endpointHost $endpointPath -}} {{- else -}} {{- printf "%s://%s:%s%s" $endpointScheme $endpointHost $endpointPort $endpointPath -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/endpoints/_service_name_endpoint_with_namespace_lookup.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | This function returns endpoint ":" pair from an endpoint definition. This is used in kubernetes-entrypoint to support dependencies between different services in different namespaces. returns: the endpoint namespace and the service name, delimited by a colon Normally, the service name is constructed dynamically from the hostname however when an ip address is used as the hostname, we default to namespace:endpointCategoryName in order to construct a valid service name however this can be overridden to a custom service name by defining .service.name within the endpoint definition values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: namespace: foo hosts: default: mariadb host_fqdn_override: default: null usage: | {{ tuple oslo_db internal . | include "helm-toolkit.endpoints.service_name_endpoint_with_namespace_lookup" }} return: | foo:mariadb */}} {{- define "helm-toolkit.endpoints.service_name_endpoint_with_namespace_lookup" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $typeYamlSafe := $type | replace "-" "_" }} {{- $endpointMap := index $context.Values.endpoints $typeYamlSafe }} {{- with $endpointMap -}} {{- $endpointName := index .hosts $endpoint | default .hosts.default }} {{- $endpointNamespace := .namespace | default $context.Release.Namespace }} {{- if regexMatch "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+" $endpointName }} {{- if .service.name }} {{- printf "%s:%s" $endpointNamespace .service.name -}} {{- else -}} {{- printf "%s:%s" $endpointNamespace $typeYamlSafe -}} {{- end -}} {{- else -}} {{- printf "%s:%s" $endpointNamespace $endpointName -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_ceph-storageclass.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Creates a manifest for kubernete ceph storageclass examples: - values: | manifests: storageclass: true storageclass: rbd: provision_storage_class: true provisioner: "ceph.com/rbd" metadata: default_storage_class: true name: general parameters: #We will grab the monitors value based on helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup pool: rbd admin_id: admin ceph_configmap_name: "ceph-etc" admin_secret_name: "pvc-ceph-conf-combined-storageclass" admin_secret_namespace: ceph user_id: admin user_secret_name: "pvc-ceph-client-key" image_format: "2" image_features: layering cephfs: provision_storage_class: true provisioner: "ceph.com/cephfs" metadata: name: cephfs parameters: admin_id: admin admin_secret_name: "pvc-ceph-cephfs-client-key" admin_secret_namespace: ceph usage: | {{- range $storageclass, $val := .Values.storageclass }} {{ dict "storageclass_data" $val "envAll" $ | include "helm-toolkit.manifests.ceph-storageclass" }} {{- end }} return: | --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: annotations: storageclass.kubernetes.io/is-default-class: "true" name: general provisioner: ceph.com/rbd parameters: monitors: ceph-mon..svc.:6789 adminId: admin adminSecretName: pvc-ceph-conf-combined-storageclass adminSecretNamespace: ceph pool: rbd userId: admin userSecretName: pvc-ceph-client-key image_format: "2" image_features: layering --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: cephfs provisioner: ceph.com/cephfs parameters: monitors: ceph-mon..svc.:6789 adminId: admin adminSecretName: pvc-ceph-cephfs-client-key adminSecretNamespace: ceph */}} {{- define "helm-toolkit.manifests.ceph-storageclass" -}} {{- $envAll := index . "envAll" -}} {{- $monHost := $envAll.Values.conf.ceph.global.mon_host -}} {{- if empty $monHost -}} {{- $monHost = tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" -}} {{- end -}} {{- $storageclassData := index . "storageclass_data" -}} --- {{- if $storageclassData.provision_storage_class }} apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: {{- if $storageclassData.metadata.default_storage_class }} annotations: storageclass.kubernetes.io/is-default-class: "true" {{- end }} name: {{ $storageclassData.metadata.name }} provisioner: {{ $storageclassData.provisioner }} parameters: monitors: {{ $monHost }} {{- range $attr, $value := $storageclassData.parameters }} {{ $attr }}: {{ $value | quote }} {{- end }} allowVolumeExpansion: true {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_certificates.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Creates a certificate using jetstack examples: - values: | endpoints: dashboard: host_fqdn_override: default: host: null tls: secretName: keystone-tls-api issuerRef: name: ca-issuer duration: 2160h organization: - ACME commonName: keystone-api.openstack.svc.cluster.local privateKey: size: 2048 usages: - server auth - client auth dnsNames: - cluster.local issuerRef: name: ca-issuer usage: | {{- $opts := dict "envAll" . "service" "dashboard" "type" "internal" -}} {{ $opts | include "helm-toolkit.manifests.certificates" }} return: | --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: keystone-tls-api namespace: NAMESPACE spec: commonName: keystone-api.openstack.svc.cluster.local dnsNames: - cluster.local duration: 2160h issuerRef: name: ca-issuer privateKey: size: 2048 organization: - ACME secretName: keystone-tls-api usages: - server auth - client auth */}} {{- define "helm-toolkit.manifests.certificates" -}} {{- $envAll := index . "envAll" -}} {{- $service := index . "service" -}} {{- $type := index . "type" | default "" -}} {{- $slice := index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls" -}} {{/* Put in some sensible default value if one is not provided by values.yaml */}} {{/* If a dnsNames list is not in the values.yaml, it can be overridden by a passed-in parameter. This allows user to use other HTK method to determine the URI and pass that into this method.*/}} {{- if not (hasKey $slice "dnsNames") -}} {{- $hostName := tuple $service $type $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" -}} {{- $dnsNames := list $hostName (printf "%s.%s" $hostName $envAll.Release.Namespace) (printf "%s.%s.svc.%s" $hostName $envAll.Release.Namespace $envAll.Values.endpoints.cluster_domain_suffix) -}} {{- $_ := $dnsNames | set (index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls") "dnsNames" -}} {{- end -}} {{/* Default privateKey size to 4096. This can be overridden. */}} {{- if not (hasKey $slice "privateKey") -}} {{- $_ := dict "size" ( printf "%d" 4096 | atoi ) | set (index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls") "privateKey" -}} {{- else if empty (index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls" "privateKey" "size") -}} {{- $_ := ( printf "%d" 4096 | atoi ) | set (index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls" "privateKey") "size" -}} {{- end -}} {{/* Default duration to 3 months. Note the min is 720h. This can be overridden. */}} {{- if not (hasKey $slice "duration") -}} {{- $_ := printf "%s" "2190h" | set (index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls") "duration" -}} {{- end -}} {{/* Default renewBefore to 15 days. This can be overridden. */}} {{- if not (hasKey $slice "renewBefore") -}} {{- $_ := printf "%s" "360h" | set (index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls") "renewBefore" -}} {{- end -}} {{/* Default the usage to server auth and client auth. This can be overridden. */}} {{- if not (hasKey $slice "usages") -}} {{- $_ := (list "server auth" "client auth") | set (index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls") "usages" -}} {{- end -}} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: {{ index $envAll.Values.endpoints $service "host_fqdn_override" "default" "tls" "secretName" }} namespace: {{ $envAll.Release.Namespace }} spec: {{ $slice | toYaml | indent 2 }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_configmap-oslo-policy.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders out the configmap -oslo-policy. values: | conf: policy.d: file1: foo: bar file2: foo: baz usage: | {{- include "helm-toolkit.manifests.configmap_oslo_policy" (dict "envAll" $envAll "serviceName" "keystone") }} return: | --- apiVersion: v1 kind: Secret metadata: name: keystone-oslo-policy data: file1: base64of(foo: bar) file2: base64of(foo: baz) */}} {{- define "helm-toolkit.manifests.configmap_oslo_policy" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $serviceName }}-oslo-policy type: Opaque data: {{- range $key, $value := index $envAll.Values.conf "policy.d" }} {{- if $value }} {{ $key }}: {{ toYaml $value | b64enc }} {{- else }} {{ $key }}: {{ "\n" | b64enc }} {{- end }} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_ingress.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Creates a manifest for a services ingress rules. examples: - values: | network: api: ingress: public: true classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / secrets: tls: key_manager: api: public: barbican-tls-public endpoints: cluster_domain_suffix: cluster.local key_manager: name: barbican hosts: default: barbican-api public: barbican host_fqdn_override: default: null public: host: barbican.openstackhelm.example tls: crt: | FOO-CRT key: | FOO-KEY ca: | FOO-CA_CRT path: default: / scheme: default: http public: https port: api: default: 9311 public: 80 usage: | {{- include "helm-toolkit.manifests.ingress" ( dict "envAll" . "backendServiceType" "key-manager" "backendPort" "b-api" "endpoint" "public" "pathType" "Prefix" ) -}} return: | --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: barbican annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx" rules: - host: barbican http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default.svc.cluster.local http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: barbican-namespace-fqdn annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx" tls: - secretName: barbican-tls-public hosts: - barbican.openstackhelm.example rules: - host: barbican.openstackhelm.example http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: barbican-cluster-fqdn annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx-cluster" tls: - secretName: barbican-tls-public hosts: - barbican.openstackhelm.example rules: - host: barbican.openstackhelm.example http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - values: | network: api: ingress: public: true classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / secrets: tls: key_manager: api: public: barbican-tls-public endpoints: cluster_domain_suffix: cluster.local key_manager: name: barbican hosts: default: barbican-api public: host: barbican tls: crt: | FOO-CRT key: | FOO-KEY ca: | FOO-CA_CRT host_fqdn_override: default: null path: default: / scheme: default: http public: https port: api: default: 9311 public: 80 usage: | {{- include "helm-toolkit.manifests.ingress" ( dict "envAll" . "backendServiceType" "key-manager" "backendPort" "b-api" "endpoint" "public" "pathType" "Prefix" ) -}} return: | --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: barbican annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx" tls: - secretName: barbican-tls-public hosts: - barbican - barbican.default - barbican.default.svc.cluster.local rules: - host: barbican http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default.svc.cluster.local http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - values: | cert_issuer_type: issuer network: api: ingress: public: true classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/secure-backends: "true" nginx.ingress.kubernetes.io/backend-protocol: "https" secrets: tls: key_manager: api: public: barbican-tls-public internal: barbican-tls-api endpoints: cluster_domain_suffix: cluster.local key_manager: name: barbican hosts: default: barbican-api public: host: barbican tls: crt: | FOO-CRT key: | FOO-KEY ca: | FOO-CA_CRT host_fqdn_override: default: null path: default: / scheme: default: http public: https port: api: default: 9311 public: 80 certs: barbican_tls_api: secretName: barbican-tls-api issuerRef: name: ca-issuer kind: Issuer usage: | {{- include "helm-toolkit.manifests.ingress" ( dict "envAll" . "backendServiceType" "key-manager" "backendPort" "b-api" "endpoint" "public" "certIssuer" "ca-issuer" "pathType" "Prefix" ) -}} return: | --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: barbican annotations: cert-manager.io/issuer: ca-issuer certmanager.k8s.io/issuer: ca-issuer nginx.ingress.kubernetes.io/backend-protocol: https nginx.ingress.kubernetes.io/secure-backends: "true" spec: ingressClassName: "nginx" tls: - secretName: barbican-tls-public-certmanager hosts: - barbican - barbican.default - barbican.default.svc.cluster.local rules: - host: barbican http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default.svc.cluster.local http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - values: | network: api: ingress: public: true classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/secure-backends: "true" nginx.ingress.kubernetes.io/backend-protocol: "https" secrets: tls: key_manager: api: public: barbican-tls-public internal: barbican-tls-api endpoints: cluster_domain_suffix: cluster.local key_manager: name: barbican hosts: default: barbican-api public: host: barbican tls: crt: | FOO-CRT key: | FOO-KEY ca: | FOO-CA_CRT host_fqdn_override: default: null path: default: / scheme: default: http public: https port: api: default: 9311 public: 80 certs: barbican_tls_api: secretName: barbican-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer usage: | {{- include "helm-toolkit.manifests.ingress" ( dict "envAll" . "backendServiceType" "key-manager" "backendPort" "b-api" "endpoint" "public" "certIssuer" "ca-issuer" "pathType" "Prefix" ) -}} return: | --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: barbican annotations: cert-manager.io/cluster-issuer: ca-issuer certmanager.k8s.io/cluster-issuer: ca-issuer nginx.ingress.kubernetes.io/backend-protocol: https nginx.ingress.kubernetes.io/secure-backends: "true" spec: ingressClassName: "nginx" tls: - secretName: barbican-tls-public-certmanager hosts: - barbican - barbican.default - barbican.default.svc.cluster.local rules: - host: barbican http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api - host: barbican.default.svc.cluster.local http: paths: - path: / pathType: Prefix backend: service: name: barbican-api port: name: b-api # Sample usage for multiple DNS names associated with the same public # endpoint and certificate - values: | endpoints: cluster_domain_suffix: cluster.local grafana: name: grafana hosts: default: grafana-dashboard public: grafana host_fqdn_override: public: host: grafana.openstackhelm.example tls: dnsNames: - grafana-alt.openstackhelm.example crt: "BASE64 ENCODED CERT" key: "BASE64 ENCODED KEY" network: grafana: ingress: classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / secrets: tls: grafana: grafana: public: grafana-tls-public usage: | {{- $ingressOpts := dict "envAll" . "backendService" "grafana" "backendServiceType" "grafana" "backendPort" "dashboard" "pathType" "Prefix" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} return: | --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx" rules: - host: grafana http: paths: - path: / pathType: Prefix backend: service: name: grafana-dashboard port: name: dashboard - host: grafana.default http: paths: - path: / pathType: Prefix backend: service: name: grafana-dashboard port: name: dashboard - host: grafana.default.svc.cluster.local http: paths: - path: / pathType: Prefix backend: service: name: grafana-dashboard port: name: dashboard --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana-namespace-fqdn annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx" tls: - secretName: grafana-tls-public hosts: - grafana.openstackhelm.example - grafana-alt.openstackhelm.example rules: - host: grafana.openstackhelm.example http: paths: - path: / pathType: Prefix backend: service: name: grafana-dashboard port: name: dashboard - host: grafana-alt.openstackhelm.example http: paths: - path: / pathType: Prefix backend: service: name: grafana-dashboard port: name: dashboard --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: grafana-cluster-fqdn annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx-cluster" tls: - secretName: grafana-tls-public hosts: - grafana.openstackhelm.example - grafana-alt.openstackhelm.example rules: - host: grafana.openstackhelm.example http: paths: - path: / pathType: Prefix backend: service: name: grafana-dashboard port: name: dashboard - host: grafana-alt.openstackhelm.example http: paths: - path: / pathType: Prefix backend: service: name: grafana-dashboard port: name: dashboard # Sample usage for custom ingressPaths (multiple paths) - values: | network: api: ingress: public: true classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / secrets: tls: identity: api: public: keystone-tls-public endpoints: cluster_domain_suffix: cluster.local identity: name: keystone hosts: default: keystone-api public: keystone host_fqdn_override: default: null path: default: /v3 scheme: default: http public: https port: api: default: 5000 public: 80 usage: | {{- include "helm-toolkit.manifests.ingress" ( dict "envAll" . "backendServiceType" "identity" "backendPort" "ks-pub" "endpoint" "public" "ingressPaths" (list "/v3" "/v2.0") "pathType" "Prefix" ) -}} return: | --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: keystone annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx" rules: - host: keystone http: paths: - path: /v3 pathType: Prefix backend: service: name: keystone-api port: name: ks-pub - path: /v2.0 pathType: Prefix backend: service: name: keystone-api port: name: ks-pub - host: keystone.default http: paths: - path: /v3 pathType: Prefix backend: service: name: keystone-api port: name: ks-pub - path: /v2.0 pathType: Prefix backend: service: name: keystone-api port: name: ks-pub - host: keystone.default.svc.cluster.local http: paths: - path: /v3 pathType: Prefix backend: service: name: keystone-api port: name: ks-pub - path: /v2.0 pathType: Prefix backend: service: name: keystone-api port: name: ks-pub # Sample usage for additionalBackends (multiple backends with different paths) - values: | network: api: ingress: public: true classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / secrets: tls: shipyard: api: public: shipyard-tls-public endpoints: cluster_domain_suffix: cluster.local shipyard: name: shipyard hosts: default: shipyard-int public: shipyard host_fqdn_override: default: null path: default: /api/v1.0 scheme: default: http public: https port: api: default: 9000 public: 80 airflow_web: name: airflow-web hosts: default: airflow-web-int public: airflow-web host_fqdn_override: default: null path: default: /airflow scheme: default: http port: api: default: 8080 usage: | {{- include "helm-toolkit.manifests.ingress" ( dict "envAll" . "backendServiceType" "shipyard" "backendPort" "api" "endpoint" "public" "pathType" "Prefix" "additionalBackends" (list (dict "backendServiceType" "airflow-web" "backendPort" "api")) ) -}} return: | --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: shipyard annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: "nginx" rules: - host: shipyard http: paths: - path: /api/v1.0 pathType: Prefix backend: service: name: shipyard-int port: name: api - path: /airflow pathType: Prefix backend: service: name: airflow-web-int port: name: api - host: shipyard.default http: paths: - path: /api/v1.0 pathType: Prefix backend: service: name: shipyard-int port: name: api - path: /airflow pathType: Prefix backend: service: name: airflow-web-int port: name: api - host: shipyard.default.svc.cluster.local http: paths: - path: /api/v1.0 pathType: Prefix backend: service: name: shipyard-int port: name: api - path: /airflow pathType: Prefix backend: service: name: airflow-web-int port: name: api */}} {{- define "helm-toolkit.manifests.ingress._host_rules" -}} {{- $vHost := index . "vHost" -}} {{- $backendName := index . "backendName" -}} {{- $backendPort := index . "backendPort" -}} {{- $pathType := index . "pathType" -}} {{- $ingressPaths := index . "ingressPaths" | default "/" -}} {{- if kindIs "string" $ingressPaths -}} {{- $ingressPaths = list $ingressPaths -}} {{- end -}} {{- $additionalBackends := index . "additionalBackends" | default list -}} - host: {{ $vHost }} http: paths: {{- range $p := $ingressPaths }} {{- if kindIs "map" $p }} - path: {{ $p.path }} pathType: {{ $p.pathType | default $pathType }} {{- else }} - path: {{ $p }} pathType: {{ $pathType }} {{- end }} backend: service: name: {{ $backendName }} port: {{- if or (kindIs "int" $backendPort) (regexMatch "^[0-9]{1,5}$" $backendPort) }} number: {{ $backendPort | int }} {{- else }} name: {{ $backendPort | quote }} {{- end }} {{- end }} {{- range $ab := $additionalBackends }} {{- $abPaths := $ab.ingressPaths | default "/" -}} {{- if kindIs "string" $abPaths -}} {{- $abPaths = list $abPaths -}} {{- end -}} {{- range $p := $abPaths }} {{- if kindIs "map" $p }} - path: {{ $p.path }} pathType: {{ $p.pathType | default $pathType }} {{- else }} - path: {{ $p }} pathType: {{ $pathType }} {{- end }} backend: service: name: {{ $ab.backendName }} port: {{- if or (kindIs "int" $ab.backendPort) (regexMatch "^[0-9]{1,5}$" $ab.backendPort) }} number: {{ $ab.backendPort | int }} {{- else }} name: {{ $ab.backendPort | quote }} {{- end }} {{- end }} {{- end }} {{- end }} {{- define "helm-toolkit.manifests.ingress" -}} {{- $envAll := index . "envAll" -}} {{- $backendService := index . "backendService" | default "api" -}} {{- $backendServiceType := index . "backendServiceType" -}} {{- $backendPort := index . "backendPort" -}} {{- $endpoint := index . "endpoint" | default "public" -}} {{- $pathType := index . "pathType" | default "Prefix" -}} {{- $certIssuer := index . "certIssuer" | default "" -}} {{- $ingressPaths := index . "ingressPaths" | default "/" -}} {{- $additionalBackendsInput := index . "additionalBackends" | default list -}} {{- $additionalBackends := list -}} {{- range $ab := $additionalBackendsInput -}} {{- $abServiceType := $ab.backendServiceType -}} {{- $abBackendName := tuple $abServiceType "internal" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" -}} {{- $abBackendPort := $ab.backendPort -}} {{- $abPaths := "" -}} {{- $abEndpointMap := index $envAll.Values.endpoints ( $abServiceType | replace "-" "_" ) -}} {{- if hasKey $abEndpointMap "path" -}} {{- if kindIs "string" $abEndpointMap.path -}} {{- $abPaths = $abEndpointMap.path -}} {{- else if kindIs "map" $abEndpointMap.path -}} {{- if hasKey $abEndpointMap.path "default" -}} {{- $abPaths = index $abEndpointMap.path "default" -}} {{- end -}} {{- end -}} {{- end -}} {{- if not $abPaths -}} {{- $abPaths = "/" -}} {{- end -}} {{- $additionalBackends = append $additionalBackends (dict "backendName" $abBackendName "backendPort" $abBackendPort "ingressPaths" $abPaths) -}} {{- end -}} {{- $ingressName := tuple $backendServiceType $endpoint $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $backendName := tuple $backendServiceType "internal" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $hostName := tuple $backendServiceType $endpoint $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $hostNameFull := tuple $backendServiceType $endpoint $envAll | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- $certIssuerType := "cluster-issuer" -}} {{- if $envAll.Values.cert_issuer_type }} {{- $certIssuerType = $envAll.Values.cert_issuer_type }} {{- end }} --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ $ingressName }} annotations: {{- if $certIssuer }} cert-manager.io/{{ $certIssuerType }}: {{ $certIssuer }} certmanager.k8s.io/{{ $certIssuerType }}: {{ $certIssuer }} {{- $slice := index $envAll.Values.endpoints $backendServiceType "host_fqdn_override" "default" "tls" -}} {{- if (hasKey $slice "duration") }} cert-manager.io/duration: {{ index $slice "duration" }} {{- end }} {{- end }} {{ toYaml (index $envAll.Values.network $backendService "ingress" "annotations") | indent 4 }} spec: ingressClassName: {{ index $envAll.Values.network $backendService "ingress" "classes" "namespace" | quote }} {{- $host := index $envAll.Values.endpoints ( $backendServiceType | replace "-" "_" ) "hosts" }} {{- if $certIssuer }} {{- $secretName := index $envAll.Values.secrets "tls" ( $backendServiceType | replace "-" "_" ) $backendService $endpoint }} {{- $_ := required "You need to specify a secret in your values for the endpoint" $secretName }} tls: - secretName: {{ printf "%s-ing" $secretName }} hosts: {{- range $key1, $vHost := tuple $hostName (printf "%s.%s" $hostName $envAll.Release.Namespace) (printf "%s.%s.svc.%s" $hostName $envAll.Release.Namespace $envAll.Values.endpoints.cluster_domain_suffix) }} - {{ $vHost }} {{- end }} {{- else }} {{- if hasKey $host $endpoint }} {{- $endpointHost := index $host $endpoint }} {{- if kindIs "map" $endpointHost }} {{- if hasKey $endpointHost "tls" }} {{- if and ( not ( empty $endpointHost.tls.key ) ) ( not ( empty $endpointHost.tls.crt ) ) }} {{- $secretName := index $envAll.Values.secrets "tls" ( $backendServiceType | replace "-" "_" ) $backendService $endpoint }} {{- $_ := required "You need to specify a secret in your values for the endpoint" $secretName }} tls: - secretName: {{ $secretName }} hosts: {{- range $key1, $vHost := tuple $hostName (printf "%s.%s" $hostName $envAll.Release.Namespace) (printf "%s.%s.svc.%s" $hostName $envAll.Release.Namespace $envAll.Values.endpoints.cluster_domain_suffix) }} - {{ $vHost }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} rules: {{- range $key1, $vHost := tuple $hostName (printf "%s.%s" $hostName $envAll.Release.Namespace) (printf "%s.%s.svc.%s" $hostName $envAll.Release.Namespace $envAll.Values.endpoints.cluster_domain_suffix) }} {{- $hostRules := dict "vHost" $vHost "backendName" $backendName "backendPort" $backendPort "pathType" $pathType "ingressPaths" $ingressPaths "additionalBackends" $additionalBackends }} {{ $hostRules | include "helm-toolkit.manifests.ingress._host_rules" | indent 4 }} {{- end }} {{- if not ( hasSuffix ( printf ".%s.svc.%s" $envAll.Release.Namespace $envAll.Values.endpoints.cluster_domain_suffix) $hostNameFull) }} {{- $ingressConf := $envAll.Values.network -}} {{- $ingressClasses := ternary (tuple "namespace") (tuple "namespace" "cluster") (and (hasKey $ingressConf "use_external_ingress_controller") $ingressConf.use_external_ingress_controller) }} {{- range $key2, $ingressController := $ingressClasses }} {{- $vHosts := list $hostNameFull }} --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ printf "%s-%s-%s" $ingressName $ingressController "fqdn" }} annotations: {{ toYaml (index $envAll.Values.network $backendService "ingress" "annotations") | indent 4 }} spec: ingressClassName: {{ index $envAll.Values.network $backendService "ingress" "classes" $ingressController | quote }} {{- $host := index $envAll.Values.endpoints ( $backendServiceType | replace "-" "_" ) "host_fqdn_override" }} {{- if hasKey $host $endpoint }} {{- $endpointHost := index $host $endpoint }} {{- if kindIs "map" $endpointHost }} {{- if hasKey $endpointHost "tls" }} {{- range $v := without (index $endpointHost.tls "dnsNames" | default list) $hostNameFull }} {{- $vHosts = append $vHosts $v }} {{- end }} {{- if hasKey $envAll.Values.endpoints "alias_fqdn" }} {{- $alias_host := $envAll.Values.endpoints.alias_fqdn }} {{- $vHosts = append $vHosts $alias_host }} {{- end }} {{- $secretName := index $envAll.Values.secrets "tls" ( $backendServiceType | replace "-" "_" ) $backendService $endpoint }} {{- $_ := required "You need to specify a secret in your values for the endpoint" $secretName }} tls: - secretName: {{ $secretName }} hosts: {{- range $vHost := $vHosts }} - {{ $vHost }} {{- end }} {{- end }} {{- end }} {{- end }} rules: {{- range $vHost := $vHosts }} {{- $hostNameFullRules := dict "vHost" $vHost "backendName" $backendName "backendPort" $backendPort "pathType" $pathType "ingressPaths" $ingressPaths "additionalBackends" $additionalBackends }} {{ $hostNameFullRules | include "helm-toolkit.manifests.ingress._host_rules" | indent 4 }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_job-bootstrap.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for db creation and user management. # It can be used in charts dict created similar to the following: # {- $bootstrapJob := dict "envAll" . "serviceName" "senlin" -} # { $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" } {{- define "helm-toolkit.manifests.job_bootstrap" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobNameRef := printf "%s_%s" $serviceName "bootstrap" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $podVolMounts := index . "podVolMounts" | default (dig $jobNameRef $jobNameRef "volumeMounts" false $envAll.Values.pod.mounts) -}} {{- $podVols := index . "podVols" | default (dig $jobNameRef $jobNameRef "volumes" false $envAll.Values.pod.mounts) -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $configMapEtc := index . "configMapEtc" | default (printf "%s-%s" $serviceName "etc" ) -}} {{- $configFile := index . "configFile" | default (printf "/etc/%s/%s.conf" $serviceName $serviceName ) -}} {{- $logConfigFile := index . "logConfigFile" | default (printf "/etc/%s/logging.conf" $serviceName ) -}} {{- $tlsSecret := index . "tlsSecret" | default "" -}} {{- $keystoneUser := index . "keystoneUser" | default $serviceName -}} {{- $openrc := index . "openrc" | default "true" -}} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "bootstrap" | quote }} labels: {{ tuple $envAll $serviceName "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: {{ tuple "bootstrap" $envAll | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "bootstrap" $envAll | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ tuple $envAll "bootstrap" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: bootstrap image: {{ $envAll.Values.images.tags.bootstrap }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{- if eq $openrc "true" }} env: {{- with $env := dict "ksUserSecret" ( index $envAll.Values.secrets.identity $keystoneUser ) "useCA" (ne $tlsSecret "") }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} {{- end }} command: - /bin/bash - -c - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: bootstrap-sh mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true - name: etc-service mountPath: {{ dir $configFile | quote }} - name: bootstrap-conf mountPath: {{ $configFile | quote }} subPath: {{ base $configFile | quote }} readOnly: true - name: bootstrap-conf mountPath: {{ $logConfigFile | quote }} subPath: {{ base $logConfigFile | quote }} readOnly: true {{ dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- if $podVolMounts }} {{ $podVolMounts | toYaml | indent 12 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: bootstrap-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} - name: etc-service emptyDir: {} - name: bootstrap-conf secret: secretName: {{ $configMapEtc | quote }} defaultMode: 0444 {{- dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- if $podVols }} {{ $podVols | toYaml | indent 8 }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_job-db-drop-mysql.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for db creation and user management. # It can be used in charts dict created similar to the following: # {- $dbToDropJob := dict "envAll" . "serviceName" "senlin" -} # { $dbToDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" } # # If the service does not use oslo then the db can be managed with: # {- $dbToDrop := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.horizon -} # {- $dbToDropJob := dict "envAll" . "serviceName" "horizon" "dbToDrop" $dbToDrop -} # { $dbToDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" } {{- define "helm-toolkit.manifests.job_db_drop_mysql" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $configMapEtc := index . "configMapEtc" | default (printf "%s-%s" $serviceName "etc" ) -}} {{- $dbToDrop := index . "dbToDrop" | default ( dict "adminSecret" $envAll.Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" ) -}} {{- $dbsToDrop := default (list $dbToDrop) (index . "dbsToDrop") }} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $dbAdminTlsSecret := index . "dbAdminTlsSecret" | default "" -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "db-drop" }} {{ tuple $envAll "db_drop" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "db-drop" | quote }} labels: {{ tuple $envAll $serviceName "db-drop" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: "helm.sh/hook": pre-delete "helm.sh/hook-delete-policy": hook-succeeded {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "db-drop" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ tuple $envAll "db_drop" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "db_drop" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{- range $key1, $dbToDrop := $dbsToDrop }} {{ $dbToDropType := default "oslo" $dbToDrop.inputType }} - name: {{ printf "%s-%s-%d" $serviceNamePretty "db-drop" $key1 | quote }} image: {{ $envAll.Values.images.tags.db_drop }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_drop | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: ROOT_DB_CONNECTION valueFrom: secretKeyRef: name: {{ $dbToDrop.adminSecret | quote }} key: DB_CONNECTION {{- if eq $dbToDropType "oslo" }} - name: OPENSTACK_CONFIG_FILE value: {{ $dbToDrop.configFile | quote }} - name: OPENSTACK_CONFIG_DB_SECTION value: {{ $dbToDrop.configDbSection | quote }} - name: OPENSTACK_CONFIG_DB_KEY value: {{ $dbToDrop.configDbKey | quote }} {{- end }} {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} {{- if eq $dbToDropType "secret" }} - name: DB_CONNECTION valueFrom: secretKeyRef: name: {{ $dbToDrop.userSecret | quote }} key: DB_CONNECTION {{- end }} command: - /tmp/db-drop.py volumeMounts: - name: pod-tmp mountPath: /tmp - name: db-drop-sh mountPath: /tmp/db-drop.py subPath: db-drop.py readOnly: true {{- if eq $dbToDropType "oslo" }} - name: etc-service mountPath: {{ dir $dbToDrop.configFile | quote }} - name: db-drop-conf mountPath: {{ $dbToDrop.configFile | quote }} subPath: {{ base $dbToDrop.configFile | quote }} readOnly: true - name: db-drop-conf mountPath: {{ $dbToDrop.logConfigFile | quote }} subPath: {{ base $dbToDrop.logConfigFile | quote }} readOnly: true {{- end }} {{- if $envAll.Values.manifests.certificates }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $dbAdminTlsSecret "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: db-drop-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} {{- if $envAll.Values.manifests.certificates }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $dbAdminTlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} {{- $local := dict "configMapBinFirst" true -}} {{- range $key1, $dbToDrop := $dbsToDrop }} {{- $dbToDropType := default "oslo" $dbToDrop.inputType }} {{- if and (eq $dbToDropType "oslo") $local.configMapBinFirst }} {{- $_ := set $local "configMapBinFirst" false }} - name: etc-service emptyDir: {} - name: db-drop-conf secret: secretName: {{ $configMapEtc | quote }} defaultMode: 0444 {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_job-db-init-mysql.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for db creation and user management. # It can be used in charts dict created similar to the following: # {- $dbToInitJob := dict "envAll" . "serviceName" "senlin" -} # { $dbToInitJob | include "helm-toolkit.manifests.job_db_init_mysql" } # # If the service does not use oslo then the db can be managed with: # {- $dbToInit := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.horizon -} # {- $dbToInitJob := dict "envAll" . "serviceName" "horizon" "dbToInit" $dbToInit -} # { $dbToInitJob | include "helm-toolkit.manifests.job_db_init_mysql" } {{- define "helm-toolkit.manifests.job_db_init_mysql" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $configMapEtc := index . "configMapEtc" | default (printf "%s-%s" $serviceName "etc" ) -}} {{- $dbToInit := index . "dbToInit" | default ( dict "adminSecret" $envAll.Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" ) -}} {{- $dbsToInit := default (list $dbToInit) (index . "dbsToInit") }} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $dbAdminTlsSecret := index . "dbAdminTlsSecret" | default "" -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "db-init" }} {{ tuple $envAll "db_init" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "db-init" | quote }} labels: {{ tuple $envAll $serviceName "db-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "db-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: {{ tuple "db_init" $envAll | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "db_init" $envAll | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ tuple $envAll "db_init" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "db_init" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{- range $key1, $dbToInit := $dbsToInit }} {{ $dbToInitType := default "oslo" $dbToInit.inputType }} - name: {{ printf "%s-%s-%d" $serviceNamePretty "db-init" $key1 | quote }} image: {{ $envAll.Values.images.tags.db_init }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_init | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: ROOT_DB_CONNECTION valueFrom: secretKeyRef: name: {{ $dbToInit.adminSecret | quote }} key: DB_CONNECTION {{- if eq $dbToInitType "oslo" }} - name: OPENSTACK_CONFIG_FILE value: {{ $dbToInit.configFile | quote }} - name: OPENSTACK_CONFIG_DB_SECTION value: {{ $dbToInit.configDbSection | quote }} - name: OPENSTACK_CONFIG_DB_KEY value: {{ $dbToInit.configDbKey | quote }} {{- end }} {{- if eq $dbToInitType "secret" }} - name: DB_CONNECTION valueFrom: secretKeyRef: name: {{ $dbToInit.userSecret | quote }} key: DB_CONNECTION {{- end }} {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} command: - /tmp/db-init.py volumeMounts: - name: pod-tmp mountPath: /tmp - name: db-init-sh mountPath: /tmp/db-init.py subPath: db-init.py readOnly: true {{- if eq $dbToInitType "oslo" }} - name: etc-service mountPath: {{ dir $dbToInit.configFile | quote }} - name: db-init-conf mountPath: {{ $dbToInit.configFile | quote }} subPath: {{ base $dbToInit.configFile | quote }} readOnly: true - name: db-init-conf mountPath: {{ $dbToInit.logConfigFile | quote }} subPath: {{ base $dbToInit.logConfigFile | quote }} readOnly: true {{- end }} {{- if $envAll.Values.manifests.certificates }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $dbAdminTlsSecret "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: db-init-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} {{- if $envAll.Values.manifests.certificates }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $dbAdminTlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} {{- $local := dict "configMapBinFirst" true -}} {{- range $key1, $dbToInit := $dbsToInit }} {{- $dbToInitType := default "oslo" $dbToInit.inputType }} {{- if and (eq $dbToInitType "oslo") $local.configMapBinFirst }} {{- $_ := set $local "configMapBinFirst" false }} - name: etc-service emptyDir: {} - name: db-init-conf secret: secretName: {{ $configMapEtc | quote }} defaultMode: 0444 {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_job-db-sync.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for db migration and management. # It can be used in charts dict created similar to the following: # {- $dbSyncJob := dict "envAll" . "serviceName" "senlin" -} # { $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" } {{- define "helm-toolkit.manifests.job_db_sync" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobNameRef := printf "%s_%s" $serviceName "db_sync" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $configMapEtc := index . "configMapEtc" | default (printf "%s-%s" $serviceName "etc" ) -}} {{- $podMount := index (index $envAll.Values.pod.mounts $jobNameRef | default dict) $jobNameRef | default dict -}} {{- $podVolMounts := (concat ((index $podMount "volumeMounts" | default list)) ((index . "podVolMounts") | default (list))) | uniq -}} {{- $podVols := (concat ((index $podMount "volumes" | default list)) ((index . "podVols") | default (list))) | uniq -}} {{- $podEnvVars := index . "podEnvVars" | default false -}} {{- $dbToSync := index . "dbToSync" | default ( dict "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "configDir" (printf "/etc/%s/%s.conf.d" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "image" ( index $envAll.Values.images.tags ( printf "%s_db_sync" $serviceName )) ) -}} {{- $etcSources := index (index $envAll.Values.pod "etcSources" | default dict) $jobNameRef | default list -}} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $dbAdminTlsSecret := index . "dbAdminTlsSecret" | default "" -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "db-sync" }} {{ tuple $envAll "db_sync" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "db-sync" | quote }} labels: {{ tuple $envAll $serviceName "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: {{ tuple "db_sync" $envAll | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "db_sync" $envAll | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ tuple $envAll "db_sync" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "db_sync" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: {{ printf "%s-%s" $serviceNamePretty "db-sync" | quote }} image: {{ $dbToSync.image | quote }} imagePullPolicy: {{ $envAll.Values.images.pull_policy | quote }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{- if $podEnvVars }} env: {{ $podEnvVars | toYaml | indent 12 }} {{- end }} command: - /bin/bash - -c - /tmp/db-sync.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: db-sync-sh mountPath: /tmp/db-sync.sh subPath: db-sync.sh readOnly: true - name: etc-service mountPath: {{ dir $dbToSync.configFile | quote }} - name: db-sync-conf mountPath: {{ $dbToSync.configFile | quote }} subPath: {{ base $dbToSync.configFile | quote }} readOnly: true - name: db-sync-conf-dir mountPath: {{ $dbToSync.configDir | quote }} readOnly: true - name: db-sync-conf mountPath: {{ $dbToSync.logConfigFile | quote }} subPath: {{ base $dbToSync.logConfigFile | quote }} readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $dbAdminTlsSecret "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- if $podVolMounts }} {{ $podVolMounts | toYaml | indent 12 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: db-sync-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} - name: etc-service emptyDir: {} - name: db-sync-conf secret: secretName: {{ $configMapEtc | quote }} defaultMode: 0444 - name: db-sync-conf-dir {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $dbAdminTlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- if $podVols }} {{ $podVols | toYaml | indent 8 }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_job-ks-endpoints.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for keystone service management. # It can be used in charts dict created similar to the following: # {- $ksEndpointJob := dict "envAll" . "serviceName" "senlin" "serviceTypes" ( tuple "clustering" ) -} # { $ksEndpointJob | include "helm-toolkit.manifests.job_ks_endpoints" } {{- define "helm-toolkit.manifests.job_ks_endpoints" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $serviceTypes := index . "serviceTypes" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $secretBin := index . "secretBin" -}} {{- $tlsSecret := index . "tlsSecret" | default "" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $restartPolicy_ := "OnFailure" -}} {{- if hasKey $envAll.Values "jobs" -}} {{- if hasKey $envAll.Values.jobs "ks_endpoints" -}} {{- $restartPolicy_ = $envAll.Values.jobs.ks_endpoints.restartPolicy | default $restartPolicy_ }} {{- end }} {{- end }} {{- $restartPolicy := index . "restartPolicy" | default $restartPolicy_ -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "ks-endpoints" }} {{ tuple $envAll "ks_endpoints" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "ks-endpoints" | quote }} labels: {{ tuple $envAll $serviceName "ks-endpoints" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "ks-endpoints" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: {{ $restartPolicy }} {{ tuple $envAll "ks_endpoints" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "ks_endpoints" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{- range $key1, $osServiceType := $serviceTypes }} {{- range $key2, $osServiceEndPoint := tuple "admin" "internal" "public" }} - name: {{ printf "%s-%s-%s" $osServiceType "ks-endpoints" $osServiceEndPoint | quote }} image: {{ $envAll.Values.images.tags.ks_endpoints }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_endpoints | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /bin/bash - -c - /tmp/ks-endpoints.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ks-endpoints-sh mountPath: /tmp/ks-endpoints.sh subPath: ks-endpoints.sh readOnly: true {{ dict "enabled" true "name" $tlsSecret "ca" true | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (ne $tlsSecret "") }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: OS_SVC_ENDPOINT value: {{ $osServiceEndPoint | quote }} - name: OS_SERVICE_NAME value: {{ tuple $osServiceType $envAll | include "helm-toolkit.endpoints.keystone_endpoint_name_lookup" }} - name: OS_SERVICE_TYPE value: {{ $osServiceType | quote }} - name: OS_SERVICE_ENDPOINT value: {{ tuple $osServiceType $osServiceEndPoint "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} {{- end }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: ks-endpoints-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} {{- dict "enabled" true "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_job-ks-service.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for keystone service management. # It can be used in charts dict created similar to the following: # {- $ksServiceJob := dict "envAll" . "serviceName" "senlin" "serviceTypes" ( tuple "clustering" ) -} # { $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" } {{- define "helm-toolkit.manifests.job_ks_service" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $serviceTypes := index . "serviceTypes" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $secretBin := index . "secretBin" -}} {{- $tlsSecret := index . "tlsSecret" | default "" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $restartPolicy_ := "OnFailure" -}} {{- if hasKey $envAll.Values "jobs" -}} {{- if hasKey $envAll.Values.jobs "ks_service" -}} {{- $restartPolicy_ = $envAll.Values.jobs.ks_service.restartPolicy | default $restartPolicy_ }} {{- end }} {{- end }} {{- $restartPolicy := index . "restartPolicy" | default $restartPolicy_ -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "ks-service" }} {{ tuple $envAll "ks_service" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "ks-service" | quote }} labels: {{ tuple $envAll $serviceName "ks-service" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "ks-service" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: {{ $restartPolicy }} {{ tuple $envAll "ks_service" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "ks_service" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{- range $key1, $osServiceType := $serviceTypes }} - name: {{ printf "%s-%s" $osServiceType "ks-service-registration" | quote }} image: {{ $envAll.Values.images.tags.ks_service }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_service | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /bin/bash - -c - /tmp/ks-service.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ks-service-sh mountPath: /tmp/ks-service.sh subPath: ks-service.sh readOnly: true {{ dict "enabled" true "name" $tlsSecret "ca" true | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (ne $tlsSecret "") }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: OS_SERVICE_NAME value: {{ tuple $osServiceType $envAll | include "helm-toolkit.endpoints.keystone_endpoint_name_lookup" }} - name: OS_SERVICE_TYPE value: {{ $osServiceType | quote }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: ks-service-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} {{- dict "enabled" true "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_job-ks-user.yaml.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for keystone user management. # It can be used in charts dict created similar to the following: # {- $ksUserJob := dict "envAll" . "serviceName" "senlin" } # { $ksUserJob | include "helm-toolkit.manifests.job_ks_user" } {{/* # This function creates a manifest for keystone user management. # It can be used in charts as follows: # {{- $ksUserJob := dict "envAll" . "serviceName" "heat" "serviceUsers" ( tuple "heat" "heat_trustee" ) -}} # {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} */}} {{- define "helm-toolkit.manifests.job_ks_user" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $singleServiceUser := index . "serviceUser" | default $serviceName -}} {{- $serviceUsers := index . "serviceUsers" | default (tuple $singleServiceUser) -}} {{- $secretBin := index . "secretBin" -}} {{- $tlsSecret := index . "tlsSecret" | default "" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $restartPolicy_ := "OnFailure" -}} {{- if hasKey $envAll.Values "jobs" -}} {{- if hasKey $envAll.Values.jobs "ks_user" -}} {{- $restartPolicy_ = $envAll.Values.jobs.ks_user.restartPolicy | default $restartPolicy_ }} {{- end }} {{- end }} {{- $restartPolicy := index . "restartPolicy" | default $restartPolicy_ -}} {{- $serviceAccountName := printf "%s-ks-user" $serviceNamePretty }} {{ tuple $envAll "ks_user" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-ks-user" $serviceNamePretty | quote }} labels: {{ tuple $envAll $serviceName "ks-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "ks-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName | quote }} {{ dict "envAll" $envAll "application" "ks_user" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} restartPolicy: {{ $restartPolicy }} {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "ks_user" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{- range $serviceUser := $serviceUsers }} - name: {{ printf "%s-ks-user" $serviceUser | replace "_" "-" | quote }} image: {{ $envAll.Values.images.tags.ks_user }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ks_user" "container" "ks_user" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ks-user-sh mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{ dict "enabled" true "name" $tlsSecret "ca" true | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (ne $tlsSecret "") }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: {{ $serviceName | quote }} {{- with $env := dict "ksUserSecret" (index $envAll.Values.secrets.identity $serviceUser ) }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_ROLES {{- $serviceOsRoles := index $envAll.Values.endpoints.identity.auth $serviceUser "role" }} {{- if kindIs "slice" $serviceOsRoles }} value: {{ include "helm-toolkit.utils.joinListWithComma" $serviceOsRoles | quote }} {{- else }} value: {{ $serviceOsRoles | quote }} {{- end }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: ks-user-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} {{- dict "enabled" true "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_job-rabbit-init.yaml.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.manifests.job_rabbit_init" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $serviceUser := index . "serviceUser" | default $serviceName -}} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceUserPretty := $serviceUser | replace "_" "-" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $tlsPath := index . "tlsPath" | default "/etc/rabbitmq/certs" -}} {{- $tlsSecret := index . "tlsSecret" | default "" -}} {{- $serviceAccountName := printf "%s-%s" $serviceUserPretty "rabbit-init" }} {{ tuple $envAll "rabbit_init" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceUserPretty "rabbit-init" | quote }} labels: {{ tuple $envAll $serviceName "rabbit-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "rabbit-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName | quote }} restartPolicy: OnFailure {{ tuple $envAll "rabbit_init" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "rabbit_init" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: rabbit-init image: {{ $envAll.Values.images.tags.rabbit_init | quote }} imagePullPolicy: {{ $envAll.Values.images.pull_policy | quote }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.rabbit_init | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /bin/bash - -c - /tmp/rabbit-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbit-init-sh mountPath: /tmp/rabbit-init.sh subPath: rabbit-init.sh readOnly: true {{- if $envAll.Values.manifests.certificates }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $tlsSecret "path" $tlsPath | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} env: - name: RABBITMQ_ADMIN_CONNECTION valueFrom: secretKeyRef: name: {{ $envAll.Values.secrets.oslo_messaging.admin }} key: RABBITMQ_CONNECTION - name: RABBITMQ_USER_CONNECTION valueFrom: secretKeyRef: name: {{ index $envAll.Values.secrets.oslo_messaging $serviceName }} key: RABBITMQ_CONNECTION {{- if $envAll.Values.conf.rabbitmq }} - name: RABBITMQ_AUXILIARY_CONFIGURATION value: {{ toJson $envAll.Values.conf.rabbitmq | quote }} {{- end }} {{- if and $envAll.Values.manifests.certificates (ne $tlsSecret "") }} - name: RABBITMQ_X509 value: "REQUIRE X509" - name: USER_CERT_PATH value: {{ $tlsPath | quote }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: rabbit-init-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} {{- if $envAll.Values.manifests.certificates }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_job-s3-bucket.yaml.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for linking an s3 bucket to an s3 user. # It can be used in charts dict created similar to the following: # {- $s3BucketJob := dict "envAll" . "serviceName" "elasticsearch" } # { $s3BucketJob | include "helm-toolkit.manifests.job_s3_bucket" } {{- define "helm-toolkit.manifests.job_s3_bucket" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $configMapCeph := index . "configMapCeph" | default (printf "ceph-etc" ) -}} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $s3UserSecret := index $envAll.Values.secrets.rgw $serviceName -}} {{- $s3Bucket := index . "s3Bucket" | default $serviceName }} {{- $tlsCertificateSecret := index . "tlsCertificateSecret" -}} {{- $tlsCertificatePath := index . "tlsCertificatePath" -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "s3-bucket" }} {{ tuple $envAll "s3_bucket" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "s3-bucket" | quote }} labels: {{ tuple $envAll $serviceName "s3-bucket" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "s3-bucket" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} spec: serviceAccountName: {{ $serviceAccountName | quote }} restartPolicy: OnFailure {{ tuple $envAll "s3_bucket" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "s3_bucket" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: s3-bucket image: {{ $envAll.Values.images.tags.s3_bucket }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.s3_bucket | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /bin/bash - -c - /tmp/create-s3-bucket.sh env: {{- include "helm-toolkit.snippets.rgw_s3_user_env_vars" $envAll | indent 12 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: s3-bucket-sh mountPath: /tmp/create-s3-bucket.sh subPath: create-s3-bucket.sh readOnly: true - name: etcceph mountPath: /etc/ceph - name: ceph-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true {{- if empty $envAll.Values.conf.ceph.admin_keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} {{- if and ($tlsCertificatePath) ($tlsCertificateSecret) }} - name: {{ $tlsCertificateSecret }} mountPath: {{ $tlsCertificatePath }} subPath: ca.crt readOnly: true {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: s3-bucket-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} - name: etcceph emptyDir: {} - name: ceph-etc configMap: name: {{ $configMapCeph | quote }} defaultMode: 0444 {{- if empty $envAll.Values.conf.ceph.admin_keyring }} - name: ceph-keyring secret: secretName: pvc-ceph-client-key {{ end }} {{- if and ($tlsCertificatePath) ($tlsCertificateSecret) }} - name: {{ $tlsCertificateSecret }} secret: secretName: {{ $tlsCertificateSecret }} defaultMode: 292 {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_job-s3-user.yaml.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for s3 user management. # It can be used in charts dict created similar to the following: # {- $s3UserJob := dict "envAll" . "serviceName" "elasticsearch" } # { $s3UserJob | include "helm-toolkit.manifests.job_s3_user" } {{- define "helm-toolkit.manifests.job_s3_user" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $configMapCeph := index . "configMapCeph" | default (printf "ceph-etc" ) -}} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $s3UserSecret := index $envAll.Values.secrets.rgw $serviceName -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "s3-user" }} {{ tuple $envAll "s3_user" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "s3-user" | quote }} labels: {{ tuple $envAll $serviceName "s3-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: "helm.sh/hook-delete-policy": before-hook-creation {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "s3-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} spec: serviceAccountName: {{ $serviceAccountName | quote }} restartPolicy: OnFailure {{ tuple $envAll "s3_user" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "s3_user" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ceph-keyring-placement image: {{ $envAll.Values.images.tags.ceph_key_placement }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} command: - /tmp/ceph-admin-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph - name: ceph-keyring-sh mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true {{- if empty $envAll.Values.conf.ceph.admin_keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} containers: - name: s3-user image: {{ $envAll.Values.images.tags.s3_user }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.s3_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /bin/bash - -c - /tmp/create-s3-user.sh env: {{- include "helm-toolkit.snippets.rgw_s3_user_env_vars" $envAll | indent 12 }} - name: RGW_HOST value: {{ tuple "ceph_object_store" "internal" "api" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: create-s3-user-sh mountPath: /tmp/create-s3-user.sh subPath: create-s3-user.sh readOnly: true - name: etcceph mountPath: /etc/ceph - name: ceph-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true {{- if empty $envAll.Values.conf.ceph.admin_keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} volumes: - name: pod-tmp emptyDir: {} - name: create-s3-user-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} - name: ceph-keyring-sh configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 - name: etcceph emptyDir: {} - name: ceph-etc configMap: name: {{ $configMapCeph | quote }} defaultMode: 0444 {{- if empty $envAll.Values.conf.ceph.admin_keyring }} - name: ceph-keyring secret: secretName: pvc-ceph-client-key {{ end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_job_image_repo_sync.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for the image repo sync jobs. # It can be used in charts dict created similar to the following: # {- $imageRepoSyncJob := dict "envAll" . "serviceName" "prometheus" -} # { $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" } {{- define "helm-toolkit.manifests.job_image_repo_sync" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $jobAnnotations := index . "jobAnnotations" -}} {{- $jobLabels := index . "jobLabels" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $tolerationsEnabled := index . "tolerationsEnabled" | default false -}} {{- $podVolMounts := index . "podVolMounts" | default false -}} {{- $podVols := index . "podVols" | default false -}} {{- $configMapBin := index . "configMapBin" | default (printf "%s-%s" $serviceName "bin" ) -}} {{- $secretBin := index . "secretBin" -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $activeDeadlineSeconds := index . "activeDeadlineSeconds" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} {{- $serviceAccountName := printf "%s-%s" $serviceNamePretty "image-repo-sync" }} {{ tuple $envAll "image_repo_sync" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ printf "%s-%s" $serviceNamePretty "image-repo-sync" | quote }} labels: {{ tuple $envAll $serviceName "image-repo-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 4 }} {{- end }} annotations: "helm.sh/hook-delete-policy": before-hook-creation {{- if $jobAnnotations }} {{ toYaml $jobAnnotations | indent 4 }} {{- end }} spec: backoffLimit: {{ $backoffLimit }} {{- if $activeDeadlineSeconds }} activeDeadlineSeconds: {{ $activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll $serviceName "image-repo-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} {{- if $jobLabels }} {{ toYaml $jobLabels | indent 8 }} {{- end }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ tuple $envAll "image_repo_sync" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if $tolerationsEnabled }} {{ tuple $envAll $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple $envAll "image_repo_sync" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: image-repo-sync {{ tuple $envAll "image_repo_sync" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.image_repo_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: LOCAL_REPO value: "{{ tuple "local_image_registry" "node" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}:{{ tuple "local_image_registry" "node" "registry" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" - name: IMAGE_SYNC_LIST value: "{{ include "helm-toolkit.utils.image_sync_list" $envAll }}" command: - /bin/bash - -c - /tmp/image-repo-sync.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: bootstrap-sh mountPath: /tmp/image-repo-sync.sh subPath: image-repo-sync.sh readOnly: true - name: docker-socket mountPath: /var/run/docker.sock {{- if $podVolMounts }} {{ $podVolMounts | toYaml | indent 12 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: bootstrap-sh {{- if $secretBin }} secret: secretName: {{ $secretBin | quote }} defaultMode: 0555 {{- else }} configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 {{- end }} - name: docker-socket hostPath: path: /var/run/docker.sock {{- if $podVols }} {{ $podVols | toYaml | indent 8 }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_network_policy.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Creates a network policy manifest for services. values: | endpoints: kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns_tcp: default: 53 dns: default: 53 protocol: UDP network_policy: myLabel: podSelector: matchLabels: component: api ingress: - from: - podSelector: matchLabels: application: keystone ports: - protocol: TCP port: 80 egress: - to: - namespaceSelector: matchLabels: name: default - namespaceSelector: matchLabels: name: kube-public ports: - protocol: TCP port: 53 - protocol: UDP port: 53 usage: | {{ dict "envAll" . "name" "application" "label" "myLabel" | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{ dict "envAll" . "key" "myLabel" "labels" (dict "application" "myApp" "component" "myComp")}} return: | --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: RELEASE-NAME namespace: NAMESPACE spec: policyTypes: - Ingress - Egress podSelector: matchLabels: application: myLabel component: api ingress: - from: - podSelector: matchLabels: application: keystone ports: - protocol: TCP port: 80 egress: - to: - podSelector: matchLabels: name: default - namespaceSelector: matchLabels: name: kube-public ports: - protocol: TCP port: 53 - protocol: UDP port: 53 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: RELEASE-NAME namespace: NAMESPACE spec: policyTypes: - Ingress - Egress podSelector: matchLabels: application: myApp component: myComp ingress: - from: - podSelector: matchLabels: application: keystone ports: - protocol: TCP port: 80 egress: - to: - podSelector: matchLabels: name: default - namespaceSelector: matchLabels: name: kube-public ports: - protocol: TCP port: 53 - protocol: UDP port: 53 */}} {{/* abstract: | Creates a network policy manifest for services. values: | network_policy: myLabel: spec: usage: | {{ dict "envAll" . "name" "application" "label" "myLabel" | include "helm-toolkit.manifests.kubernetes_network_policy" }} return: | --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: RELEASE-NAME-myLabel-netpol namespace: NAMESPACE spec: */}} {{- define "helm-toolkit.manifests.kubernetes_network_policy" -}} {{- $envAll := index . "envAll" -}} {{- $name := index . "name" -}} {{- $labels := index . "labels" | default nil -}} {{- $label := index . "key" | default (index . "label") -}} {{- $spec_labels := list -}} {{- range $label, $value := $envAll.Values.network_policy }} {{- if hasKey $value "spec" }} {{- $spec_labels = append $spec_labels $label }} {{- end }} {{- end }} {{- if $spec_labels }} {{- range $label := $spec_labels }} {{- $raw_spec := (index $envAll.Values.network_policy $label "spec") }} --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: {{ $envAll.Release.Name }}-{{ $label | replace "_" "-" }}-netpol namespace: {{ $envAll.Release.Namespace }} spec: {{ $raw_spec | toYaml | indent 2 }} {{- end }} {{- else }} --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: {{ $label | replace "_" "-" }}-netpol namespace: {{ $envAll.Release.Namespace }} spec: {{- if hasKey (index $envAll.Values "network_policy") $label }} policyTypes: {{- $is_egress := false -}} {{- if hasKey (index $envAll.Values.network_policy $label) "policyTypes" -}} {{- if has "Egress" (index $envAll.Values.network_policy $label "policyTypes") -}} {{- $is_egress = true -}} {{- end -}} {{- end -}} {{- if or $is_egress (index $envAll.Values.network_policy $label "egress") }} - Egress {{ end -}} {{- $is_ingress := false -}} {{- if hasKey (index $envAll.Values.network_policy $label) "policyTypes" -}} {{- if has "Ingress" (index $envAll.Values.network_policy $label "policyTypes") -}} {{- $is_ingress = true -}} {{- end -}} {{- end -}} {{- if or $is_ingress (index $envAll.Values.network_policy $label "ingress") }} - Ingress {{ end -}} {{- end }} podSelector: matchLabels: {{- if empty $labels }} {{ $name }}: {{ $label }} {{- else }} {{ range $k, $v := $labels }} {{ $k }}: {{ $v }} {{- end }} {{- end }} {{- if hasKey (index $envAll.Values "network_policy") $label }} {{- if hasKey (index $envAll.Values.network_policy $label) "podSelector" }} {{- if index $envAll.Values.network_policy $label "podSelector" "matchLabels" }} {{ index $envAll.Values.network_policy $label "podSelector" "matchLabels" | toYaml | indent 6 }} {{ end }} {{ end }} {{ end }} {{- if hasKey (index $envAll.Values "network_policy") $label }} egress: {{- range $key, $value := $envAll.Values.endpoints }} {{- if kindIs "map" $value }} {{- if or (hasKey $value "namespace") (hasKey $value "hosts") }} - to: {{- if index $value "namespace" }} - namespaceSelector: matchLabels: name: {{ index $value "namespace" }} {{- else if index $value "hosts" }} {{- $defaultValue := index $value "hosts" "internal" }} {{- if hasKey (index $value "hosts") "internal" }} {{- $a := split "-" $defaultValue }} - podSelector: matchLabels: application: {{ printf "%s" (index $a._0) | default $defaultValue }} {{- else }} {{- $defaultValue := index $value "hosts" "default" }} {{- $a := split "-" $defaultValue }} - podSelector: matchLabels: application: {{ printf "%s" (index $a._0) | default $defaultValue }} {{- end }} {{- end }} {{- if index $value "port" }} ports: {{- range $k, $v := index $value "port" }} {{- if $k }} {{- range $pk, $pv := $v }} {{- if and $pv (ne $pk "protocol") }} - port: {{ $pv }} protocol: {{ $v.protocol | default "TCP" }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- if index $envAll.Values.network_policy $label "egress" }} {{ index $envAll.Values.network_policy $label "egress" | toYaml | indent 4 }} {{- end }} {{- end }} {{- if hasKey (index $envAll.Values "network_policy") $label }} {{- if index $envAll.Values.network_policy $label "ingress" }} ingress: {{ index $envAll.Values.network_policy $label "ingress" | toYaml | indent 4 }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_secret-ks-etc.yaml.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.manifests.secret_ks_etc" -}} {{- $envAll := index . "envAll" -}} {{- $serviceName := index . "serviceName" -}} {{- $serviceUserSections := index . "serviceUserSections" -}} {{- $serviceNamePretty := $serviceName | replace "_" "-" -}} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-ks-etc" $serviceNamePretty | quote }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ tuple "ks_etc" $serviceName $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- range $epName, $sectionName := $serviceUserSections }} {{- $epAuth := index $envAll.Values.endpoints.identity.auth $epName -}} {{- $configSection := dict "region_name" $epAuth.region_name "project_name" $epAuth.project_name "project_domain_name" $epAuth.project_domain_name "user_domain_name" $epAuth.user_domain_name "username" $epAuth.username "password" $epAuth.password -}} {{- $configSnippet := dict $sectionName $configSection }} {{ printf "%s_%s.conf" $serviceName $sectionName | indent 2 }}: {{ include "helm-toolkit.utils.to_oslo_conf" $configSnippet | b64enc }} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_secret-registry.yaml.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Creates a manifest for a authenticating a registry with a secret examples: - values: | annotations: secret: oci_image_registry: {{ $serviceName }}: custom.tld/key: "value" secrets: oci_image_registry: {{ $serviceName }}: {{ $keyName }} endpoints: oci_image_registry: name: oci-image-registry auth: enabled: true {{ $serviceName }}: name: {{ $userName }} password: {{ $password }} usage: | {{- include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) -}} return: | --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: custom.tld/key: "value" type: kubernetes.io/dockerconfigjson data: dockerconfigjson: {{ $dockerAuth }} */}} {{- define "helm-toolkit.manifests.secret_registry" }} {{- $envAll := index . "envAll" }} {{- $registryUser := index . "registryUser" }} {{- $secretName := index $envAll.Values.secrets.oci_image_registry $registryUser }} {{- $registryHost := tuple "oci_image_registry" "internal" $envAll | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{/* We only use "host:port" when port is non-null, else just use "host" */}} {{- $registryPort := "" }} {{- $port := $envAll.Values.endpoints.oci_image_registry.port.registry.default }} {{- if $port }} {{- $port = tuple "oci_image_registry" "internal" "registry" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $registryPort = printf ":%s" $port }} {{- end }} {{- $imageCredentials := index $envAll.Values.endpoints.oci_image_registry.auth $registryUser }} {{- $dockerAuthToken := printf "%s:%s" $imageCredentials.username $imageCredentials.password | b64enc }} {{- $dockerAuth := printf "{\"auths\": {\"%s%s\": {\"auth\": \"%s\"}}}" $registryHost $registryPort $dockerAuthToken | b64enc }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oci_image_registry" $registryUser $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: {{ $dockerAuth }} {{- end -}} ================================================ FILE: helm-toolkit/templates/manifests/_secret-tls.yaml.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Creates a manifest for a services public tls secret examples: - values: | annotations: secret: tls: key_manager_api_public: custom.tld/key: "value" secrets: tls: key_manager: api: public: barbican-tls-public endpoints: key_manager: host_fqdn_override: public: tls: crt: | FOO-CRT key: | FOO-KEY ca: | FOO-CA_CRT usage: | {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "key-manager" ) -}} return: | --- apiVersion: v1 kind: Secret metadata: name: barbican-tls-public annotations: custom.tld/key: "value" type: kubernetes.io/tls data: tls.key: Rk9PLUtFWQo= tls.crt: Rk9PLUNSVAoKRk9PLUNBX0NSVAo= - values: | secrets: tls: key_manager: api: public: barbican-tls-public endpoints: key_manager: host_fqdn_override: public: tls: crt: | FOO-CRT FOO-INTERMEDIATE_CRT FOO-CA_CRT key: | FOO-KEY usage: | {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "key-manager" ) -}} return: | --- apiVersion: v1 kind: Secret metadata: name: barbican-tls-public type: kubernetes.io/tls data: tls.key: Rk9PLUtFWQo= tls.crt: Rk9PLUNSVApGT08tSU5URVJNRURJQVRFX0NSVApGT08tQ0FfQ1JUCg== */}} {{- define "helm-toolkit.manifests.secret_ingress_tls" }} {{- $envAll := index . "envAll" }} {{- $endpoint := index . "endpoint" | default "public" }} {{- $backendServiceType := index . "backendServiceType" }} {{- $backendService := index . "backendService" | default "api" }} {{- $host := index $envAll.Values.endpoints ( $backendServiceType | replace "-" "_" ) "host_fqdn_override" }} {{- if hasKey $host $endpoint }} {{- $endpointHost := index $host $endpoint }} {{- if kindIs "map" $endpointHost }} {{- if hasKey $endpointHost "tls" }} {{- if and $endpointHost.tls.key $endpointHost.tls.crt }} {{- $customAnnotationKey := printf "%s_%s_%s" ( $backendServiceType | replace "-" "_" ) $backendService $endpoint }} --- apiVersion: v1 kind: Secret metadata: name: {{ index $envAll.Values.secrets.tls ( $backendServiceType | replace "-" "_" ) $backendService $endpoint }} annotations: {{ tuple "tls" $customAnnotationKey $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: kubernetes.io/tls data: tls.key: {{ $endpointHost.tls.key | b64enc }} {{- if $endpointHost.tls.ca }} tls.crt: {{ list $endpointHost.tls.crt $endpointHost.tls.ca | join "\n" | b64enc }} {{- else }} tls.crt: {{ $endpointHost.tls.crt | b64enc }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/manifests/_service-ingress.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function creates a manifest for a services ingress rules. # It can be used in charts dict created similar to the following: # {- $serviceIngressOpts := dict "envAll" . "backendServiceType" "key-manager" -} # { $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" } {{- define "helm-toolkit.manifests.service_ingress" -}} {{- $envAll := index . "envAll" -}} {{- $backendServiceType := index . "backendServiceType" -}} --- apiVersion: v1 kind: Service metadata: name: {{ tuple $backendServiceType "public" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: http port: 80 - name: https port: 443 selector: app: ingress-api {{- if index $envAll.Values.endpoints $backendServiceType }} {{- if index $envAll.Values.endpoints $backendServiceType "ip" }} {{- if index $envAll.Values.endpoints $backendServiceType "ip" "ingress" }} clusterIP: {{ (index $envAll.Values.endpoints $backendServiceType "ip" "ingress") }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_create-s3-user.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.create_s3_user" }} #!/bin/bash set -e function create_s3_user () { echo "Creating s3 user and key pair" radosgw-admin user create \ --uid=${S3_USERNAME} \ --display-name=${S3_USERNAME} \ --key-type=s3 \ --access-key ${S3_ACCESS_KEY} \ --secret-key ${S3_SECRET_KEY} } function update_s3_user () { # Retrieve old access keys, if they exist old_access_keys=$(radosgw-admin user info --uid=${S3_USERNAME} \ | jq -r '.keys[].access_key' || true) if [[ ! -z ${old_access_keys} ]]; then for access_key in $old_access_keys; do # If current access key is the same as the key supplied, do nothing. if [ "$access_key" == "${S3_ACCESS_KEY}" ]; then echo "Current user and key pair exists." continue else # If keys differ, remove previous key radosgw-admin key rm --uid=${S3_USERNAME} --key-type=s3 --access-key=$access_key fi done fi # Perform one more additional check to account for scenarios where multiple # key pairs existed previously, but one existing key was the supplied key current_access_key=$(radosgw-admin user info --uid=${S3_USERNAME} \ | jq -r '.keys[].access_key' || true) # If the supplied key does not exist, modify the user if [[ -z ${current_access_key} ]]; then # Modify user with new access and secret keys echo "Updating existing user's key pair" radosgw-admin user modify \ --uid=${S3_USERNAME}\ --access-key ${S3_ACCESS_KEY} \ --secret-key ${S3_SECRET_KEY} fi } user_exists=$(radosgw-admin user info --uid=${S3_USERNAME} || true) if [[ -z ${user_exists} ]]; then create_s3_user else update_s3_user fi {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_db-drop.py.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.db_drop" }} #!/usr/bin/env python # Drops db and user for an OpenStack Service: # Set ROOT_DB_CONNECTION and DB_CONNECTION environment variables to contain # SQLAlchemy strings for the root connection to the database and the one you # wish the service to use. Alternatively, you can use an ini formatted config # at the location specified by OPENSTACK_CONFIG_FILE, and extract the string # from the key OPENSTACK_CONFIG_DB_KEY, in the section specified by # OPENSTACK_CONFIG_DB_SECTION. import os import sys try: import ConfigParser PARSER_OPTS = {} except ImportError: import configparser as ConfigParser PARSER_OPTS = {"strict": False} import logging from sqlalchemy import create_engine from sqlalchemy import text # Create logger, console handler and formatter logger = logging.getLogger('OpenStack-Helm DB Drop') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) # Get the connection string for the service db root user if "ROOT_DB_CONNECTION" in os.environ: db_connection = os.environ['ROOT_DB_CONNECTION'] logger.info('Got DB root connection') else: logger.critical('environment variable ROOT_DB_CONNECTION not set') sys.exit(1) mysql_x509 = os.getenv('MARIADB_X509', "") ssl_args = {} if mysql_x509: ssl_args = {'ssl': {'ca': '/etc/mysql/certs/ca.crt', 'key': '/etc/mysql/certs/tls.key', 'cert': '/etc/mysql/certs/tls.crt'}} # Get the connection string for the service db if "OPENSTACK_CONFIG_FILE" in os.environ: os_conf = os.environ['OPENSTACK_CONFIG_FILE'] if "OPENSTACK_CONFIG_DB_SECTION" in os.environ: os_conf_section = os.environ['OPENSTACK_CONFIG_DB_SECTION'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_SECTION not set') sys.exit(1) if "OPENSTACK_CONFIG_DB_KEY" in os.environ: os_conf_key = os.environ['OPENSTACK_CONFIG_DB_KEY'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_KEY not set') sys.exit(1) try: config = ConfigParser.RawConfigParser(**PARSER_OPTS) logger.info("Using {0} as db config source".format(os_conf)) config.read(os_conf) logger.info("Trying to load db config from {0}:{1}".format( os_conf_section, os_conf_key)) user_db_conn = config.get(os_conf_section, os_conf_key) logger.info("Got config from {0}".format(os_conf)) except: logger.critical("Tried to load config from {0} but failed.".format(os_conf)) raise elif "DB_CONNECTION" in os.environ: user_db_conn = os.environ['DB_CONNECTION'] logger.info('Got config from DB_CONNECTION env var') else: logger.critical('Could not get db config, either from config file or env var') sys.exit(1) # Root DB engine try: root_engine_full = create_engine(db_connection) root_user = root_engine_full.url.username root_password = root_engine_full.url.password drivername = root_engine_full.url.drivername host = root_engine_full.url.host port = root_engine_full.url.port root_engine_url = ''.join([drivername, '://', root_user, ':', root_password, '@', host, ':', str (port)]) root_engine = create_engine(root_engine_url, connect_args=ssl_args) connection = root_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1} as {2}".format( host, port, root_user)) except: logger.critical('Could not connect to database as root user') raise # User DB engine try: user_engine = create_engine(user_db_conn, connect_args=ssl_args) # Get our user data out of the user_engine database = user_engine.url.database user = user_engine.url.username password = user_engine.url.password logger.info('Got user db config') except: logger.critical('Could not get user database config') raise # Delete DB try: with root_engine.connect() as connection: connection.execute(text("DROP DATABASE IF EXISTS {0}".format(database))) try: connection.commit() except AttributeError: pass logger.info("Deleted database {0}".format(database)) except: logger.critical("Could not drop database {0}".format(database)) raise # Delete DB User try: with root_engine.connect() as connection: connection.execute(text("DROP USER IF EXISTS {0}".format(user))) try: connection.commit() except AttributeError: pass logger.info("Deleted user {0}".format(user)) except: logger.critical("Could not delete user {0}".format(user)) raise logger.info('Finished DB Management') {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_db-init.py.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.db_init" }} #!/usr/bin/env python # Creates db and user for an OpenStack Service: # Set ROOT_DB_CONNECTION and DB_CONNECTION environment variables to contain # SQLAlchemy strings for the root connection to the database and the one you # wish the service to use. Alternatively, you can use an ini formatted config # at the location specified by OPENSTACK_CONFIG_FILE, and extract the string # from the key OPENSTACK_CONFIG_DB_KEY, in the section specified by # OPENSTACK_CONFIG_DB_SECTION. import os import sys try: import ConfigParser PARSER_OPTS = {} except ImportError: import configparser as ConfigParser PARSER_OPTS = {"strict": False} import logging from sqlalchemy import create_engine from sqlalchemy import text # Create logger, console handler and formatter logger = logging.getLogger('OpenStack-Helm DB Init') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) # Get the connection string for the service db root user if "ROOT_DB_CONNECTION" in os.environ: db_connection = os.environ['ROOT_DB_CONNECTION'] logger.info('Got DB root connection') else: logger.critical('environment variable ROOT_DB_CONNECTION not set') sys.exit(1) mysql_x509 = os.getenv('MARIADB_X509', "") ssl_args = {} if mysql_x509: ssl_args = {'ssl': {'ca': '/etc/mysql/certs/ca.crt', 'key': '/etc/mysql/certs/tls.key', 'cert': '/etc/mysql/certs/tls.crt'}} # Get the connection string for the service db if "OPENSTACK_CONFIG_FILE" in os.environ: os_conf = os.environ['OPENSTACK_CONFIG_FILE'] if "OPENSTACK_CONFIG_DB_SECTION" in os.environ: os_conf_section = os.environ['OPENSTACK_CONFIG_DB_SECTION'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_SECTION not set') sys.exit(1) if "OPENSTACK_CONFIG_DB_KEY" in os.environ: os_conf_key = os.environ['OPENSTACK_CONFIG_DB_KEY'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_KEY not set') sys.exit(1) try: config = ConfigParser.RawConfigParser(**PARSER_OPTS) logger.info("Using {0} as db config source".format(os_conf)) config.read(os_conf) logger.info("Trying to load db config from {0}:{1}".format( os_conf_section, os_conf_key)) user_db_conn = config.get(os_conf_section, os_conf_key) logger.info("Got config from {0}".format(os_conf)) except: logger.critical("Tried to load config from {0} but failed.".format(os_conf)) raise elif "DB_CONNECTION" in os.environ: user_db_conn = os.environ['DB_CONNECTION'] logger.info('Got config from DB_CONNECTION env var') else: logger.critical('Could not get db config, either from config file or env var') sys.exit(1) # Root DB engine try: root_engine_full = create_engine(db_connection) root_user = root_engine_full.url.username root_password = root_engine_full.url.password drivername = root_engine_full.url.drivername host = root_engine_full.url.host port = root_engine_full.url.port root_engine_url = ''.join([drivername, '://', root_user, ':', root_password, '@', host, ':', str (port)]) root_engine = create_engine(root_engine_url, connect_args=ssl_args) connection = root_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1} as {2}".format( host, port, root_user)) except: logger.critical('Could not connect to database as root user') raise # User DB engine try: user_engine = create_engine(user_db_conn, connect_args=ssl_args) # Get our user data out of the user_engine database = user_engine.url.database user = user_engine.url.username password = user_engine.url.password logger.info('Got user db config') except: logger.critical('Could not get user database config') raise # Create DB try: with root_engine.connect() as connection: connection.execute(text("CREATE DATABASE IF NOT EXISTS {0}".format(database))) try: connection.commit() except AttributeError: pass logger.info("Created database {0}".format(database)) except: logger.critical("Could not create database {0}".format(database)) raise # Create DB User try: with root_engine.connect() as connection: connection.execute( text("CREATE USER IF NOT EXISTS \'{0}\'@\'%\' IDENTIFIED BY \'{1}\' {2}".format( user, password, mysql_x509))) connection.execute( text("GRANT ALL ON `{0}`.* TO \'{1}\'@\'%\'".format(database, user))) try: connection.commit() except AttributeError: pass logger.info("Created user {0} for {1}".format(user, database)) except: logger.critical("Could not create user {0} for {1}".format(user, database)) raise # Test connection try: connection = user_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1}/{2} as {3}".format( host, port, database, user)) except: logger.critical('Could not connect to database as user') raise logger.info('Finished DB Management') {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_db-pg-init.sh.tpl ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- define "helm-toolkit.scripts.pg_db_init" }} #!/bin/bash set -ex if [[ ! -v DB_HOST ]]; then echo "environment variable DB_HOST not set" exit 1 elif [[ ! -v DB_ADMIN_USER ]]; then echo "environment variable DB_ADMIN_USER not set" exit 1 elif [[ ! -v PGPASSWORD ]]; then echo "environment variable PGPASSWORD not set" exit 1 elif [[ ! -v DB_PORT ]]; then echo "environment variable DB_PORT not set" exit 1 elif [[ ! -v USER_DB_USER ]]; then echo "environment variable USER_DB_USER not set" exit 1 elif [[ ! -v USER_DB_PASS ]]; then echo "environment variable USER_DB_PASS not set" exit 1 elif [[ ! -v USER_DB_NAME ]]; then echo "environment variable USER_DB_NAME not set" exit 1 else echo "Got DB connection info" fi pgsql_superuser_cmd () { DB_COMMAND="$1" if [[ ! -z $2 ]]; then export PGDATABASE=$2 fi /usr/bin/psql \ -h ${DB_HOST} \ -p ${DB_PORT} \ -U ${DB_ADMIN_USER} \ --command="${DB_COMMAND}" } #create db pgsql_superuser_cmd "SELECT 1 FROM pg_database WHERE datname = '$USER_DB_NAME'" | grep -q "(1 row)" || pgsql_superuser_cmd "CREATE DATABASE $USER_DB_NAME" #create db user pgsql_superuser_cmd "SELECT * FROM pg_roles WHERE rolname = '$USER_DB_USER';" | grep -q "(1 row)" || \ pgsql_superuser_cmd "CREATE ROLE ${USER_DB_USER} LOGIN PASSWORD '$USER_DB_PASS';" #Set password everytime. This is required for cases when we would want password rotation to take effect and set the updated password for a user. pgsql_superuser_cmd "SELECT * FROM pg_roles WHERE rolname = '$USER_DB_USER';" && pgsql_superuser_cmd "ALTER USER ${USER_DB_USER} with password '$USER_DB_PASS'" #give permissions to user pgsql_superuser_cmd "GRANT ALL PRIVILEGES ON DATABASE $USER_DB_NAME to $USER_DB_USER;" #revoke all privileges from PUBLIC role pgsql_superuser_cmd "REVOKE ALL ON DATABASE $USER_DB_NAME FROM PUBLIC;" #Critical for PG15+: allow user to create in public schema pgsql_superuser_cmd "GRANT USAGE, CREATE ON SCHEMA public TO $USER_DB_USER;" "$USER_DB_NAME" {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_image-repo-sync.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.image_repo_sync" }} #!/bin/sh set -ex IFS=','; for IMAGE in ${IMAGE_SYNC_LIST}; do docker pull ${IMAGE} docker tag ${IMAGE} ${LOCAL_REPO}/${IMAGE} docker push ${LOCAL_REPO}/${IMAGE} done {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_ks-domain-user.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.keystone_domain_user" }} #!/bin/bash # Copyright 2017 Pete Birley # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex # Manage domain SERVICE_OS_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ --description="Service Domain for ${SERVICE_OS_DOMAIN_NAME}" \ "${SERVICE_OS_DOMAIN_NAME}") # Display domain openstack domain show "${SERVICE_OS_DOMAIN_ID}" # Manage user SERVICE_OS_USERID=$(openstack user create --or-show --enable -f value -c id \ --domain="${SERVICE_OS_DOMAIN_ID}" \ --description "Service User for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_DOMAIN_NAME}" \ --password="${SERVICE_OS_PASSWORD}" \ "${SERVICE_OS_USERNAME}") # Manage user password (we do this to ensure the password is updated if required) openstack user set --password="${SERVICE_OS_PASSWORD}" "${SERVICE_OS_USERID}" # Display user openstack user show "${SERVICE_OS_USERID}" # Manage role SERVICE_OS_ROLE_ID=$(openstack role show -f value -c id \ "${SERVICE_OS_ROLE}" || openstack role create -f value -c id \ "${SERVICE_OS_ROLE}" ) # Manage user role assignment openstack role add \ --domain="${SERVICE_OS_DOMAIN_ID}" \ --user="${SERVICE_OS_USERID}" \ --user-domain="${SERVICE_OS_DOMAIN_ID}" \ "${SERVICE_OS_ROLE_ID}" # Display user role assignment openstack role assignment list \ --role="${SERVICE_OS_ROLE_ID}" \ --user-domain="${SERVICE_OS_DOMAIN_ID}" \ --user="${SERVICE_OS_USERID}" {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_ks-endpoints.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.keystone_endpoints" }} #!/bin/bash # Copyright 2017 Pete Birley # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex # Get Service ID OS_SERVICE_ID=$( openstack service list -f csv --quote none | \ grep ",${OS_SERVICE_NAME},${OS_SERVICE_TYPE}$" | \ sed -e "s/,${OS_SERVICE_NAME},${OS_SERVICE_TYPE}//g" ) # Get Endpoint ID if it exists OS_ENDPOINT_ID=$( openstack endpoint list -f csv --quote none | \ grep "^[a-z0-9]*,${OS_REGION_NAME},${OS_SERVICE_NAME},${OS_SERVICE_TYPE},True,${OS_SVC_ENDPOINT}," | \ awk -F ',' '{ print $1 }' ) # Making sure only a single endpoint exists for a service within a region if [ "$(echo $OS_ENDPOINT_ID | wc -w)" -gt "1" ]; then echo "More than one endpoint found, cleaning up" for ENDPOINT_ID in $OS_ENDPOINT_ID; do openstack endpoint delete ${ENDPOINT_ID} done unset OS_ENDPOINT_ID fi # Determine if Endpoint needs updated if [[ ${OS_ENDPOINT_ID} ]]; then OS_ENDPOINT_URL_CURRENT=$(openstack endpoint show ${OS_ENDPOINT_ID} -f value -c url) if [ "${OS_ENDPOINT_URL_CURRENT}" == "${OS_SERVICE_ENDPOINT}" ]; then echo "Endpoints Match: no action required" OS_ENDPOINT_UPDATE="False" else echo "Endpoints Dont Match: removing existing entries" openstack endpoint delete ${OS_ENDPOINT_ID} OS_ENDPOINT_UPDATE="True" fi else OS_ENDPOINT_UPDATE="True" fi # Update Endpoint if required if [[ "${OS_ENDPOINT_UPDATE}" == "True" ]]; then OS_ENDPOINT_ID=$( openstack endpoint create -f value -c id \ --region="${OS_REGION_NAME}" \ "${OS_SERVICE_ID}" \ ${OS_SVC_ENDPOINT} \ "${OS_SERVICE_ENDPOINT}" ) fi # Display the Endpoint openstack endpoint show ${OS_ENDPOINT_ID} {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_ks-service.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.keystone_service" }} #!/bin/bash # Copyright 2017 Pete Birley # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex # Service boilerplate description OS_SERVICE_DESC="${OS_REGION_NAME}: ${OS_SERVICE_NAME} (${OS_SERVICE_TYPE}) service" # Get Service ID if it exists unset OS_SERVICE_ID # FIXME - There seems to be an issue once in a while where the # openstack service list fails and encounters an error message such as: # Unable to establish connection to # https://keystone-api.openstack.svc.cluster.local:5000/v3/auth/tokens: # ('Connection aborted.', OSError("(104, 'ECONNRESET')",)) # During an upgrade scenario, this would cause the OS_SERVICE_ID to be blank # and it would attempt to create a new service when it was not needed. # This duplciate service would sometimes be used by other services such as # Horizon and would give an 'Invalid Service Catalog' error. # This loop allows for a 'retry' of the openstack service list in an # attempt to get the service list as expected if it does ecounter an error. # This loop and recheck can be reverted once the underlying issue is addressed. # If OS_SERVICE_ID is blank then wait a few seconds to give it # additional time and try again for i in $(seq 3) do OS_SERVICE_ID=$( openstack service list -f csv --quote none | \ grep ",${OS_SERVICE_NAME},${OS_SERVICE_TYPE}$" | \ sed -e "s/,${OS_SERVICE_NAME},${OS_SERVICE_TYPE}//g" ) # If the service was found, go ahead and exit successfully. if [[ -n "${OS_SERVICE_ID}" ]]; then exit 0 fi sleep 2 done # If we've reached this point and a Service ID was not found, # then create the service OS_SERVICE_ID=$(openstack service create -f value -c id \ --name="${OS_SERVICE_NAME}" \ --description "${OS_SERVICE_DESC}" \ --enable \ "${OS_SERVICE_TYPE}") {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_ks-user.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.keystone_user" }} #!/bin/bash # Copyright 2017 Pete Birley # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex shopt -s nocasematch if [[ "${SERVICE_OS_PROJECT_DOMAIN_NAME}" == "Default" ]] then PROJECT_DOMAIN_ID="default" else # Manage project domain PROJECT_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ --description="Domain for ${SERVICE_OS_PROJECT_DOMAIN_NAME}" \ "${SERVICE_OS_PROJECT_DOMAIN_NAME}") fi if [[ "${SERVICE_OS_USER_DOMAIN_NAME}" == "Default" ]] then USER_DOMAIN_ID="default" else # Manage user domain USER_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ --description="Domain for ${SERVICE_OS_USER_DOMAIN_NAME}" \ "${SERVICE_OS_USER_DOMAIN_NAME}") fi shopt -u nocasematch # Manage user project USER_PROJECT_DESC="Service Project for ${SERVICE_OS_PROJECT_DOMAIN_NAME}" USER_PROJECT_ID=$(openstack project create --or-show --enable -f value -c id \ --domain="${PROJECT_DOMAIN_ID}" \ --description="${USER_PROJECT_DESC}" \ "${SERVICE_OS_PROJECT_NAME}"); # Manage user USER_DESC="Service User for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_USER_DOMAIN_NAME}/${SERVICE_OS_SERVICE_NAME}" USER_ID=$(openstack user create --or-show --enable -f value -c id \ --domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ --description="${USER_DESC}" \ "${SERVICE_OS_USERNAME}"); # Manage user password (we do this in a seperate step to ensure the password is updated if required) set +x echo "Setting user password via: openstack user set --password=xxxxxxx ${USER_ID}" openstack user set --password="${SERVICE_OS_PASSWORD}" "${USER_ID}" set -x function ks_assign_user_role () { if [[ "$SERVICE_OS_ROLE" == "admin" ]] then USER_ROLE_ID="$SERVICE_OS_ROLE" else USER_ROLE_ID=$(openstack role create --or-show -f value -c id "${SERVICE_OS_ROLE}"); fi # Manage user role assignment openstack role add \ --user="${USER_ID}" \ --user-domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ "${USER_ROLE_ID}" } # Manage user service role IFS=',' for SERVICE_OS_ROLE in ${SERVICE_OS_ROLES}; do ks_assign_user_role done # Manage user member role : ${MEMBER_OS_ROLE:="member"} export USER_ROLE_ID=$(openstack role create --or-show -f value -c id \ "${MEMBER_OS_ROLE}"); ks_assign_user_role {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_rabbit-init.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.rabbit_init" }} #!/bin/bash set -e # Extract connection details RABBIT_HOSTNAME=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $1}') RABBIT_PORT=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $2}') # Extract Admin User creadential RABBITMQ_ADMIN_USERNAME=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $4}') RABBITMQ_ADMIN_PASSWORD=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $5}' | \ sed 's/%/\\x/g' | \ xargs -0 printf "%b") # Extract User creadential RABBITMQ_USERNAME=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $4}') RABBITMQ_PASSWORD=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $5}' | \ sed 's/%/\\x/g' | \ xargs -0 printf "%b") # Extract User vHost RABBITMQ_VHOST=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $3}') # Resolve vHost to / if no value is set RABBITMQ_VHOST="${RABBITMQ_VHOST:-/}" function rabbitmqadmin_cli () { if [ -n "$RABBITMQ_X509" ] then rabbitmqadmin \ --ssl \ --ssl-disable-hostname-verification \ --ssl-ca-cert-file="${USER_CERT_PATH}/ca.crt" \ --ssl-cert-file="${USER_CERT_PATH}/tls.crt" \ --ssl-key-file="${USER_CERT_PATH}/tls.key" \ --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} else rabbitmqadmin \ --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} fi } echo "Managing: User: ${RABBITMQ_USERNAME}" rabbitmqadmin_cli \ declare user \ name="${RABBITMQ_USERNAME}" \ password="${RABBITMQ_PASSWORD}" \ tags="user" echo "Deleting Guest User" rabbitmqadmin_cli \ delete user \ name="guest" || true if [ "${RABBITMQ_VHOST}" != "/" ] then echo "Managing: vHost: ${RABBITMQ_VHOST}" rabbitmqadmin_cli \ declare vhost \ name="${RABBITMQ_VHOST}" else echo "Skipping root vHost declaration: vHost: ${RABBITMQ_VHOST}" fi echo "Managing: Permissions: ${RABBITMQ_USERNAME} on ${RABBITMQ_VHOST}" rabbitmqadmin_cli \ declare permission \ vhost="${RABBITMQ_VHOST}" \ user="${RABBITMQ_USERNAME}" \ configure=".*" \ write=".*" \ read=".*" if [ ! -z "$RABBITMQ_AUXILIARY_CONFIGURATION" ] then echo "Applying additional configuration" echo "${RABBITMQ_AUXILIARY_CONFIGURATION}" > /tmp/rmq_definitions.json rabbitmqadmin_cli import /tmp/rmq_definitions.json fi {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/_rally_test.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.scripts.rally_test" -}} #!/bin/bash set -ex {{- $rallyTests := index . 0 }} : "${RALLY_ENV_NAME:="openstack-helm"}" : "${OS_INTERFACE:="public"}" : "${RALLY_CLEANUP:="true"}" if [ "x$RALLY_CLEANUP" == "xtrue" ]; then function rally_cleanup { openstack user delete \ --domain="${SERVICE_OS_USER_DOMAIN_NAME}" \ "${SERVICE_OS_USERNAME}" {{ $rallyTests.clean_up | default "" | indent 4 }} } trap rally_cleanup EXIT fi function create_or_update_db () { revisionResults=$(rally db revision) if [ $revisionResults = "None" ] then rally db create else rally db upgrade fi } create_or_update_db cat > /tmp/rally-config.json << EOF { "openstack": { "auth_url": "${OS_AUTH_URL}", "region_name": "${OS_REGION_NAME}", "endpoint_type": "${OS_INTERFACE}", "admin": { "username": "${OS_USERNAME}", "password": "${OS_PASSWORD}", "user_domain_name": "${OS_USER_DOMAIN_NAME}", "project_name": "${OS_PROJECT_NAME}", "project_domain_name": "${OS_PROJECT_DOMAIN_NAME}" }, "users": [ { "username": "${SERVICE_OS_USERNAME}", "password": "${SERVICE_OS_PASSWORD}", "project_name": "${SERVICE_OS_PROJECT_NAME}", "user_domain_name": "${SERVICE_OS_USER_DOMAIN_NAME}", "project_domain_name": "${SERVICE_OS_PROJECT_DOMAIN_NAME}" } ], "https_insecure": false, "https_cacert": "${OS_CACERT}" } } EOF rally deployment create --file /tmp/rally-config.json --name "${RALLY_ENV_NAME}" rm -f /tmp/rally-config.json rally deployment use "${RALLY_ENV_NAME}" rally deployment check {{- if $rallyTests.run_tempest }} rally verify create-verifier --name "${RALLY_ENV_NAME}-tempest" --type tempest SERVICE_TYPE="$(rally deployment check | grep "${RALLY_ENV_NAME}" | awk -F \| '{print $3}' | tr -d ' ' | tr -d '\n')" rally verify start --pattern "tempest.api.${SERVICE_TYPE}*" rally verify delete-verifier --id "${RALLY_ENV_NAME}-tempest" --force {{- end }} rally task validate /etc/rally/rally_tests.yaml rally task start /etc/rally/rally_tests.yaml rally task sla-check rally env cleanup rally deployment destroy --deployment "${RALLY_ENV_NAME}" {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/db-backup-restore/_backup_main.sh.tpl ================================================ {{- define "helm-toolkit.scripts.db-backup-restore.backup_main" }} #!/bin/bash # This file contains a database backup framework which database scripts # can use to perform a backup. The idea here is that the database-specific # functions will be implemented by the various databases using this script # (like mariadb, postgresql or etcd for example). The database-specific # script will need to first "source" this file like this: # source /tmp/backup_main.sh # # Then the script should call the main backup function (backup_databases): # backup_databases [scope] # [scope] is an optional parameter, defaulted to "all". If only one specific # database is required to be backed up then this parameter will # contain the name of the database; otherwise all are backed up. # # The framework will require the following variables to be exported: # # export DB_NAMESPACE Namespace where the database(s) reside # export DB_NAME Name of the database system # export LOCAL_DAYS_TO_KEEP Number of days to keep the local backups # export REMOTE_DAYS_TO_KEEP Number of days to keep the remote backups # export ARCHIVE_DIR Local location where the backup tarballs should # be stored. (full directory path) # export BACK_UP_MODE Determines the mode of backup taken. # export REMOTE_BACKUP_ENABLED "true" if remote backup enabled; false # otherwise # export CONTAINER_NAME Name of the container on the RGW to store # the backup tarball. # export STORAGE_POLICY Name of the storage policy defined on the # RGW which is intended to store backups. # RGW access variables: # export OS_REGION_NAME Name of the region the RGW resides in # export OS_AUTH_URL Keystone URL associated with the RGW # export OS_PROJECT_NAME Name of the project associated with the # keystone user # export OS_USERNAME Name of the keystone user # export OS_PASSWORD Password of the keystone user # export OS_USER_DOMAIN_NAME Keystone domain the project belongs to # export OS_PROJECT_DOMAIN_NAME Keystone domain the user belongs to # export OS_IDENTITY_API_VERSION Keystone API version to use # # export REMOTE_BACKUP_RETRIES Number of retries to send backup to remote # in case of any temporary failures. # export MIN_DELAY_SEND_REMOTE Minimum seconds to delay before sending backup # to remote to stagger backups being sent to RGW # export MAX_DELAY_SEND_REMOTE Maximum seconds to delay before sending backup # to remote to stagger backups being sent to RGW. # A random number between min and max delay is generated # to set the delay. # # RGW backup throttle limits variables: # export THROTTLE_BACKUPS_ENABLED Boolean variableto control backup functionality # export THROTTLE_LIMIT Number of simultaneous RGW upload sessions # export THROTTLE_LOCK_EXPIRE_AFTER Time in seconds to expire flag file is orphaned # export THROTTLE_RETRY_AFTER Time in seconds to wait before retry # export THROTTLE_CONTAINER_NAME Name of RGW container to place flag falies into # # The database-specific functions that need to be implemented are: # dump_databases_to_directory [scope] # where: # is the full directory path to dump the database files # into. This is a temporary directory for this backup only. # is the full directory path where error logs are to be # written by the application. # [scope] set to "all" if all databases are to be backed up; or # set to the name of a specific database to be backed up. # This optional parameter is defaulted to "all". # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to dump the database file(s) to the specified # directory path. If this function completes successfully (returns 0), the # framework will automatically tar/zip the files in that directory and # name the tarball appropriately according to the proper conventions. # # verify_databases_backup_archives [scope] # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to verify the database backup archives. If this function # completes successfully (returns 0), the # framework will automatically starts remote backup upload. # # # The functions in this file will take care of: # 1) Calling "dump_databases_to_directory" and then compressing the files, # naming the tarball properly, and then storing it locally at the specified # local directory. # 2) Sending the tarball built to the remote gateway, to be stored in the # container configured to store database backups. # 3) Removing local backup tarballs which are older than the number of days # specified by the "LOCAL_DAYS_TO_KEEP" variable. # 4) Removing remote backup tarballs (from the remote gateway) which are older # than the number of days specified by the "REMOTE_DAYS_TO_KEEP" variable. # 5) Controlling remote storage gateway load from client side and throttling it # by using a dedicated RGW container to store flag files defining upload session # in progress # # Note: not using set -e in this script because more elaborate error handling # is needed. log_backup_error_exit() { MSG=$1 ERRCODE=${2:-0} log ERROR "${DB_NAME}_backup" "${DB_NAMESPACE} namespace: ${MSG}" rm -f $ERR_LOG_FILE rm -rf $TMP_DIR exit 0 } log_verify_backup_exit() { MSG=$1 ERRCODE=${2:-0} log ERROR "${DB_NAME}_verify_backup" "${DB_NAMESPACE} namespace: ${MSG}" rm -f $ERR_LOG_FILE # rm -rf $TMP_DIR exit 0 } log() { #Log message to a file or stdout #TODO: This can be convert into mail alert of alert send to a monitoring system #Params: $1 log level #Params: $2 service #Params: $3 message #Params: $4 Destination LEVEL=$1 SERVICE=$2 MSG=$3 DEST=$4 DATE=$(date +"%m-%d-%y %H:%M:%S") if [[ -z "$DEST" ]]; then echo "${DATE} ${LEVEL}: $(hostname) ${SERVICE}: ${MSG}" else echo "${DATE} ${LEVEL}: $(hostname) ${SERVICE}: ${MSG}" >>$DEST fi } # Generate a random number between MIN_DELAY_SEND_REMOTE and # MAX_DELAY_SEND_REMOTE random_number() { diff=$((${MAX_DELAY_SEND_REMOTE} - ${MIN_DELAY_SEND_REMOTE} + 1)) echo $(($(( ${RANDOM} % ${diff} )) + ${MIN_DELAY_SEND_REMOTE} )) } #Get the day delta since the archive file backup seconds_difference() { ARCHIVE_DATE=$( date --date="$1" +%s ) if [[ $? -ne 0 ]]; then SECOND_DELTA=0 fi CURRENT_DATE=$( date +%s ) SECOND_DELTA=$(($CURRENT_DATE-$ARCHIVE_DATE)) if [[ "$SECOND_DELTA" -lt 0 ]]; then SECOND_DELTA=0 fi echo $SECOND_DELTA } # Send the specified tarball file at the specified filepath to the # remote gateway. send_to_remote_server() { FILEPATH=$1 FILE=$2 # Grab the list of containers on the remote site RESULT=$(openstack container list 2>&1) if [[ $? -eq 0 ]]; then printf "%s\n" "$RESULT" | grep "$CONTAINER_NAME" if [[ $? -ne 0 ]]; then # Find the swift URL from the keystone endpoint list SWIFT_URL=$(openstack catalog show object-store -c endpoints | grep public | awk '{print $4}') if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to get object-store enpoints from keystone catalog." return 2 fi # Get a token from keystone TOKEN=$(openstack token issue -f value -c id) if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to get keystone token." return 2 fi # Create the container RES_FILE=$(mktemp -p /tmp) curl -g -i -X PUT ${SWIFT_URL}/${CONTAINER_NAME} \ -H "X-Auth-Token: ${TOKEN}" \ -H "X-Storage-Policy: ${STORAGE_POLICY}" 2>&1 > $RES_FILE if [[ $? -ne 0 || $(grep "HTTP" $RES_FILE | awk '{print $2}') -ge 400 ]]; then log WARN "${DB_NAME}_backup" "Unable to create container ${CONTAINER_NAME}" cat $RES_FILE rm -f $RES_FILE return 2 fi rm -f $RES_FILE swift stat $CONTAINER_NAME if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to retrieve container ${CONTAINER_NAME} details after creation." return 2 fi fi else echo $RESULT | grep -E "HTTP 401|HTTP 403" if [[ $? -eq 0 ]]; then log ERROR "${DB_NAME}_backup" "Access denied by keystone: ${RESULT}" return 2 else echo $RESULT | grep -E "ConnectionError|Failed to discover available identity versions|Service Unavailable|HTTP 50" if [[ $? -eq 0 ]]; then log WARN "${DB_NAME}_backup" "Could not reach the RGW: ${RESULT}" # In this case, keystone or the site/node may be temporarily down. # Return slightly different error code so the calling code can retry return 2 else log ERROR "${DB_NAME}_backup" "Could not get container list: ${RESULT}" return 2 fi fi fi # load balance delay DELAY=$((1 + ${RANDOM} % 30)) echo "Sleeping for ${DELAY} seconds to spread the load in time..." sleep ${DELAY} #--------------------------------------------------------------------------- # Remote backup throttling export THROTTLE_BACKUPS_ENABLED=$(echo $THROTTLE_BACKUPS_ENABLED | sed 's/"//g') if $THROTTLE_BACKUPS_ENABLED; then # Remove Quotes from the constants which were added due to reading # from secret. export THROTTLE_LIMIT=$(echo $THROTTLE_LIMIT | sed 's/"//g') export THROTTLE_LOCK_EXPIRE_AFTER=$(echo $THROTTLE_LOCK_EXPIRE_AFTER | sed 's/"//g') export THROTTLE_RETRY_AFTER=$(echo $THROTTLE_RETRY_AFTER | sed 's/"//g') export THROTTLE_CONTAINER_NAME=$(echo $THROTTLE_CONTAINER_NAME | sed 's/"//g') # load balance delay RESULT=$(openstack container list 2>&1) if [[ $? -eq 0 ]]; then printf "%s\n" "$RESULT" | grep "$THROTTLE_CONTAINER_NAME" if [[ $? -ne 0 ]]; then # Find the swift URL from the keystone endpoint list SWIFT_URL=$(openstack catalog show object-store -c endpoints | grep public | awk '{print $4}') if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to get object-store enpoints from keystone catalog." return 2 fi # Get a token from keystone TOKEN=$(openstack token issue -f value -c id) if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to get keystone token." return 2 fi # Create the container RES_FILE=$(mktemp -p /tmp) curl -g -i -X PUT ${SWIFT_URL}/${THROTTLE_CONTAINER_NAME} \ -H "X-Auth-Token: ${TOKEN}" \ -H "X-Storage-Policy: ${STORAGE_POLICY}" 2>&1 > $RES_FILE if [[ $? -ne 0 || $(grep "HTTP" $RES_FILE | awk '{print $2}') -ge 400 ]]; then log WARN "${DB_NAME}_backup" "Unable to create container ${THROTTLE_CONTAINER_NAME}" cat $RES_FILE rm -f $RES_FILE return 2 fi rm -f $RES_FILE swift stat $THROTTLE_CONTAINER_NAME if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to retrieve container ${THROTTLE_CONTAINER_NAME} details after creation." return 2 fi fi else echo $RESULT | grep -E "HTTP 401|HTTP 403" if [[ $? -eq 0 ]]; then log ERROR "${DB_NAME}_backup" "Access denied by keystone: ${RESULT}" return 2 else echo $RESULT | grep -E "ConnectionError|Failed to discover available identity versions|Service Unavailable|HTTP 50" if [[ $? -eq 0 ]]; then log WARN "${DB_NAME}_backup" "Could not reach the RGW: ${RESULT}" # In this case, keystone or the site/node may be temporarily down. # Return slightly different error code so the calling code can retry return 2 else log ERROR "${DB_NAME}_backup" "Could not get container list: ${RESULT}" return 2 fi fi fi NUMBER_OF_SESSIONS=$(openstack object list $THROTTLE_CONTAINER_NAME -f value | wc -l) log INFO "${DB_NAME}_backup" "There are ${NUMBER_OF_SESSIONS} remote sessions right now." while [[ ${NUMBER_OF_SESSIONS} -ge ${THROTTLE_LIMIT} ]] do log INFO "${DB_NAME}_backup" "Current number of active uploads is ${NUMBER_OF_SESSIONS}>=${THROTTLE_LIMIT}!" log INFO "${DB_NAME}_backup" "Retrying in ${THROTTLE_RETRY_AFTER} seconds...." sleep ${THROTTLE_RETRY_AFTER} NUMBER_OF_SESSIONS=$(openstack object list $THROTTLE_CONTAINER_NAME -f value | wc -l) log INFO "${DB_NAME}_backup" "There are ${NUMBER_OF_SESSIONS} remote sessions right now." done # Create a lock file in THROTTLE_CONTAINER THROTTLE_FILEPATH=$(mktemp -d) THROTTLE_FILE=${CONTAINER_NAME}.lock date +%s > $THROTTLE_FILEPATH/$THROTTLE_FILE # Create an object to store the file openstack object create --name $THROTTLE_FILE $THROTTLE_CONTAINER_NAME $THROTTLE_FILEPATH/$THROTTLE_FILE if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Cannot create throttle container object ${THROTTLE_FILE}!" return 2 fi swift post $THROTTLE_CONTAINER_NAME $THROTTLE_FILE -H "X-Delete-After:${THROTTLE_LOCK_EXPIRE_AFTER}" if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Cannot set throttle container object ${THROTTLE_FILE} expiration header!" return 2 fi openstack object show $THROTTLE_CONTAINER_NAME $THROTTLE_FILE if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to retrieve throttle container object $THROTTLE_FILE after creation." return 2 fi fi #--------------------------------------------------------------------------- # Create an object to store the file openstack object create --name $FILE $CONTAINER_NAME $FILEPATH/$FILE if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Cannot create container object ${FILE}!" return 2 fi openstack object show $CONTAINER_NAME $FILE if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Unable to retrieve container object $FILE after creation." return 2 fi # Remote backup verification MD5_REMOTE=$(openstack object show $CONTAINER_NAME $FILE -f json | jq -r ".etag") MD5_LOCAL=$(cat ${FILEPATH}/${FILE} | md5sum | awk '{print $1}') log INFO "${DB_NAME}_backup" "Obtained MD5 hash for the file $FILE in container $CONTAINER_NAME." log INFO "${DB_NAME}_backup" "Local MD5 hash is ${MD5_LOCAL}." log INFO "${DB_NAME}_backup" "Remote MD5 hash is ${MD5_REMOTE}." if [[ "${MD5_LOCAL}" == "${MD5_REMOTE}" ]]; then log INFO "${DB_NAME}_backup" "The local backup & remote backup MD5 hash values are matching for file $FILE in container $CONTAINER_NAME." else log ERROR "${DB_NAME}_backup" "Mismatch between the local backup & remote backup MD5 hash values" return 2 fi rm -f ${REMOTE_FILE} #--------------------------------------------------------------------------- # Remote backup throttling export THROTTLE_BACKUPS_ENABLED=$(echo $THROTTLE_BACKUPS_ENABLED | sed 's/"//g') if $THROTTLE_BACKUPS_ENABLED; then # Remove flag file # Delete an object to remove the flag file openstack object delete $THROTTLE_CONTAINER_NAME $THROTTLE_FILE if [[ $? -ne 0 ]]; then log WARN "${DB_NAME}_backup" "Cannot delete throttle container object ${THROTTLE_FILE}" return 0 else log INFO "${DB_NAME}_backup" "The throttle container object ${THROTTLE_FILE} has been successfully removed." fi rm -f ${THROTTLE_FILEPATH}/${THROTTLE_FILE} fi #--------------------------------------------------------------------------- log INFO "${DB_NAME}_backup" "Created file $FILE in container $CONTAINER_NAME successfully." return 0 } # This function attempts to store the built tarball to the remote gateway, # with built-in logic to handle error cases like: # 1) Network connectivity issues - retries for a specific amount of time # 2) Authorization errors - immediately logs an ERROR and returns function store_backup_remotely() { local FILEPATH=$1 local FILE=$2 local count=0 while [[ ${count} -lt ${REMOTE_BACKUP_RETRIES} ]]; do # Store the new archive to the remote backup storage facility. send_to_remote_server $FILEPATH $FILE SEND_RESULT="$?" # Check if successful if [[ $SEND_RESULT -eq 0 ]]; then log INFO "${DB_NAME}_backup" "Backup file ${FILE} successfully sent to RGW." return 0 elif [[ $SEND_RESULT -eq 2 ]]; then if [[ ${count} -ge ${REMOTE_BACKUP_RETRIES} ]]; then log ERROR "${DB_NAME}_backup" "Backup file ${FILE} could not be sent to the RGW in " \ "${REMOTE_BACKUP_RETRIES} retries. Errors encountered. Exiting." break fi # Temporary failure occurred. We need to retry log WARN "${DB_NAME}_backup" "Backup file ${FILE} could not be sent to RGW due to connection issue." sleep_time=$(random_number) log INFO "${DB_NAME}_backup" "Sleeping ${sleep_time} seconds waiting for RGW to become available..." sleep ${sleep_time} log INFO "${DB_NAME}_backup" "Retrying..." else log ERROR "${DB_NAME}_backup" "Backup file ${FILE} could not be sent to the RGW. Errors encountered. Exiting." break fi # Increment the counter count=$((count+1)) done log INFO "${DB_NAME}_backup" "Switching to failover RGW..." # If initial attempts failed and failover variables are defined, retry with failover environment variables if [[ $SEND_RESULT -ne 0 ]] && \ [[ -n "${OS_AUTH_URL_FAILOVER}" ]] && \ [[ -n "${OS_REGION_NAME_FAILOVER}" ]] && \ [[ -n "${OS_INTERFACE_FAILOVER}" ]] && \ [[ -n "${OS_PROJECT_DOMAIN_NAME_FAILOVER}" ]] && \ [[ -n "${OS_PROJECT_NAME_FAILOVER}" ]] && \ [[ -n "${OS_USER_DOMAIN_NAME_FAILOVER}" ]] && \ [[ -n "${OS_USERNAME_FAILOVER}" ]] && \ [[ -n "${OS_PASSWORD_FAILOVER}" ]]; then log INFO "${DB_NAME}_backup" "Initial attempts failed. Retrying with failover environment variables..." # Redefine OS_* variables with OS_*_FAILOVER ones export OS_AUTH_URL=${OS_AUTH_URL_FAILOVER} export OS_REGION_NAME=${OS_REGION_NAME_FAILOVER} export OS_INTERFACE=${OS_INTERFACE_FAILOVER} export OS_PROJECT_DOMAIN_NAME=${OS_PROJECT_DOMAIN_NAME_FAILOVER} export OS_PROJECT_NAME=${OS_PROJECT_NAME_FAILOVER} export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME_FAILOVER} export OS_USERNAME=${OS_USERNAME_FAILOVER} export OS_PASSWORD=${OS_PASSWORD_FAILOVER} export OS_DEFAULT_DOMAIN=${OS_DEFAULT_DOMAIN_FAILOVER} count=0 while [[ ${count} -lt ${REMOTE_BACKUP_RETRIES} ]]; do # Store the new archive to the remote backup storage facility. send_to_remote_server $FILEPATH $FILE SEND_RESULT="$?" # Check if successful if [[ $SEND_RESULT -eq 0 ]]; then log INFO "${DB_NAME}_backup" "Backup file ${FILE} successfully sent to failover RGW." return 0 elif [[ $SEND_RESULT -eq 2 ]]; then if [[ ${count} -ge ${REMOTE_BACKUP_RETRIES} ]]; then log ERROR "${DB_NAME}_backup" "Backup file ${FILE} could not be sent to the failover RGW in " \ "${REMOTE_BACKUP_RETRIES} retries. Errors encountered. Exiting." break fi # Temporary failure occurred. We need to retry log WARN "${DB_NAME}_backup" "Backup file ${FILE} could not be sent to failover RGW due to connection issue." sleep_time=$(random_number) log INFO "${DB_NAME}_backup" "Sleeping ${sleep_time} seconds waiting for failover RGW to become available..." sleep ${sleep_time} log INFO "${DB_NAME}_backup" "Retrying..." else log ERROR "${DB_NAME}_backup" "Backup file ${FILE} could not be sent to the failover RGW. Errors encountered. Exiting." break fi # Increment the counter count=$((count+1)) done fi return 1 } function get_archive_date(){ # get_archive_date function returns correct archive date # for different formats of archives' names # the old one: ....tar.gz # the new one: ..
...tar.gz local A_FILE="$1" awk -F. '{print $(NF-2)}' <<< ${A_FILE} | tr -d "Z" } # This function takes a list of archives' names as an input # and creates a hash table where keys are number of seconds # between current date and archive date (see seconds_difference), # and values are space separated archives' names # # +------------+---------------------------------------------------------------------------------------------------------+ # | 1265342678 | "tmp/mysql.backup.auto.2022-02-14T10:13:13Z.tar.gz" | # +------------+---------------------------------------------------------------------------------------------------------+ # | 2346254257 | "tmp/mysql.backup.auto.2022-02-11T10:13:13Z.tar.gz tmp/mysql.backup.manual.2022-02-11T10:13:13Z.tar.gz" | # +------------+---------------------------------------------------------------------------------------------------------+ # <...> # +------------+---------------------------------------------------------------------------------------------------------+ # | 6253434567 | "tmp/mysql.backup.manual.2022-02-01T10:13:13Z.tar.gz" | # +------------+---------------------------------------------------------------------------------------------------------+ # We will use the explained above data stracture to cover rare, but still # possible case, when we have several backups of the same date. E.g. # one manual, and one automatic. declare -A fileTable create_hash_table() { unset fileTable fileList=$@ for ARCHIVE_FILE in ${fileList}; do # Creating index, we will round given ARCHIVE_DATE to the midnight (00:00:00) # to take in account a possibility, that we can have more than one scheduled # backup per day. ARCHIVE_DATE=$(get_archive_date ${ARCHIVE_FILE}) ARCHIVE_DATE=$(date --date=${ARCHIVE_DATE} +%D) log INFO "${DB_NAME}_backup" "Archive date to build index: ${ARCHIVE_DATE}" INDEX=$(seconds_difference ${ARCHIVE_DATE}) if [[ -z fileTable[${INDEX}] ]]; then fileTable[${INDEX}]=${ARCHIVE_FILE} else fileTable[${INDEX}]="${fileTable[${INDEX}]} ${ARCHIVE_FILE}" fi echo "INDEX: ${INDEX} VALUE: ${fileTable[${INDEX}]}" done } function get_backup_prefix() { # Create list of all possible prefixes in a format: # . to cover a possible situation # when different backups of different databases and/or # namespaces share the same local or remote storage. ALL_FILES=($@) PREFIXES=() for fname in ${ALL_FILES[@]}; do prefix=$(basename ${fname} | cut -d'.' -f1,2 ) for ((i=0; i<${#PREFIXES[@]}; i++)) do if [[ ${PREFIXES[${i}]} == ${prefix} ]]; then prefix="" break fi done if [[ ! -z ${prefix} ]]; then PREFIXES+=(${prefix}) fi done } remove_old_local_archives() { SECONDS_TO_KEEP=$(( $((${LOCAL_DAYS_TO_KEEP}))*86400)) log INFO "${DB_NAME}_backup" "Deleting backups older than ${LOCAL_DAYS_TO_KEEP} days (${SECONDS_TO_KEEP} seconds)" if [[ -d $ARCHIVE_DIR ]]; then count=0 # We iterate over the hash table, checking the delta in seconds (hash keys), # and minimum number of backups we must have in place. List of keys has to be sorted. for INDEX in $(tr " " "\n" <<< ${!fileTable[@]} | sort -n -); do ARCHIVE_FILE=${fileTable[${INDEX}]} if [[ ${INDEX} -lt ${SECONDS_TO_KEEP} || ${count} -lt ${LOCAL_DAYS_TO_KEEP} ]]; then ((count++)) log INFO "${DB_NAME}_backup" "Keeping file(s) ${ARCHIVE_FILE}." else log INFO "${DB_NAME}_backup" "Deleting file(s) ${ARCHIVE_FILE}." rm -f ${ARCHIVE_FILE} if [[ $? -ne 0 ]]; then # Log error but don't exit so we can finish the script # because at this point we haven't sent backup to RGW yet log ERROR "${DB_NAME}_backup" "Failed to cleanup local backup. Cannot remove some of ${ARCHIVE_FILE}" fi fi done else log WARN "${DB_NAME}_backup" "The local backup directory ${$ARCHIVE_DIR} does not exist." fi } prepare_list_of_remote_backups() { BACKUP_FILES=$(mktemp -p /tmp) DB_BACKUP_FILES=$(mktemp -p /tmp) openstack object list $CONTAINER_NAME > $BACKUP_FILES if [[ $? -ne 0 ]]; then log_backup_error_exit \ "Failed to cleanup remote backup. Could not obtain a list of current backup files in the RGW" fi # Filter out other types of backup files cat $BACKUP_FILES | grep $DB_NAME | grep $DB_NAMESPACE | awk '{print $2}' > $DB_BACKUP_FILES } # The logic implemented with this function is absolutely similar # to the function remove_old_local_archives (see above) remove_old_remote_archives() { count=0 SECONDS_TO_KEEP=$((${REMOTE_DAYS_TO_KEEP}*86400)) log INFO "${DB_NAME}_backup" "Deleting backups older than ${REMOTE_DAYS_TO_KEEP} days (${SECONDS_TO_KEEP} seconds)" for INDEX in $(tr " " "\n" <<< ${!fileTable[@]} | sort -n -); do ARCHIVE_FILE=${fileTable[${INDEX}]} if [[ ${INDEX} -lt ${SECONDS_TO_KEEP} || ${count} -lt ${REMOTE_DAYS_TO_KEEP} ]]; then ((count++)) log INFO "${DB_NAME}_backup" "Keeping remote backup(s) ${ARCHIVE_FILE}." else log INFO "${DB_NAME}_backup" "Deleting remote backup(s) ${ARCHIVE_FILE} from the RGW" openstack object delete ${CONTAINER_NAME} ${ARCHIVE_FILE} || log WARN "${DB_NAME}_backup" \ "Failed to cleanup remote backup. Cannot delete container object ${ARCHIVE_FILE}" fi done # Cleanup now that we're done. for fd in ${BACKUP_FILES} ${DB_BACKUP_FILES}; do if [[ -f ${fd} ]]; then rm -f ${fd} else log WARN "${DB_NAME}_backup" "Can not delete a temporary file ${fd}" fi done } # Main function to backup the databases. Calling functions need to supply: # 1) The directory where the final backup will be kept after it is compressed. # 2) A temporary directory to use for placing database files to be compressed. # Note: this temp directory will be deleted after backup is done. # 3) Optional "scope" parameter indicating what database to back up. Defaults # to "all". backup_databases() { SCOPE=${1:-"all"} # Create necessary directories if they do not exist. mkdir -p $ARCHIVE_DIR || log_backup_error_exit \ "Backup of the ${DB_NAME} database failed. Cannot create directory ${ARCHIVE_DIR}!" export TMP_DIR=$(mktemp -d) || log_backup_error_exit \ "Backup of the ${DB_NAME} database failed. Cannot create temp directory!" # Create temporary log file export ERR_LOG_FILE=$(mktemp -p /tmp) || log_backup_error_exit \ "Backup of the ${DB_NAME} database failed. Cannot create log file!" # It is expected that this function will dump the database files to the $TMP_DIR dump_databases_to_directory $TMP_DIR $ERR_LOG_FILE $SCOPE # If successful, there should be at least one file in the TMP_DIR if [[ $? -ne 0 || $(ls $TMP_DIR | wc -w) -eq 0 ]]; then cat $ERR_LOG_FILE log_backup_error_exit "Backup of the ${DB_NAME} database failed and needs attention." fi log INFO "${DB_NAME}_backup" "Databases dumped successfully. Creating tarball..." NOW=$(date +"%Y-%m-%dT%H:%M:%SZ") if [[ -z "${BACK_UP_MODE}" ]]; then TARBALL_FILE="${DB_NAME}.${DB_NAMESPACE}.${SCOPE}.${NOW}.tar.gz" else TARBALL_FILE="${DB_NAME}.${DB_NAMESPACE}.${SCOPE}.${BACK_UP_MODE}.${NOW}.tar.gz" fi cd $TMP_DIR || log_backup_error_exit \ "Backup of the ${DB_NAME} database failed. Cannot change to directory $TMP_DIR" #Archive the current database files tar zcvf $ARCHIVE_DIR/$TARBALL_FILE * if [[ $? -ne 0 ]]; then log_backup_error_exit \ "Backup ${DB_NAME} to local file system failed. Backup tarball could not be created." fi # Get the size of the file ARCHIVE_SIZE=$(ls -l $ARCHIVE_DIR/$TARBALL_FILE | awk '{print $5}') log INFO "${DB_NAME}_backup" "Tarball $TARBALL_FILE created successfully." cd $ARCHIVE_DIR #Only delete the old archive after a successful archive export LOCAL_DAYS_TO_KEEP=$(echo $LOCAL_DAYS_TO_KEEP | sed 's/"//g') if [[ "$LOCAL_DAYS_TO_KEEP" -gt 0 ]]; then get_backup_prefix $(ls -1 ${ARCHIVE_DIR}/*.gz) for ((i=0; i<${#PREFIXES[@]}; i++)); do echo "Working with prefix: ${PREFIXES[i]}" create_hash_table $(ls -1 ${ARCHIVE_DIR}/${PREFIXES[i]}*.gz) remove_old_local_archives done fi # Local backup verification process # It is expected that this function will verify the database backup files if verify_databases_backup_archives ${SCOPE}; then log INFO "${DB_NAME}_backup_verify" "Databases backup verified successfully. Uploading verified backups to remote location..." else # If successful, there should be at least one file in the TMP_DIR if [[ $(ls $TMP_DIR | wc -w) -eq 0 ]]; then cat $ERR_LOG_FILE fi log_verify_backup_exit "Verify of the ${DB_NAME} database backup failed and needs attention." exit 1 fi # Remove the temporary directory and files as they are no longer needed. rm -rf $TMP_DIR rm -f $ERR_LOG_FILE # Remote backup REMOTE_BACKUP=$(echo $REMOTE_BACKUP_ENABLED | sed 's/"//g') if $REMOTE_BACKUP; then # Remove Quotes from the constants which were added due to reading # from secret. export REMOTE_BACKUP_RETRIES=$(echo $REMOTE_BACKUP_RETRIES | sed 's/"//g') export MIN_DELAY_SEND_REMOTE=$(echo $MIN_DELAY_SEND_REMOTE | sed 's/"//g') export MAX_DELAY_SEND_REMOTE=$(echo $MAX_DELAY_SEND_REMOTE | sed 's/"//g') export REMOTE_DAYS_TO_KEEP=$(echo $REMOTE_DAYS_TO_KEEP | sed 's/"//g') store_backup_remotely $ARCHIVE_DIR $TARBALL_FILE if [[ $? -ne 0 ]]; then # This error should print first, then print the summary as the last # thing that the user sees in the output. log ERROR "${DB_NAME}_backup" "Backup ${TARBALL_FILE} could not be sent to remote RGW." echo "==================================================================" echo "Local backup successful, but could not send to remote RGW." echo "Backup archive name: $TARBALL_FILE" echo "Backup archive size: $ARCHIVE_SIZE" echo "==================================================================" # Because the local backup was successful, exit with 0 so the pod will not # continue to restart and fill the disk with more backups. The ERRORs are # logged and alerting system should catch those errors and flag the operator. exit 0 fi #Only delete the old archive after a successful archive if [[ "$REMOTE_DAYS_TO_KEEP" -gt 0 ]]; then prepare_list_of_remote_backups get_backup_prefix $(cat $DB_BACKUP_FILES) for ((i=0; i<${#PREFIXES[@]}; i++)); do echo "Working with prefix: ${PREFIXES[i]}" create_hash_table $(cat ${DB_BACKUP_FILES} | grep ${PREFIXES[i]}) remove_old_remote_archives done fi echo "==================================================================" echo "Local backup and backup to remote RGW successful!" echo "Backup archive name: $TARBALL_FILE" echo "Backup archive size: $ARCHIVE_SIZE" echo "==================================================================" else # Remote backup is not enabled. This is ok; at least we have a local backup. log INFO "${DB_NAME}_backup" "Skipping remote backup, as it is not enabled." echo "==================================================================" echo "Local backup successful!" echo "Backup archive name: $TARBALL_FILE" echo "Backup archive size: $ARCHIVE_SIZE" echo "==================================================================" fi } {{- end }} ================================================ FILE: helm-toolkit/templates/scripts/db-backup-restore/_restore_main.sh.tpl ================================================ {{- define "helm-toolkit.scripts.db-backup-restore.restore_main" }} #!/bin/bash # This file contains a database restore framework which database scripts # can use to perform a backup. The idea here is that the database-specific # functions will be implemented by the various databases using this script # (like mariadb, postgresql or etcd for example). The database-specific # script will need to first "source" this file like this: # source /tmp/restore_main.sh # # Then the script should call the main CLI function (cli_main): # cli_main # where: # is the list of arguments given by the user # # The framework will require the following variables to be exported: # # export DB_NAMESPACE Namespace where the database(s) reside # export DB_NAME Name of the database system # export ARCHIVE_DIR Location where the backup tarballs should # be stored. (full directory path which # should already exist) # export CONTAINER_NAME Name of the container on the RGW where # the backups are stored. # RGW access variables: # export OS_REGION_NAME Name of the region the RGW resides in # export OS_AUTH_URL Keystone URL associated with the RGW # export OS_PROJECT_NAME Name of the project associated with the # keystone user # export OS_USERNAME Name of the keystone user # export OS_PASSWORD Password of the keystone user # export OS_USER_DOMAIN_NAME Keystone domain the project belongs to # export OS_PROJECT_DOMAIN_NAME Keystone domain the user belongs to # export OS_IDENTITY_API_VERSION Keystone API version to use # # The database-specific functions that need to be implemented are: # get_databases # where: # is the full directory path where the decompressed # database files reside # is the full path of the file to write the database # names into, one database per line # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to extract the database names from the # uncompressed database files found in the given "tmp_dir", which is # the staging directory for database restore. The database names # should be written to the given "db_file", one database name per # line. # # get_tables # is the name of the database to get the tables from # is the full directory path where the decompressed # database files reside # is the full path of the file to write the table # names into, one table per line # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to extract the table names from the given # database, found in the uncompressed database files located in the # given "tmp_dir", which is the staging directory for database restore. # The table names should be written to the given "table_file", one # table name per line. # # get_rows # is the name of the table to get the rows from # is the name of the database the table resides in # is the full directory path where the decompressed # database files reside # is the full path of the file to write the table # row data into, one row (INSERT statement) per line # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to extract the rows from the given table # in the given database, found in the uncompressed database files # located in the given "tmp_dir", which is the staging directory for # database restore. The table rows should be written to the given # "rows_file", one row (INSERT statement) per line. # # get_schema # is the name of the table to get the schema from # is the name of the database the table resides in # is the full directory path where the decompressed # database files reside # is the full path of the file to write the table # schema data into # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to extract the schema from the given table # in the given database, found in the uncompressed database files # located in the given "tmp_dir", which is the staging directory for # database restore. The table schema and related alterations and # grant information should be written to the given "schema_file". # # restore_single_db # where: # is the name of the database to be restored # is the full directory path where the decompressed # database files reside # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to restore the database given as "db_name" # using the database files located in the "tmp_dir". The framework # will delete the "tmp_dir" and the files in it after the restore is # complete. # # restore_all_dbs # where: # is the full directory path where the decompressed # database files reside # returns: 0 if no errors; 1 if any errors occurred # # This function is expected to restore all of the databases which # are backed up in the database files located in the "tmp_dir". The # framework will delete the "tmp_dir" and the files in it after the # restore is complete. # # The functions in this file will take care of: # 1) The CLI parameter parsing for the arguments passed in by the user. # 2) The listing of either local or remote archive files at the request # of the user. # 3) The retrieval/download of an archive file located either in the local # file system or remotely stored on an RGW. # 4) Calling either "restore_single_db" or "restore_all_dbs" when the user # chooses to restore a database or all databases. # 5) The framework will call "get_databases" when it needs a list of # databases when the user requests a database list or when the user # requests to restore a single database (to ensure it exists in the # archive). Similarly, the framework will call "get_tables", "get_rows", # or "get_schema" when it needs that data requested by the user. # usage() { ret_val=$1 echo "Usage:" echo "Restore command options" echo "=============================" echo "help" echo "list_archives [remote]" echo "list_databases [remote]" echo "list_tables [remote]" echo "list_rows [remote]" echo "list_schema [remote]" echo "restore [remote]" echo " where = | ALL" echo "delete_archive [remote]" clean_and_exit $ret_val "" } log() { #Log message to a file or stdout #TODO: This can be convert into mail alert of alert send to a monitoring system #Params: $1 log level #Params: $2 service #Params: $3 message #Params: $4 Destination LEVEL=$1 SERVICE=$2 MSG=$3 DEST=$4 DATE=$(date +"%m-%d-%y %H:%M:%S") if [[ -z "$DEST" ]]; then echo "${DATE} ${LEVEL}: $(hostname) ${SERVICE}: ${MSG}" else echo "${DATE} ${LEVEL}: $(hostname) ${SERVICE}: ${MSG}" >>$DEST fi } #Exit cleanly with some message and return code clean_and_exit() { RETCODE=$1 MSG=$2 # Clean/remove temporary directories/files rm -rf $TMP_DIR rm -f $RESULT_FILE if [[ "x${MSG}" != "x" ]]; then echo $MSG fi exit $RETCODE } determine_resulting_error_code() { RESULT="$1" echo ${RESULT} | grep "HTTP 404" if [[ $? -eq 0 ]]; then log ERROR "${DB_NAME}_restore" "Could not find the archive: ${RESULT}" return 1 else echo ${RESULT} | grep "HTTP 401" if [[ $? -eq 0 ]]; then log ERROR "${DB_NAME}_restore" "Could not access the archive: ${RESULT}" return 1 else echo ${RESULT} | grep "HTTP 503" if [[ $? -eq 0 ]]; then log WARN "${DB_NAME}_restore" "RGW service is unavailable. ${RESULT}" # In this case, the RGW may be temporarily down. # Return slightly different error code so the calling code can retry return 2 else echo ${RESULT} | grep "ConnectionError" if [[ $? -eq 0 ]]; then log WARN "${DB_NAME}_restore" "Could not reach the RGW: ${RESULT}" # In this case, keystone or the site/node may be temporarily down. # Return slightly different error code so the calling code can retry return 2 else log ERROR "${DB_NAME}_restore" "Archive ${ARCHIVE} could not be retrieved: ${RESULT}" return 1 fi fi fi fi return 0 } # Retrieve a list of archives from the RGW. function retrieve_remote_listing() { # List archives from PRIMARY RGW log INFO "${DB_NAME}_restore" "Listing archives from PRIMARY RGW..." list_archives_from_rgw "PRIMARY" local primary_result=$? # Check if failover environment variables are defined if [[ -n "${OS_AUTH_URL_FAILOVER}" ]] && \ [[ -n "${OS_REGION_NAME_FAILOVER}" ]] && \ [[ -n "${OS_INTERFACE_FAILOVER}" ]] && \ [[ -n "${OS_PROJECT_DOMAIN_NAME_FAILOVER}" ]] && \ [[ -n "${OS_PROJECT_NAME_FAILOVER}" ]] && \ [[ -n "${OS_USER_DOMAIN_NAME_FAILOVER}" ]] && \ [[ -n "${OS_USERNAME_FAILOVER}" ]] && \ [[ -n "${OS_PASSWORD_FAILOVER}" ]]; then # Redefine OS_* variables with OS_*_FAILOVER ones log INFO "${DB_NAME}_restore" "Listing archives from FAILOVER RGW..." # Saving original OS_* variables as OS_*_PRIMARY export OS_AUTH_URL_PRIMARY=${OS_AUTH_URL} export OS_REGION_NAME_PRIMARY=${OS_REGION_NAME} export OS_INTERFACE_PRIMARY=${OS_INTERFACE} export OS_PROJECT_DOMAIN_NAME_PRIMARY=${OS_PROJECT_DOMAIN_NAME} export OS_PROJECT_NAME_PRIMARY=${OS_PROJECT_NAME} export OS_USER_DOMAIN_NAME_PRIMARY=${OS_USER_DOMAIN_NAME} export OS_USERNAME_PRIMARY=${OS_USERNAME} export OS_PASSWORD_PRIMARY=${OS_PASSWORD} export OS_DEFAULT_DOMAIN_PRIMARY=${OS_DEFAULT_DOMAIN} export OS_AUTH_URL=${OS_AUTH_URL_FAILOVER} export OS_REGION_NAME=${OS_REGION_NAME_FAILOVER} export OS_INTERFACE=${OS_INTERFACE_FAILOVER} export OS_PROJECT_DOMAIN_NAME=${OS_PROJECT_DOMAIN_NAME_FAILOVER} export OS_PROJECT_NAME=${OS_PROJECT_NAME_FAILOVER} export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME_FAILOVER} export OS_USERNAME=${OS_USERNAME_FAILOVER} export OS_PASSWORD=${OS_PASSWORD_FAILOVER} export OS_DEFAULT_DOMAIN=${OS_DEFAULT_DOMAIN_FAILOVER} list_archives_from_rgw "FAILOVER" local failover_result=$? # Restore original OS_* variables from OS_*_PRIMARY export OS_AUTH_URL=${OS_AUTH_URL_PRIMARY} export OS_REGION_NAME=${OS_REGION_NAME_PRIMARY} export OS_INTERFACE=${OS_INTERFACE_PRIMARY} export OS_PROJECT_DOMAIN_NAME=${OS_PROJECT_DOMAIN_NAME_PRIMARY} export OS_PROJECT_NAME=${OS_PROJECT_NAME_PRIMARY} export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME_PRIMARY} export OS_USERNAME=${OS_USERNAME_PRIMARY} export OS_PASSWORD=${OS_PASSWORD_PRIMARY} export OS_DEFAULT_DOMAIN=${OS_DEFAULT_DOMAIN_PRIMARY} # Return success if either primary or failover listing was successful if [[ $primary_result -eq 0 || $failover_result -eq 0 ]]; then return 0 else return 1 fi else # Return the result of the primary listing if failover variables are not defined return $primary_result fi } function list_archives_from_rgw() { local prefix=$1 local RESULT log INFO "${DB_NAME}_restore" "Obtaining list of archives from ${prefix} RGW..." RESULT=$(openstack container show $CONTAINER_NAME 2>&1) if [[ $? -eq 0 ]]; then openstack object list $CONTAINER_NAME | grep $DB_NAME | grep $DB_NAMESPACE | awk -v prefix="$prefix" '{print prefix ":" $2}' >> $TMP_DIR/archive_list if [[ $? -ne 0 ]]; then log ERROR "${DB_NAME}_restore" "Container object listing could not be obtained from ${prefix} RGW." return 1 else log INFO "${DB_NAME}_restore" "Archive listing successfully retrieved from ${prefix} RGW." fi else log ERROR "${DB_NAME}_restore" "Failed to obtain container show from ${prefix} RGW: ${RESULT}" return 1 fi return 0 } # Retrieve a single archive from the RGW. retrieve_remote_archive() { local archive=$1 local prefix=$(echo $archive | awk -F: '{print $1}') local filename if [[ $prefix == "PRIMARY" || $prefix == "FAILOVER" ]]; then filename=$(echo $archive | awk -F: '{print $2":"$3":"$4}') else filename=$archive fi if [[ $prefix == "PRIMARY" ]]; then log INFO "${DB_NAME}_restore" "Retrieving archive ${filename} from PRIMARY RGW..." retrieve_archive_from_rgw $filename return $? elif [[ $prefix == "FAILOVER" ]]; then log INFO "${DB_NAME}_restore" "Retrieving archive ${filename} from FAILOVER RGW..." # Saving original OS_* variables as OS_*_PRIMARY export OS_AUTH_URL_PRIMARY=${OS_AUTH_URL} export OS_REGION_NAME_PRIMARY=${OS_REGION_NAME} export OS_INTERFACE_PRIMARY=${OS_INTERFACE} export OS_PROJECT_DOMAIN_NAME_PRIMARY=${OS_PROJECT_DOMAIN_NAME} export OS_PROJECT_NAME_PRIMARY=${OS_PROJECT_NAME} export OS_USER_DOMAIN_NAME_PRIMARY=${OS_USER_DOMAIN_NAME} export OS_USERNAME_PRIMARY=${OS_USERNAME} export OS_PASSWORD_PRIMARY=${OS_PASSWORD} export OS_DEFAULT_DOMAIN_PRIMARY=${OS_DEFAULT_DOMAIN} # Redefine OS_* variables with OS_*_FAILOVER ones export OS_AUTH_URL=${OS_AUTH_URL_FAILOVER} export OS_REGION_NAME=${OS_REGION_NAME_FAILOVER} export OS_INTERFACE=${OS_INTERFACE_FAILOVER} export OS_PROJECT_DOMAIN_NAME=${OS_PROJECT_DOMAIN_NAME_FAILOVER} export OS_PROJECT_NAME=${OS_PROJECT_NAME_FAILOVER} export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME_FAILOVER} export OS_USERNAME=${OS_USERNAME_FAILOVER} export OS_PASSWORD=${OS_PASSWORD_FAILOVER} export OS_DEFAULT_DOMAIN=${OS_DEFAULT_DOMAIN_FAILOVER} retrieve_archive_from_rgw $filename local result=$? # Restore original OS_* variables from OS_*_PRIMARY export OS_AUTH_URL=${OS_AUTH_URL_PRIMARY} export OS_REGION_NAME=${OS_REGION_NAME_PRIMARY} export OS_INTERFACE=${OS_INTERFACE_PRIMARY} export OS_PROJECT_DOMAIN_NAME=${OS_PROJECT_DOMAIN_NAME_PRIMARY} export OS_PROJECT_NAME=${OS_PROJECT_NAME_PRIMARY} export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME_PRIMARY} export OS_USERNAME=${OS_USERNAME_PRIMARY} export OS_PASSWORD=${OS_PASSWORD_PRIMARY} export OS_DEFAULT_DOMAIN=${OS_DEFAULT_DOMAIN_PRIMARY} return $result else log ERROR "${DB_NAME}_restore" "Invalid prefix ${prefix} for archive ${archive}." return 1 fi } # Function to retrieve an archive from RGW retrieve_archive_from_rgw() { local filename=$1 local RESULT log INFO "${DB_NAME}_restore" "Obtaining archive ${filename} from RGW..." RESULT=$(openstack object save --file $TMP_DIR/${filename} $CONTAINER_NAME ${filename} 2>&1) if [[ $? -eq 0 ]]; then log INFO "${DB_NAME}_restore" "Archive ${filename} successfully retrieved." return 0 else log ERROR "${DB_NAME}_restore" "Failed to retrieve archive ${filename}." determine_resulting_error_code "${RESULT}" return $? fi } # Delete an archive from the RGW. # Delete a single archive from the RGW. delete_remote_archive() { local archive=$1 local prefix=$(echo $archive | awk -F: '{print $1}') local filename if [[ $prefix == "PRIMARY" || $prefix == "FAILOVER" ]]; then filename=$(echo $archive | awk -F: '{print $2":"$3":"$4}') else filename=$archive fi if [[ $prefix == "PRIMARY" ]]; then log INFO "${DB_NAME}_restore" "Deleting archive ${filename} from PRIMARY RGW..." delete_archive_from_rgw $filename return $? elif [[ $prefix == "FAILOVER" ]]; then log INFO "${DB_NAME}_restore" "Deleting archive ${filename} from FAILOVER RGW..." # Saving original OS_* variables as OS_*_PRIMARY export OS_AUTH_URL_PRIMARY=${OS_AUTH_URL} export OS_REGION_NAME_PRIMARY=${OS_REGION_NAME} export OS_INTERFACE_PRIMARY=${OS_INTERFACE} export OS_PROJECT_DOMAIN_NAME_PRIMARY=${OS_PROJECT_DOMAIN_NAME} export OS_PROJECT_NAME_PRIMARY=${OS_PROJECT_NAME} export OS_USER_DOMAIN_NAME_PRIMARY=${OS_USER_DOMAIN_NAME} export OS_USERNAME_PRIMARY=${OS_USERNAME} export OS_PASSWORD_PRIMARY=${OS_PASSWORD} export OS_DEFAULT_DOMAIN_PRIMARY=${OS_DEFAULT_DOMAIN} # Redefine OS_* variables with OS_*_FAILOVER ones export OS_AUTH_URL=${OS_AUTH_URL_FAILOVER} export OS_REGION_NAME=${OS_REGION_NAME_FAILOVER} export OS_INTERFACE=${OS_INTERFACE_FAILOVER} export OS_PROJECT_DOMAIN_NAME=${OS_PROJECT_DOMAIN_NAME_FAILOVER} export OS_PROJECT_NAME=${OS_PROJECT_NAME_FAILOVER} export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME_FAILOVER} export OS_USERNAME=${OS_USERNAME_FAILOVER} export OS_PASSWORD=${OS_PASSWORD_FAILOVER} export OS_DEFAULT_DOMAIN=${OS_DEFAULT_DOMAIN_FAILOVER} delete_archive_from_rgw $filename local result=$? # Restore original OS_* variables from OS_*_PRIMARY export OS_AUTH_URL=${OS_AUTH_URL_PRIMARY} export OS_REGION_NAME=${OS_REGION_NAME_PRIMARY} export OS_INTERFACE=${OS_INTERFACE_PRIMARY} export OS_PROJECT_DOMAIN_NAME=${OS_PROJECT_DOMAIN_NAME_PRIMARY} export OS_PROJECT_NAME=${OS_PROJECT_NAME_PRIMARY} export OS_USER_DOMAIN_NAME=${OS_USER_DOMAIN_NAME_PRIMARY} export OS_USERNAME=${OS_USERNAME_PRIMARY} export OS_PASSWORD=${OS_PASSWORD_PRIMARY} export OS_DEFAULT_DOMAIN=${OS_DEFAULT_DOMAIN_PRIMARY} return $result else log ERROR "${DB_NAME}_restore" "Invalid prefix ${prefix} for archive ${archive}." return 1 fi } # Function to delete an archive from RGW delete_archive_from_rgw() { local filename=$1 local RESULT RESULT=$(openstack object delete $CONTAINER_NAME $filename 2>&1) if [[ $? -eq 0 ]]; then log INFO "${DB_NAME}_restore" "Archive ${filename} successfully deleted." return 0 else log ERROR "${DB_NAME}_restore" "Failed to delete archive ${filename}." determine_resulting_error_code "${RESULT}" return $? fi } # Display all archives list_archives() { REMOTE=$1 if [[ "x${REMOTE^^}" == "xREMOTE" ]]; then retrieve_remote_listing if [[ $? -eq 0 && -e $TMP_DIR/archive_list ]]; then echo echo "All Archives from RGW Data Store" echo "==============================================" cat $TMP_DIR/archive_list | sort clean_and_exit 0 "" else clean_and_exit 1 "ERROR: Archives could not be retrieved from the RGW." fi elif [[ "x${REMOTE}" == "x" ]]; then if [[ -d $ARCHIVE_DIR ]]; then archives=$(find $ARCHIVE_DIR/ -iname "*.gz" -print | sort) echo echo "All Local Archives" echo "==============================================" for archive in $archives do echo $archive | cut -d '/' -f8- done clean_and_exit 0 "" else clean_and_exit 1 "ERROR: Local archive directory is not available." fi else usage 1 fi } # Retrieve the archive from the desired location and decompress it into # the restore directory get_archive() { local archive=$1 local prefix=$(echo $archive | awk -F: '{print $1}') local filename if [[ $prefix == "PRIMARY" || $prefix == "FAILOVER" ]]; then filename=$(echo $archive | awk -F: '{print $2":"$3":"$4}') else filename=$archive fi REMOTE=$2 if [[ "x$REMOTE" == "xremote" ]]; then log INFO "${DB_NAME}_restore" "Retrieving archive ${prefix}:${filename} from the remote RGW..." retrieve_remote_archive ${prefix}:${filename} if [[ $? -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not retrieve remote archive: ${prefix}:${filename}" fi elif [[ "x$REMOTE" == "x" ]]; then if [[ -e $ARCHIVE_DIR/$filename ]]; then cp $ARCHIVE_DIR/$filename $TMP_DIR/$filename if [[ $? -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not copy local archive to restore directory." fi else clean_and_exit 1 "ERROR: Local archive file could not be found." fi else usage 1 fi log INFO "${DB_NAME}_restore" "Decompressing archive $filename..." cd $TMP_DIR tar zxvf - < $TMP_DIR/$filename 1>/dev/null if [[ $? -ne 0 ]]; then clean_and_exit 1 "ERROR: Archive decompression failed." fi } # Display all databases from an archive list_databases() { ARCHIVE_FILE=$1 REMOTE=$2 WHERE="local" if [[ -n ${REMOTE} ]]; then WHERE="remote" fi # Get the archive from the source location (local/remote) get_archive $ARCHIVE_FILE $REMOTE # Expectation is that the database listing will be put into # the given file one database per line get_databases $TMP_DIR $RESULT_FILE if [[ "$?" -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not retrieve databases from $WHERE archive $ARCHIVE_FILE." fi if [[ -f "$RESULT_FILE" ]]; then echo " " echo "Databases in the $WHERE archive $ARCHIVE_FILE" echo "================================================================================" cat $RESULT_FILE else clean_and_exit 1 "ERROR: Databases file missing. Could not list databases from $WHERE archive $ARCHIVE_FILE." fi } # Display all tables of a database from an archive list_tables() { ARCHIVE_FILE=$1 DATABASE=$2 REMOTE=$3 WHERE="local" if [[ -n ${REMOTE} ]]; then WHERE="remote" fi # Get the archive from the source location (local/remote) get_archive $ARCHIVE_FILE $REMOTE # Expectation is that the database listing will be put into # the given file one table per line get_tables $DATABASE $TMP_DIR $RESULT_FILE if [[ "$?" -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not retrieve tables for database ${DATABASE} from $WHERE archive $ARCHIVE_FILE." fi if [[ -f "$RESULT_FILE" ]]; then echo " " echo "Tables in database $DATABASE from $WHERE archive $ARCHIVE_FILE" echo "================================================================================" cat $RESULT_FILE else clean_and_exit 1 "ERROR: Tables file missing. Could not list tables of database ${DATABASE} from $WHERE archive $ARCHIVE_FILE." fi } # Display all rows of the given database table from an archive list_rows() { ARCHIVE_FILE=$1 DATABASE=$2 TABLE=$3 REMOTE=$4 WHERE="local" if [[ -n ${REMOTE} ]]; then WHERE="remote" fi # Get the archive from the source location (local/remote) get_archive $ARCHIVE_FILE $REMOTE # Expectation is that the database listing will be put into # the given file one table per line get_rows $DATABASE $TABLE $TMP_DIR $RESULT_FILE if [[ "$?" -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not retrieve rows in table ${TABLE} of database ${DATABASE} from $WHERE archive $ARCHIVE_FILE." fi if [[ -f "$RESULT_FILE" ]]; then echo " " echo "Rows in table $TABLE of database $DATABASE from $WHERE archive $ARCHIVE_FILE" echo "================================================================================" cat $RESULT_FILE else clean_and_exit 1 "ERROR: Rows file missing. Could not list rows in table ${TABLE} of database ${DATABASE} from $WHERE archive $ARCHIVE_FILE." fi } # Display the schema information of the given database table from an archive list_schema() { ARCHIVE_FILE=$1 DATABASE=$2 TABLE=$3 REMOTE=$4 WHERE="local" if [[ -n ${REMOTE} ]]; then WHERE="remote" fi # Get the archive from the source location (local/remote) get_archive $ARCHIVE_FILE $REMOTE # Expectation is that the schema information will be placed into # the given schema file. get_schema $DATABASE $TABLE $TMP_DIR $RESULT_FILE if [[ "$?" -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not retrieve schema for table ${TABLE} of database ${DATABASE} from $WHERE archive $ARCHIVE_FILE." fi if [[ -f "$RESULT_FILE" ]]; then echo " " echo "Schema for table $TABLE of database $DATABASE from $WHERE archive $ARCHIVE_FILE" echo "================================================================================" cat $RESULT_FILE else clean_and_exit 1 "ERROR: Schema file missing. Could not list schema for table ${TABLE} of database ${DATABASE} from $WHERE archive $ARCHIVE_FILE." fi } # Delete an archive delete_archive() { ARCHIVE_FILE=$1 REMOTE=$2 WHERE="local" if [[ -n ${REMOTE} ]]; then WHERE="remote" fi if [[ "${WHERE}" == "remote" ]]; then delete_remote_archive ${ARCHIVE_FILE} if [[ $? -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not delete remote archive: ${ARCHIVE_FILE}" fi else # Local if [[ -e ${ARCHIVE_DIR}/${ARCHIVE_FILE} ]]; then rm -f ${ARCHIVE_DIR}/${ARCHIVE_FILE} if [[ $? -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not delete local archive." fi else clean_and_exit 1 "ERROR: Local archive file could not be found." fi fi log INFO "${DB_NAME}_restore" "Successfully deleted archive ${ARCHIVE_FILE} from ${WHERE} storage." } # Return 1 if the given database exists in the database file. 0 otherwise. database_exists() { DB=$1 grep "${DB}" ${RESULT_FILE} if [[ $? -eq 0 ]]; then return 1 fi return 0 } # This is the main CLI interpreter function cli_main() { ARGS=("$@") # Create the ARCHIVE DIR if it's not already there. mkdir -p $ARCHIVE_DIR # Create temp directory for a staging area to decompress files into export TMP_DIR=$(mktemp -d) # Create a temp file for storing list of databases (if needed) export RESULT_FILE=$(mktemp -p /tmp) case "${ARGS[0]}" in "help") usage 0 ;; "list_archives") if [[ ${#ARGS[@]} -gt 2 ]]; then usage 1 elif [[ ${#ARGS[@]} -eq 1 ]]; then list_archives else list_archives ${ARGS[1]} fi clean_and_exit 0 ;; "list_databases") if [[ ${#ARGS[@]} -lt 2 || ${#ARGS[@]} -gt 3 ]]; then usage 1 elif [[ ${#ARGS[@]} -eq 2 ]]; then list_databases ${ARGS[1]} else list_databases ${ARGS[1]} ${ARGS[2]} fi ;; "list_tables") if [[ ${#ARGS[@]} -lt 3 || ${#ARGS[@]} -gt 4 ]]; then usage 1 elif [[ ${#ARGS[@]} -eq 3 ]]; then list_tables ${ARGS[1]} ${ARGS[2]} else list_tables ${ARGS[1]} ${ARGS[2]} ${ARGS[3]} fi ;; "list_rows") if [[ ${#ARGS[@]} -lt 4 || ${#ARGS[@]} -gt 5 ]]; then usage 1 elif [[ ${#ARGS[@]} -eq 4 ]]; then list_rows ${ARGS[1]} ${ARGS[2]} ${ARGS[3]} else list_rows ${ARGS[1]} ${ARGS[2]} ${ARGS[3]} ${ARGS[4]} fi ;; "list_schema") if [[ ${#ARGS[@]} -lt 4 || ${#ARGS[@]} -gt 5 ]]; then usage 1 elif [[ ${#ARGS[@]} -eq 4 ]]; then list_schema ${ARGS[1]} ${ARGS[2]} ${ARGS[3]} else list_schema ${ARGS[1]} ${ARGS[2]} ${ARGS[3]} ${ARGS[4]} fi ;; "restore") REMOTE="" if [[ ${#ARGS[@]} -lt 3 || ${#ARGS[@]} -gt 4 ]]; then usage 1 elif [[ ${#ARGS[@]} -eq 4 ]]; then REMOTE=${ARGS[3]} fi ARCHIVE=${ARGS[1]} DB_SPEC=${ARGS[2]} #Get all the databases in that archive get_archive $ARCHIVE $REMOTE if [[ "$( echo $DB_SPEC | tr '[a-z]' '[A-Z]')" != "ALL" ]]; then # Expectation is that the database listing will be put into # the given file one database per line get_databases $TMP_DIR $RESULT_FILE if [[ "$?" -ne 0 ]]; then clean_and_exit 1 "ERROR: Could not get the list of databases to restore." fi if [[ ! $DB_NAMESPACE == "kube-system" ]]; then #check if the requested database is available in the archive database_exists $DB_SPEC if [[ $? -ne 1 ]]; then clean_and_exit 1 "ERROR: Database ${DB_SPEC} does not exist." fi fi log INFO "${DB_NAME}_restore" "Restoring Database $DB_SPEC And Grants" restore_single_db $DB_SPEC $TMP_DIR if [[ "$?" -eq 0 ]]; then log INFO "${DB_NAME}_restore" "Single database restored successfully." else clean_and_exit 1 "ERROR: Single database restore failed." fi clean_and_exit 0 "" else log INFO "${DB_NAME}_restore" "Restoring All The Databases. This could take a few minutes..." restore_all_dbs $TMP_DIR if [[ "$?" -eq 0 ]]; then log INFO "${DB_NAME}_restore" "All databases restored successfully." else clean_and_exit 1 "ERROR: Database restore failed." fi clean_and_exit 0 "" fi ;; "delete_archive") if [[ ${#ARGS[@]} -lt 2 || ${#ARGS[@]} -gt 3 ]]; then usage 1 elif [[ ${#ARGS[@]} -eq 2 ]]; then delete_archive ${ARGS[1]} else delete_archive ${ARGS[1]} ${ARGS[2]} fi ;; *) usage 1 ;; esac clean_and_exit 0 "" } {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_custom_job_annotations.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Adds custom annotations to the job spec of a component. examples: - values: | annotations: job: default: custom.tld/key: "value" custom.tld/key2: "value2" keystone_domain_manage: another.tld/foo: "bar" usage: | {{ tuple "keystone_domain_manage" . | include "helm-toolkit.snippets.custom_job_annotations" }} return: | another.tld/foo: bar - values: | annotations: job: default: custom.tld/key: "value" custom.tld/key2: "value2" keystone_domain_manage: another.tld/foo: "bar" usage: | {{ tuple "keystone_bootstrap" . | include "helm-toolkit.snippets.custom_job_annotations" }} return: | custom.tld/key: "value" custom.tld/key2: "value2" - values: | annotations: job: default: custom.tld/key: "value" custom.tld/key2: "value2" keystone_domain_manage: another.tld/foo: "bar" keystone_bootstrap: usage: | {{ tuple "keystone_bootstrap" . | include "helm-toolkit.snippets.custom_job_annotations" }} return: | custom.tld/key: "value" custom.tld/key2: "value2" */}} {{- define "helm-toolkit.snippets.custom_job_annotations" -}} {{- $envAll := index . 1 -}} {{- $component := index . 0 | replace "-" "_" -}} {{- if (hasKey $envAll.Values "annotations") -}} {{- if (hasKey $envAll.Values.annotations "job") -}} {{- $annotationsMap := $envAll.Values.annotations.job -}} {{- $defaultAnnotations := dict -}} {{- if (hasKey $annotationsMap "default" ) -}} {{- $defaultAnnotations = $annotationsMap.default -}} {{- end -}} {{- $annotations := index $annotationsMap $component | default $defaultAnnotations -}} {{- if (not (empty $annotations)) -}} {{- toYaml $annotations -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_custom_pod_annotations.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Adds custom annotations to the pod spec of a component. examples: - values: | annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" nova_compute: another.tld/foo: "bar" usage: | {{ tuple "nova_compute" . | include "helm-toolkit.snippets.custom_pod_annotations" }} return: | another.tld/foo: bar - values: | annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" nova_compute: another.tld/foo: "bar" usage: | {{ tuple "nova_api" . | include "helm-toolkit.snippets.custom_pod_annotations" }} return: | custom.tld/key: "value" custom.tld/key2: "value2" - values: | annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" nova_compute: another.tld/foo: "bar" nova_api: usage: | {{ tuple "nova_api" . | include "helm-toolkit.snippets.custom_pod_annotations" }} return: | custom.tld/key: "value" custom.tld/key2: "value2" */}} {{- define "helm-toolkit.snippets.custom_pod_annotations" -}} {{- $component := index . 0 -}} {{- $envAll := index . 1 -}} {{- if (hasKey $envAll.Values "annotations") -}} {{- if (hasKey $envAll.Values.annotations "pod") -}} {{- $annotationsMap := $envAll.Values.annotations.pod -}} {{- $defaultAnnotations := dict -}} {{- if (hasKey $annotationsMap "default" ) -}} {{- $defaultAnnotations = $annotationsMap.default -}} {{- end -}} {{- $annotations := index $annotationsMap $component | default $defaultAnnotations -}} {{- if (not (empty $annotations)) -}} {{- toYaml $annotations -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_custom_secret_annotations.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Adds custom annotations to the secret spec of a component. examples: - values: | annotations: secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" usage: | {{ tuple "identity" "admin" . | include "helm-toolkit.snippets.custom_secret_annotations" }} return: | another.tld/foo: bar - values: | annotations: secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" usage: | {{ tuple "oslo_db" "admin" . | include "helm-toolkit.snippets.custom_secret_annotations" }} return: | custom.tld/key: "value" custom.tld/key2: "value2" - values: | annotations: secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oslo_db: admin: usage: | {{ tuple "oslo_db" "admin" . | include "helm-toolkit.snippets.custom_secret_annotations" }} return: | custom.tld/key: "value" custom.tld/key2: "value2" */}} {{- define "helm-toolkit.snippets.custom_secret_annotations" -}} {{- $secretType := index . 0 -}} {{- $userClass := index . 1 | replace "-" "_" -}} {{- $envAll := index . 2 -}} {{- if (hasKey $envAll.Values "annotations") -}} {{- if (hasKey $envAll.Values.annotations "secret") -}} {{- $annotationsMap := index $envAll.Values.annotations.secret $secretType | default dict -}} {{- $defaultAnnotations := dict -}} {{- if (hasKey $envAll.Values.annotations.secret "default" ) -}} {{- $defaultAnnotations = $envAll.Values.annotations.secret.default -}} {{- end -}} {{- $annotations := index $annotationsMap $userClass | default $defaultAnnotations -}} {{- if (not (empty $annotations)) -}} {{- toYaml $annotations -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_image.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Resolves an image reference to a string, and its pull policy values: | images: tags: test_image: docker.io/port/test:version-foo image_foo: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal pull_policy: IfNotPresent local_registry: active: true exclude: - image_foo endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 usage: | {{ tuple . "test_image" | include "helm-toolkit.snippets.image" }} return: | image: "localhost:5000/docker.io/port/test:version-foo" imagePullPolicy: IfNotPresent */}} {{- define "helm-toolkit.snippets.image" -}} {{- $envAll := index . 0 -}} {{- $image := index . 1 -}} {{- $imageTag := index $envAll.Values.images.tags $image -}} {{- if and ($envAll.Values.images.local_registry.active) (not (has $image $envAll.Values.images.local_registry.exclude )) -}} {{- $registryPrefix := printf "%s:%s" (tuple "local_image_registry" "node" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup") (tuple "local_image_registry" "node" "registry" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup") -}} image: {{ printf "%s/%s" $registryPrefix $imageTag | quote }} {{- else -}} image: {{ $imageTag | quote }} {{- end }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_keystone_openrc_env_vars.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns a set of container enviorment variables, equivlant to an openrc for use with keystone based command line clients. values: | secrets: identity: admin: example-keystone-admin usage: | {{ include "helm-toolkit.snippets.keystone_openrc_env_vars" ( dict "ksUserSecret" .Values.secrets.identity.admin ) }} return: | - name: OS_IDENTITY_API_VERSION value: "3" - name: OS_AUTH_URL valueFrom: secretKeyRef: name: example-keystone-admin key: OS_AUTH_URL - name: OS_REGION_NAME valueFrom: secretKeyRef: name: example-keystone-admin key: OS_REGION_NAME - name: OS_INTERFACE valueFrom: secretKeyRef: name: example-keystone-admin key: OS_INTERFACE - name: OS_ENDPOINT_TYPE valueFrom: secretKeyRef: name: example-keystone-admin key: OS_INTERFACE - name: OS_PROJECT_DOMAIN_NAME valueFrom: secretKeyRef: name: example-keystone-admin key: OS_PROJECT_DOMAIN_NAME - name: OS_PROJECT_NAME valueFrom: secretKeyRef: name: example-keystone-admin key: OS_PROJECT_NAME - name: OS_USER_DOMAIN_NAME valueFrom: secretKeyRef: name: example-keystone-admin key: OS_USER_DOMAIN_NAME - name: OS_USERNAME valueFrom: secretKeyRef: name: example-keystone-admin key: OS_USERNAME - name: OS_PASSWORD valueFrom: secretKeyRef: name: example-keystone-admin key: OS_PASSWORD - name: OS_CACERT valueFrom: secretKeyRef: name: example-keystone-admin key: OS_CACERT */}} {{- define "helm-toolkit.snippets.keystone_openrc_env_vars" }} {{- $useCA := .useCA -}} {{- $ksUserSecret := .ksUserSecret }} - name: OS_IDENTITY_API_VERSION value: "3" - name: OS_AUTH_URL valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_AUTH_URL - name: OS_REGION_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_REGION_NAME - name: OS_INTERFACE valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_INTERFACE - name: OS_ENDPOINT_TYPE valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_INTERFACE - name: OS_PROJECT_DOMAIN_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PROJECT_DOMAIN_NAME - name: OS_PROJECT_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PROJECT_NAME - name: OS_USER_DOMAIN_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_USER_DOMAIN_NAME - name: OS_USERNAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_USERNAME - name: OS_PASSWORD valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PASSWORD - name: OS_DEFAULT_DOMAIN valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_DEFAULT_DOMAIN {{- if $useCA }} - name: OS_CACERT valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_CACERT {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_keystone_openrc_failover_env_vars.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns a set of container failover environment variables, equivlant to an openrc for use with keystone based command line clients. values: | secrets: identity: admin: example-keystone-admin usage: | {{ include "helm-toolkit.snippets.keystone_openrc_failover_env_vars" ( dict "ksUserSecret" .Values.secrets.identity.admin ) }} return: | - name: OS_AUTH_URL_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_AUTH_URL_FAILOVER - name: OS_REGION_NAME_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_REGION_NAME_FAILOVER - name: OS_INTERFACE_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_INTERFACE_FAILOVER - name: OS_PROJECT_DOMAIN_NAME_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_PROJECT_DOMAIN_NAME_FAILOVER - name: OS_PROJECT_NAME_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_PROJECT_NAME_FAILOVER - name: OS_USER_DOMAIN_NAME_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_USER_DOMAIN_NAME_FAILOVER - name: OS_USERNAME_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_USERNAME_FAILOVER - name: OS_PASSWORD_FAILOVER valueFrom: secretKeyRef: name: example-keystone-admin key: OS_PASSWORD_FAILOVER */}} {{- define "helm-toolkit.snippets.keystone_openrc_failover_env_vars" }} {{- $useCA := .useCA -}} {{- $ksUserSecret := .ksUserSecret }} - name: OS_AUTH_URL_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_AUTH_URL_FAILOVER - name: OS_REGION_NAME_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_REGION_NAME_FAILOVER - name: OS_INTERFACE_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_INTERFACE_FAILOVER - name: OS_PROJECT_DOMAIN_NAME_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PROJECT_DOMAIN_NAME_FAILOVER - name: OS_PROJECT_NAME_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PROJECT_NAME_FAILOVER - name: OS_USER_DOMAIN_NAME_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_USER_DOMAIN_NAME_FAILOVER - name: OS_USERNAME_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_USERNAME_FAILOVER - name: OS_PASSWORD_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PASSWORD_FAILOVER - name: OS_DEFAULT_DOMAIN_FAILOVER valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_DEFAULT_DOMAIN_FAILOVER {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_keystone_secret_openrc.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.keystone_secret_openrc" }} {{- $userClass := index . 0 -}} {{- $identityEndpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $userContext := index $context.Values.endpoints.identity.auth $userClass }} OS_AUTH_URL: {{ tuple "identity" $identityEndpoint "api" $context | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} OS_REGION_NAME: {{ $userContext.region_name | b64enc }} OS_INTERFACE: {{ $userContext.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME: {{ $userContext.project_domain_name | b64enc }} OS_PROJECT_NAME: {{ $userContext.project_name | b64enc }} OS_USER_DOMAIN_NAME: {{ $userContext.user_domain_name | b64enc }} OS_USERNAME: {{ $userContext.username | b64enc }} OS_PASSWORD: {{ $userContext.password | b64enc }} OS_DEFAULT_DOMAIN: {{ $userContext.default_domain_id | default "default" | b64enc }} {{- if $userContext.cacert }} OS_CACERT: {{ $userContext.cacert | b64enc }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_keystone_user_create_env_vars.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns a set of container enviorment variables, for use with the keystone user management jobs. values: | secrets: identity: service_user: example-keystone-user usage: | {{ include "helm-toolkit.snippets.keystone_user_create_env_vars" ( dict "ksUserSecret" .Values.secrets.identity.service_user "useCA" true ) }} return: | - name: SERVICE_OS_REGION_NAME valueFrom: secretKeyRef: name: example-keystone-user key: OS_REGION_NAME - name: SERVICE_OS_PROJECT_DOMAIN_NAME valueFrom: secretKeyRef: name: example-keystone-user key: OS_PROJECT_DOMAIN_NAME - name: SERVICE_OS_PROJECT_NAME valueFrom: secretKeyRef: name: example-keystone-user key: OS_PROJECT_NAME - name: SERVICE_OS_USER_DOMAIN_NAME valueFrom: secretKeyRef: name: example-keystone-user key: OS_USER_DOMAIN_NAME - name: SERVICE_OS_USERNAME valueFrom: secretKeyRef: name: example-keystone-user key: OS_USERNAME - name: SERVICE_OS_PASSWORD valueFrom: secretKeyRef: name: example-keystone-user key: OS_PASSWORD */}} {{- define "helm-toolkit.snippets.keystone_user_create_env_vars" }} {{- $ksUserSecret := .ksUserSecret }} - name: SERVICE_OS_REGION_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_REGION_NAME - name: SERVICE_OS_PROJECT_DOMAIN_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PROJECT_DOMAIN_NAME - name: SERVICE_OS_PROJECT_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PROJECT_NAME - name: SERVICE_OS_USER_DOMAIN_NAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_USER_DOMAIN_NAME - name: SERVICE_OS_USERNAME valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_USERNAME - name: SERVICE_OS_PASSWORD valueFrom: secretKeyRef: name: {{ $ksUserSecret }} key: OS_PASSWORD {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_apparmor_configmap.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders a configmap used for loading custom AppArmor profiles. values: | pod: mandatory_access_control: type: apparmor configmap_apparmor: true apparmor_profiles: |- my_apparmor-v1.profile: |- #include profile my-apparmor-v1 flags=(attach_disconnected,mediate_deleted) { } usage: | {{ dict "envAll" . "component" "myComponent" | include "helm-toolkit.snippets.kubernetes_apparmor_configmap" }} return: | apiVersion: v1 kind: ConfigMap metadata: name: releaseName-myComponent-apparmor namespace: myNamespace data: my_apparmor-v1.profile: |- #include profile my-apparmor-v1 flags=(attach_disconnected,mediate_deleted) { } */}} {{- define "helm-toolkit.snippets.kubernetes_apparmor_configmap" -}} {{- $envAll := index . "envAll" -}} {{- $component := index . "component" -}} {{- if hasKey $envAll.Values.pod "mandatory_access_control" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control "type" -}} {{- if eq $envAll.Values.pod.mandatory_access_control.type "apparmor" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control "configmap_apparmor" -}} {{- if $envAll.Values.pod.mandatory_access_control.configmap_apparmor }} {{- $mapName := printf "%s-%s-%s" $envAll.Release.Name $component "apparmor" -}} {{- if $envAll.Values.conf.apparmor_profiles }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $mapName }} namespace: {{ $envAll.Release.Namespace }} data: {{ $envAll.Values.conf.apparmor_profiles | toYaml | indent 2 }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_apparmor_loader_init_container.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders the init container used for apparmor loading. values: | images: tags: apparmor_loader: my-repo.io/apparmor-loader:1.0.0 pod: mandatory_access_control: type: apparmor configmap_apparmor: true apparmor-loader: unconfined usage: | {{ dict "envAll" . | include "helm-toolkit.snippets.kubernetes_apparmor_loader_init_container" }} return: | - name: apparmor-loader image: my-repo.io/apparmor-loader:1.0.0 args: - /profiles securityContext: privileged: true volumeMounts: - name: sys mountPath: /sys readOnly: true - name: includes mountPath: /etc/apparmor.d readOnly: true - name: profiles mountPath: /profiles readOnly: true */}} {{- define "helm-toolkit.snippets.kubernetes_apparmor_loader_init_container" -}} {{- $envAll := index . "envAll" -}} {{- if hasKey $envAll.Values.pod "mandatory_access_control" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control "type" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control "configmap_apparmor" -}} {{- if eq $envAll.Values.pod.mandatory_access_control.type "apparmor" -}} {{- if $envAll.Values.pod.mandatory_access_control.configmap_apparmor }} - name: apparmor-loader image: {{ $envAll.Values.images.tags.apparmor_loader }} args: - /profiles securityContext: privileged: true volumeMounts: - name: sys mountPath: /sys readOnly: true - name: includes mountPath: /etc/apparmor.d readOnly: true - name: profiles mountPath: /profiles readOnly: true {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_apparmor_volumes.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders the volumes used by the apparmor loader. values: | pod: mandatory_access_control: type: apparmor configmap_apparmor: true inputs: | envAll: "Environment or Context." component: "Name of the component used for the name of configMap." requireSys: "Boolean. True if it needs the hostpath /sys in volumes." usage: | {{ dict "envAll" . "component" "keystone" "requireSys" true | include "helm-toolkit.snippets.kubernetes_apparmor_volumes" }} return: | - name: sys hostPath: path: /sys - name: includes hostPath: path: /etc/apparmor.d - name: profiles configMap: name: RELEASENAME-keystone-apparmor defaultMode: 0555 */}} {{- define "helm-toolkit.snippets.kubernetes_apparmor_volumes" -}} {{- $envAll := index . "envAll" -}} {{- $component := index . "component" -}} {{- $requireSys := index . "requireSys" | default false -}} {{- $configName := printf "%s-%s-%s" $envAll.Release.Name $component "apparmor" -}} {{- if hasKey $envAll.Values.pod "mandatory_access_control" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control "type" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control "configmap_apparmor" -}} {{- if eq $envAll.Values.pod.mandatory_access_control.type "apparmor" -}} {{- if $envAll.Values.pod.mandatory_access_control.configmap_apparmor }} {{- if $requireSys }} - name: sys hostPath: path: /sys {{- end }} - name: includes hostPath: path: /etc/apparmor.d - name: profiles configMap: name: {{ $configName | quote }} defaultMode: 0555 {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_container_security_context.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders securityContext for a Kubernetes container. For container level, see here: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#securitycontext-v1-core examples: - values: | pod: security_context: myApp: container: foo: runAsUser: 34356 readOnlyRootFilesystem: true usage: | {{ dict "envAll" . "application" "myApp" "container" "foo" | include "helm-toolkit.snippets.kubernetes_container_security_context" }} return: | securityContext: readOnlyRootFilesystem: true runAsUser: 34356 */}} {{- define "helm-toolkit.snippets.kubernetes_container_security_context" -}} {{- $envAll := index . "envAll" -}} {{- $application := index . "application" -}} {{- $container := index . "container" -}} {{- if hasKey $envAll.Values.pod "security_context" }} {{- if hasKey ( index $envAll.Values.pod.security_context ) $application }} {{- if hasKey ( index $envAll.Values.pod.security_context $application "container" ) $container }} securityContext: {{ toYaml ( index $envAll.Values.pod.security_context $application "container" $container ) | indent 2 }} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_entrypoint_init_container.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns a container definition for use with the kubernetes-entrypoint image. values: | images: tags: dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal pull_policy: IfNotPresent local_registry: active: true exclude: - dep_check dependencies: dynamic: common: local_image_registry: jobs: - calico-image-repo-sync services: - endpoint: node service: local_image_registry static: calico_node: services: - endpoint: internal service: etcd custom_resources: - apiVersion: argoproj.io/v1alpha1 kind: Workflow name: wf-example fields: - key: "status.phase" value: "Succeeded" endpoints: local_image_registry: namespace: docker-registry hosts: default: localhost node: localhost etcd: hosts: default: etcd # NOTE (portdirect): if the stanza, or a portion of it, under `pod` is not # specififed then the following will be used as defaults: # pod: # security_context: # kubernetes_entrypoint: # container: # kubernetes_entrypoint: # runAsUser: 65534 # readOnlyRootFilesystem: true # allowPrivilegeEscalation: false pod: security_context: kubernetes_entrypoint: container: kubernetes_entrypoint: runAsUser: 0 readOnlyRootFilesystem: false usage: | {{ tuple . "calico_node" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" }} return: | - name: init image: "quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal" imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: false runAsUser: 0 env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: INTERFACE_NAME value: eth0 - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/ - name: DEPENDENCY_SERVICE value: "default:etcd,docker-registry:localhost" - name: DEPENDENCY_JOBS value: "calico-image-repo-sync" - name: DEPENDENCY_DAEMONSET value: "" - name: DEPENDENCY_CONTAINER value: "" - name: DEPENDENCY_POD_JSON value: "" - name: DEPENDENCY_CUSTOM_RESOURCE value: "[{\"apiVersion\":\"argoproj.io/v1alpha1\",\"kind\":\"Workflow\",\"namespace\":\"default\",\"name\":\"wf-example\",\"fields\":[{\"key\":\"status.phase\",\"value\":\"Succeeded\"}]}]" command: - kubernetes-entrypoint volumeMounts: [] */}} {{- define "helm-toolkit.snippets.kubernetes_entrypoint_init_container._default_security_context" -}} Values: pod: security_context: kubernetes_entrypoint: container: kubernetes_entrypoint: runAsUser: 65534 readOnlyRootFilesystem: true allowPrivilegeEscalation: false {{- end -}} {{- define "helm-toolkit.snippets.kubernetes_entrypoint_init_container" -}} {{- $envAll := index . 0 -}} {{- $component := index . 1 -}} {{- $mounts := index . 2 -}} {{- $_ := set $envAll.Values "__kubernetes_entrypoint_init_container" dict -}} {{- $_ := set $envAll.Values.__kubernetes_entrypoint_init_container "deps" dict -}} {{- if and ($envAll.Values.images.local_registry.active) (ne $component "image_repo_sync") -}} {{- if eq $component "pod_dependency" -}} {{- $_ := include "helm-toolkit.utils.merge" ( tuple $envAll.Values.__kubernetes_entrypoint_init_container.deps ( index $envAll.Values.pod_dependency ) $envAll.Values.dependencies.dynamic.common.local_image_registry ) -}} {{- else -}} {{- $_ := include "helm-toolkit.utils.merge" ( tuple $envAll.Values.__kubernetes_entrypoint_init_container.deps ( index $envAll.Values.dependencies.static $component ) $envAll.Values.dependencies.dynamic.common.local_image_registry ) -}} {{- end -}} {{- else -}} {{- if eq $component "pod_dependency" -}} {{- $_ := set $envAll.Values.__kubernetes_entrypoint_init_container "deps" ( index $envAll.Values.pod_dependency ) -}} {{- else -}} {{- $_ := set $envAll.Values.__kubernetes_entrypoint_init_container "deps" ( index $envAll.Values.dependencies.static $component ) -}} {{- end -}} {{- end -}} {{- if and ($envAll.Values.manifests.job_rabbit_init) (hasKey $envAll.Values.dependencies "dynamic") -}} {{- if $envAll.Values.dependencies.dynamic.job_rabbit_init -}} {{- if eq $component "pod_dependency" -}} {{- $_ := include "helm-toolkit.utils.merge" ( tuple $envAll.Values.__kubernetes_entrypoint_init_container.deps ( index $envAll.Values.pod_dependency ) (index $envAll.Values.dependencies.dynamic.job_rabbit_init $component) ) -}} {{- else -}} {{- $_ := include "helm-toolkit.utils.merge" ( tuple $envAll.Values.__kubernetes_entrypoint_init_container.deps ( index $envAll.Values.dependencies.static $component ) (index $envAll.Values.dependencies.dynamic.job_rabbit_init $component)) -}} {{- end -}} {{- end -}} {{- end -}} {{- $_ := include "helm-toolkit.utils.dependency_jobs_filter" (dict "envAll" $envAll "deps" $envAll.Values.__kubernetes_entrypoint_init_container.deps) | toString | fromYaml -}} {{- $deps := $envAll.Values.__kubernetes_entrypoint_init_container.deps }} {{- range $deps.custom_resources }} {{- $_ := set . "namespace" $envAll.Release.Namespace -}} {{- end -}} {{- $default_security_context := include "helm-toolkit.snippets.kubernetes_entrypoint_init_container._default_security_context" . | fromYaml }} {{- $patchedEnvAll := mergeOverwrite $default_security_context $envAll }} - name: init {{ tuple $envAll "dep_check" | include "helm-toolkit.snippets.image" | indent 2 }} {{- dict "envAll" $patchedEnvAll "application" "kubernetes_entrypoint" "container" "kubernetes_entrypoint" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 2 }} env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - name: INTERFACE_NAME value: eth0 - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/ - name: DEPENDENCY_SERVICE value: "{{ tuple $deps.services $envAll | include "helm-toolkit.utils.comma_joined_service_list" }}" {{- if $deps.jobs -}} {{- if kindIs "string" (index $deps.jobs 0) }} - name: DEPENDENCY_JOBS value: "{{ include "helm-toolkit.utils.joinListWithComma" $deps.jobs }}" {{- else }} - name: DEPENDENCY_JOBS_JSON value: {{- toJson $deps.jobs | quote -}} {{- end -}} {{- end }} - name: DEPENDENCY_DAEMONSET value: "{{ include "helm-toolkit.utils.joinListWithComma" $deps.daemonset }}" - name: DEPENDENCY_CONTAINER value: "{{ include "helm-toolkit.utils.joinListWithComma" $deps.container }}" - name: DEPENDENCY_POD_JSON value: {{ if $deps.pod }}{{ toJson $deps.pod | quote }}{{ else }}""{{ end }} - name: DEPENDENCY_CUSTOM_RESOURCE value: {{ if $deps.custom_resources }}{{ toJson $deps.custom_resources | quote }}{{ else }}""{{ end }} command: - kubernetes-entrypoint volumeMounts: {{ toYaml $mounts | indent 4 }} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_kubectl_params.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.kubernetes_kubectl_params" -}} {{- $envAll := index . 0 -}} {{- $application := index . 1 -}} {{- $component := index . 2 -}} {{ print "-l application=" $application " -l component=" $component }} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_mandatory_access_control_annotation.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders mandatory access control annotations for a list of containers driven by values.yaml. As of now, it can only generate an apparmor annotation, but in the future could generate others. values: | pod: mandatory_access_control: type: apparmor myPodName: myContainerName: localhost/myAppArmor mySecondContainerName: localhost/secondProfile # optional myThirdContainerName: localhost/thirdProfile # optional usage: | {{ dict "envAll" . "podName" "myPodName" "containerNames" (list "myContainerName" "mySecondContainerName" "myThirdContainerName") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" }} return: | container.apparmor.security.beta.kubernetes.io/myContainerName: localhost/myAppArmor container.apparmor.security.beta.kubernetes.io/mySecondContainerName: localhost/secondProfile container.apparmor.security.beta.kubernetes.io/myThirdContainerName: localhost/thirdProfile note: | The number of container underneath is a variable arguments. It loops through all the container names specified. */}} {{- define "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" -}} {{- $envAll := index . "envAll" -}} {{- $podName := index . "podName" -}} {{- $containerNames := index . "containerNames" -}} {{- if hasKey $envAll.Values.pod "mandatory_access_control" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control "type" -}} {{- $macType := $envAll.Values.pod.mandatory_access_control.type -}} {{- if $macType -}} {{- if eq $macType "apparmor" -}} {{- if hasKey $envAll.Values.pod.mandatory_access_control $podName -}} {{- range $name := $containerNames -}} {{- $apparmorProfile := index $envAll.Values.pod.mandatory_access_control $podName $name -}} {{- if $apparmorProfile }} container.apparmor.security.beta.kubernetes.io/{{ $name }}: {{ $apparmorProfile }} {{- end -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_metadata_labels.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders a set of standardised labels values: | release_group: null pod: labels: default: label1.example.com: value bar: label2.example.com: bar usage: | {{ tuple . "foo" "bar" | include "helm-toolkit.snippets.kubernetes_metadata_labels" }} return: | release_group: RELEASE-NAME application: foo component: bar label1.example.com: value label2.example.com: bar */}} {{- define "helm-toolkit.snippets.kubernetes_metadata_labels" -}} {{- $envAll := index . 0 -}} {{- $application := index . 1 -}} {{- $component := index . 2 -}} {{- $podValues := $envAll.Values.pod | default dict -}} {{- $labels := $podValues.labels | default dict -}} release_group: {{ $envAll.Values.release_group | default $envAll.Release.Name }} application: {{ $application }} component: {{ $component }} {{- if or $labels.include_app_kubernetes_io (not (hasKey $labels "include_app_kubernetes_io")) }} app.kubernetes.io/name: {{ $application }} app.kubernetes.io/component: {{ $component }} app.kubernetes.io/instance: {{ $envAll.Values.release_group | default $envAll.Release.Name }} {{- end -}} {{- if $labels }} {{- if hasKey $labels $component }} {{ index $podValues "labels" $component | toYaml }} {{- end -}} {{- if hasKey $labels "default" }} {{ $labels.default | toYaml }} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_pod_anti_affinity.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders kubernetes anti affinity rules, this function supports both hard 'requiredDuringSchedulingIgnoredDuringExecution' and soft 'preferredDuringSchedulingIgnoredDuringExecution' types. values: | pod: affinity: anti: topologyKey: default: kubernetes.io/hostname type: default: requiredDuringSchedulingIgnoredDuringExecution weight: default: 10 usage: | {{ tuple . "appliction_x" "component_y" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" }} return: | podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: release_group operator: In values: - RELEASE-NAME - key: application operator: In values: - appliction_x - key: component operator: In values: - component_y topologyKey: kubernetes.io/hostname */}} {{- define "helm-toolkit.snippets.kubernetes_pod_anti_affinity._match_expressions" -}} {{- $envAll := index . "envAll" -}} {{- $application := index . "application" -}} {{- $component := index . "component" -}} {{- $expressionRelease := dict "key" "release_group" "operator" "In" "values" ( list ( $envAll.Values.release_group | default $envAll.Release.Name ) ) -}} {{- $expressionApplication := dict "key" "application" "operator" "In" "values" ( list $application ) -}} {{- $expressionComponent := dict "key" "component" "operator" "In" "values" ( list $component ) -}} {{- list $expressionRelease $expressionApplication $expressionComponent | toYaml }} {{- end -}} {{- define "helm-toolkit.snippets.kubernetes_pod_anti_affinity" -}} {{- $envAll := index . 0 -}} {{- $application := index . 1 -}} {{- $component := index . 2 -}} {{- $antiAffinityType := index $envAll.Values.pod.affinity.anti.type $component | default $envAll.Values.pod.affinity.anti.type.default }} {{- $antiAffinityKey := index $envAll.Values.pod.affinity.anti.topologyKey $component | default $envAll.Values.pod.affinity.anti.topologyKey.default }} podAntiAffinity: {{- $matchExpressions := include "helm-toolkit.snippets.kubernetes_pod_anti_affinity._match_expressions" ( dict "envAll" $envAll "application" $application "component" $component ) -}} {{- if eq $antiAffinityType "preferredDuringSchedulingIgnoredDuringExecution" }} {{ $antiAffinityType }}: - podAffinityTerm: labelSelector: matchExpressions: {{ $matchExpressions | indent 10 }} topologyKey: {{ $antiAffinityKey }} {{- if $envAll.Values.pod.affinity.anti.weight }} weight: {{ index $envAll.Values.pod.affinity.anti.weight $component | default $envAll.Values.pod.affinity.anti.weight.default }} {{- else }} weight: 10 {{- end -}} {{- else if eq $antiAffinityType "requiredDuringSchedulingIgnoredDuringExecution" }} {{ $antiAffinityType }}: - labelSelector: matchExpressions: {{ $matchExpressions | indent 8 }} topologyKey: {{ $antiAffinityKey }} {{- else }} {} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_pod_image_pull_secret.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders image pull secrets for a pod values: | pod: image_pull_secrets: default: - name: some-pull-secret bar: - name: another-pull-secret usage: | {{ tuple . "bar" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" }} return: | imagePullSecrets: - name: some-pull-secret - name: another-pull-secret */}} {{- define "helm-toolkit.snippets.kubernetes_image_pull_secrets" -}} {{- $envAll := index . 0 -}} {{- $application := index . 1 -}} {{- if ($envAll.Values.pod).image_pull_secrets }} imagePullSecrets: {{- if hasKey $envAll.Values.pod.image_pull_secrets $application }} {{ index $envAll.Values.pod "image_pull_secrets" $application | toYaml | indent 2 }} {{- end -}} {{- if hasKey $envAll.Values.pod.image_pull_secrets "default" }} {{ $envAll.Values.pod.image_pull_secrets.default | toYaml | indent 2 }} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_pod_priority_class.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Adds custom annotations to the secret spec of a component. examples: - values: | pod: priorityClassName: designate_api: "high-priority" usage: | {{ tuple "designate_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" }} return: | priorityClassName: "high-priority" - values: | pod: priorityClassName: {} usage: | {{ tuple "designate_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" }} return: | "" */}} {{- define "helm-toolkit.snippets.kubernetes_pod_priority_class" -}} {{- $component := index . 0 | replace "-" "_" -}} {{- $envAll := index . 1 -}} {{- $priorityClassName := dig "priorityClassName" $component false $envAll.Values.pod -}} {{- if $priorityClassName -}} {{- toYaml (dict "priorityClassName" $priorityClassName) -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_pod_rbac_roles.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.kubernetes_pod_rbac_roles" -}} {{- $envAll := index . 0 -}} {{- $deps := index . 1 -}} {{- $namespace := index . 2 -}} {{- $saName := index . 3 | replace "_" "-" }} {{- $saNamespace := index . 4 -}} {{- $releaseName := $envAll.Release.Name }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $releaseName }}-{{ $saNamespace }}-{{ $saName }} namespace: {{ $namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $releaseName }}-{{ $saNamespace }}-{{ $saName }} subjects: - kind: ServiceAccount name: {{ $saName }} namespace: {{ $saNamespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $releaseName }}-{{ $saNamespace }}-{{ $saName }} namespace: {{ $namespace }} rules: - apiGroups: - "" - extensions - batch - apps verbs: - get - list resources: {{- range $k, $v := $deps -}} {{ if eq $v "daemonsets" }} - daemonsets {{- end -}} {{ if eq $v "jobs" }} - jobs {{- end -}} {{ if or (eq $v "pods") (eq $v "daemonsets") (eq $v "jobs") }} - pods {{- end -}} {{ if eq $v "services" }} - services - endpoints {{- end -}} {{ if eq $v "secrets" }} - secrets {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_pod_rbac_serviceaccount.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" -}} {{- $envAll := index . 0 -}} {{- $component := index . 1 -}} {{- $saName := index . 2 -}} {{- $saNamespace := $envAll.Release.Namespace }} {{- $randomKey := randAlphaNum 32 }} {{- $allNamespace := dict $randomKey "" }} {{- $_ := set $envAll.Values "__kubernetes_entrypoint_init_container" dict -}} {{- $_ := set $envAll.Values.__kubernetes_entrypoint_init_container "deps" dict -}} {{- if and ($envAll.Values.images.local_registry.active) (ne $component "image_repo_sync") -}} {{- if eq $component "pod_dependency" -}} {{- $_ := include "helm-toolkit.utils.merge" ( tuple $envAll.Values.__kubernetes_entrypoint_init_container.deps ( index $envAll.Values.pod_dependency ) $envAll.Values.dependencies.dynamic.common.local_image_registry ) -}} {{- else -}} {{- $_ := include "helm-toolkit.utils.merge" ( tuple $envAll.Values.__kubernetes_entrypoint_init_container.deps ( index $envAll.Values.dependencies.static $component ) $envAll.Values.dependencies.dynamic.common.local_image_registry ) -}} {{- end -}} {{- else -}} {{- if eq $component "pod_dependency" -}} {{- $_ := set $envAll.Values.__kubernetes_entrypoint_init_container "deps" ( index $envAll.Values.pod_dependency ) -}} {{- else -}} {{- $_ := set $envAll.Values.__kubernetes_entrypoint_init_container "deps" ( index $envAll.Values.dependencies.static $component ) -}} {{- end -}} {{- end -}} {{- $_ := include "helm-toolkit.utils.dependency_jobs_filter" (dict "envAll" $envAll "deps" $envAll.Values.__kubernetes_entrypoint_init_container.deps) | toString | fromYaml -}} {{- $deps := $envAll.Values.__kubernetes_entrypoint_init_container.deps }} --- apiVersion: v1 kind: ServiceAccount metadata: name: {{ $saName }} namespace: {{ $saNamespace }} {{- if $envAll.Values.manifests.secret_registry }} {{- if $envAll.Values.endpoints.oci_image_registry.auth.enabled }} imagePullSecrets: - name: {{ index $envAll.Values.secrets.oci_image_registry $envAll.Chart.Name }} {{- end -}} {{- end -}} {{- range $k, $v := $deps -}} {{- if eq $k "services" }} {{- range $serv := $v }} {{- $endpointMap := index $envAll.Values.endpoints $serv.service }} {{- $endpointNS := $endpointMap.namespace | default $saNamespace }} {{- if not (contains "services" ((index $allNamespace $endpointNS) | default "")) }} {{- $_ := set $allNamespace $endpointNS (printf "%s%s" "services," ((index $allNamespace $endpointNS) | default "")) }} {{- end -}} {{- end -}} {{- else if and (eq $k "jobs") $v }} {{- $_ := set $allNamespace $saNamespace (printf "%s%s" "jobs," ((index $allNamespace $saNamespace) | default "")) }} {{- else if and (eq $k "daemonset") $v }} {{- $_ := set $allNamespace $saNamespace (printf "%s%s" "daemonsets," ((index $allNamespace $saNamespace) | default "")) }} {{- else if and (eq $k "pod") $v }} {{- $_ := set $allNamespace $saNamespace (printf "%s%s" "pods," ((index $allNamespace $saNamespace) | default "")) }} {{- else if and (eq $k "secret") $v }} {{- $_ := set $allNamespace $saNamespace (printf "%s%s" "secrets," ((index $allNamespace $saNamespace) | default "")) }} {{- end -}} {{- end -}} {{- $_ := unset $allNamespace $randomKey }} {{- range $ns, $vv := $allNamespace }} {{- $resourceList := (splitList "," (trimSuffix "," $vv)) }} {{- tuple $envAll $resourceList $ns $saName $saNamespace | include "helm-toolkit.snippets.kubernetes_pod_rbac_roles" }} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_pod_runtime_class.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Adds custom annotations to the secret spec of a component. examples: - values: | pod: runtimeClassName: designate_api: "runtime-class" usage: | {{ tuple "designate_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" }} return: | runtimeClassName: "runtime-class" - values: | pod: runtimeClassName: {} usage: | {{ tuple "designate_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" }} return: | "" */}} {{- define "helm-toolkit.snippets.kubernetes_pod_runtime_class" -}} {{- $component := index . 0 | replace "-" "_" -}} {{- $envAll := index . 1 -}} {{- $runtimeClassName := dig "runtimeClassName" $component false $envAll.Values.pod -}} {{- if $runtimeClassName -}} {{- toYaml (dict "runtimeClassName" $runtimeClassName) -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_pod_security_context.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders securityContext for a Kubernetes pod. For pod level, seurity context see here: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#podsecuritycontext-v1-core examples: - values: | pod: # NOTE: The 'user' key is deprecated, and will be removed shortly. user: myApp: uid: 34356 security_context: myApp: pod: runAsNonRoot: true usage: | {{ dict "envAll" . "application" "myApp" | include "helm-toolkit.snippets.kubernetes_pod_security_context" }} return: | securityContext: runAsUser: 34356 runAsNonRoot: true - values: | pod: security_context: myApp: pod: runAsUser: 34356 runAsNonRoot: true usage: | {{ dict "envAll" . "application" "myApp" | include "helm-toolkit.snippets.kubernetes_pod_security_context" }} return: | securityContext: runAsNonRoot: true runAsUser: 34356 */}} {{- define "helm-toolkit.snippets.kubernetes_pod_security_context" -}} {{- $envAll := index . "envAll" -}} {{- $application := index . "application" -}} securityContext: {{- if hasKey $envAll.Values.pod "user" }} {{- if hasKey $envAll.Values.pod.user $application }} {{- if hasKey ( index $envAll.Values.pod.user $application ) "uid" }} runAsUser: {{ index $envAll.Values.pod.user $application "uid" }} {{- end -}} {{- end -}} {{- end -}} {{- if hasKey $envAll.Values.pod "security_context" }} {{- if hasKey ( index $envAll.Values.pod.security_context ) $application }} {{ toYaml ( index $envAll.Values.pod.security_context $application "pod" ) | indent 2 }} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_probes.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders kubernetes liveness and readiness probes for containers values: | pod: probes: api: default: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 usage: | {{- define "probeTemplate" }} httpGet: path: /status port: 9090 {{- end }} {{ dict "envAll" . "component" "api" "container" "default" "type" "readiness" "probeTemplate" (include "probeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" }} return: | readinessProbe: httpGet: path: /status port: 9090 initialDelaySeconds: 30 timeoutSeconds: 30 */}} {{- define "helm-toolkit.snippets.kubernetes_probe" -}} {{- $envAll := index . "envAll" -}} {{- $component := index . "component" -}} {{- $container := index . "container" -}} {{- $type := index . "type" -}} {{- $probeTemplate := index . "probeTemplate" -}} {{- $probeOpts := index $envAll.Values.pod.probes $component $container $type -}} {{- if $probeOpts.enabled -}} {{- $probeOverides := index $probeOpts "params" | default dict -}} {{ dict ( printf "%sProbe" $type ) (mergeOverwrite $probeTemplate $probeOverides ) | toYaml }} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_resources.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* Note: This function is deprecated and will be removed in the future. abstract: | Renders kubernetes resource limits for pods values: | pod: resources: enabled: true api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" hugepages-1Gi: "1Gi" usage: | {{ include "helm-toolkit.snippets.kubernetes_resources" ( tuple . .Values.pod.resources.api ) }} return: | resources: limits: cpu: "2000m" memory: "1024Mi" hugepages-1Gi: "1Gi" requests: cpu: "100m" memory: "128Mi */}} {{- define "helm-toolkit.snippets.kubernetes_resources" -}} {{- $envAll := index . 0 -}} {{- $component := index . 1 -}} {{- if $envAll.Values.pod.resources.enabled -}} resources: {{ toYaml $component | trim | indent 2 }} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_seccomp_annotation.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders seccomp annotations for a list of containers driven by values.yaml. values: | pod: seccomp: myPodName: myContainerName: localhost/mySeccomp mySecondContainerName: localhost/secondProfile # optional myThirdContainerName: localhost/thirdProfile # optional usage: | {{ dict "envAll" . "podName" "myPodName" "containerNames" (list "myContainerName" "mySecondContainerName" "myThirdContainerName") | include "helm-toolkit.snippets.kubernetes_seccomp_annotation" }} return: | container.seccomp.security.alpha.kubernetes.io/myContainerName: localhost/mySeccomp container.seccomp.security.alpha.kubernetes.io/mySecondContainerName: localhost/secondProfile container.seccomp.security.alpha.kubernetes.io/myThirdContainerName: localhost/thirdProfile note: | The number of container underneath is a variable arguments. It loops through all the container names specified. */}} {{- define "helm-toolkit.snippets.kubernetes_seccomp_annotation" -}} {{- $envAll := index . "envAll" -}} {{- $podName := index . "podName" -}} {{- $containerNames := index . "containerNames" -}} {{- if hasKey (index $envAll.Values.pod "seccomp") $podName -}} {{- range $name := $containerNames -}} {{- $seccompProfile := index $envAll.Values.pod.seccomp $podName $name -}} {{- if $seccompProfile }} container.seccomp.security.alpha.kubernetes.io/{{ $name }}: {{ $seccompProfile }} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_tolerations.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders kubernetes tolerations for pods values: | pod: tolerations: api: enabled: true tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/node operator: Exists usage: | {{ include "helm-toolkit.snippets.kubernetes_tolerations" ( tuple . .Values.pod.tolerations.api ) }} return: | tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/node operator: Exists */}} {{- define "helm-toolkit.snippets.kubernetes_tolerations" -}} {{- $envAll := index . 0 -}} {{- $component := index . 1 -}} {{- $pod := index $envAll.Values.pod.tolerations $component }} tolerations: {{ toYaml $pod.tolerations }} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_upgrades_daemonset.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.kubernetes_upgrades_daemonset" -}} {{- $envAll := index . 0 -}} {{- $component := index . 1 -}} {{- $upgradeMap := index $envAll.Values.pod.lifecycle.upgrades.daemonsets $component -}} {{- $pod_replacement_strategy := $envAll.Values.pod.lifecycle.upgrades.daemonsets.pod_replacement_strategy -}} {{- with $upgradeMap -}} {{- if .enabled }} minReadySeconds: {{ .min_ready_seconds }} updateStrategy: type: {{ $pod_replacement_strategy }} {{- if $pod_replacement_strategy }} {{- if eq $pod_replacement_strategy "RollingUpdate" }} rollingUpdate: maxUnavailable: {{ .max_unavailable }} {{- end }} {{- end }} {{- end }} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_upgrades_deployment.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.kubernetes_upgrades_deployment" -}} {{- $envAll := index . 0 -}} {{- with $envAll.Values.pod.lifecycle.upgrades.deployments -}} revisionHistoryLimit: {{ .revision_history }} strategy: type: {{ .pod_replacement_strategy }} {{- if eq .pod_replacement_strategy "RollingUpdate" }} rollingUpdate: maxUnavailable: {{ .rolling_update.max_unavailable }} maxSurge: {{ .rolling_update.max_surge }} {{- end }} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_kubernetes_upgrades_statefulset.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders upgradeStrategy configuration for Kubernetes statefulsets. See: https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets Types: - RollingUpdate (default) - OnDelete Partitions: - Stage updates to a statefulset by keeping pods at current version while allowing mutations to statefulset's .spec.template values: | pod: lifecycle: upgrades: statefulsets: pod_replacement_strategy: RollingUpdate partition: 2 usage: | {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_statefulset" | indent 2 }} return: | updateStrategy: type: RollingUpdate rollingUpdate: partition: 2 */}} {{- define "helm-toolkit.snippets.kubernetes_upgrades_statefulset" -}} {{- $envAll := index . 0 -}} {{- with $envAll.Values.pod.lifecycle.upgrades.statefulsets -}} updateStrategy: type: {{ .pod_replacement_strategy }} {{ if .partition -}} rollingUpdate: partition: {{ .partition }} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_mon_host_from_k8s_ep.sh.tpl ================================================ {{- define "helm-toolkit.snippets.mon_host_from_k8s_ep" -}} {{/* Inserts a bash function definition mon_host_from_k8s_ep() which can be used to construct a mon_hosts value from the given namespaced endpoint. Usage (e.g. in _script.sh.tpl): #!/bin/bash : "${NS:=ceph}" : "${EP:=ceph-mon-discovery}" {{ include "helm-toolkit.snippets.mon_host_from_k8s_ep" . }} MON_HOST=$(mon_host_from_k8s_ep "$NS" "$EP") if [ -z "$MON_HOST" ]; then # deal with failure else sed -i -e "s/^mon_host = /mon_host = $MON_HOST/" /etc/ceph/ceph.conf fi */}} {{` # Construct a mon_hosts value from the given namespaced endpoint # IP x.x.x.x with port p named "mon-msgr2" will appear as [v2:x.x.x.x/p/0] # IP x.x.x.x with port q named "mon" will appear as [v1:x.x.x.x/q/0] # IP x.x.x.x with ports p and q will appear as [v2:x.x.x.x/p/0,v1:x.x.x.x/q/0] # The entries for all IPs will be joined with commas mon_host_from_k8s_ep() { local ns=$1 local ep=$2 if [ -z "$ns" ] || [ -z "$ep" ]; then return 1 fi # We don't want shell expansion for the go-template expression # shellcheck disable=SC2016 kubectl get endpoints -n "$ns" "$ep" -o go-template=' {{- $sep := "" }} {{- range $_,$s := .subsets }} {{- $v2port := 0 }} {{- $v1port := 0 }} {{- range $_,$port := index $s "ports" }} {{- if (eq $port.name "mon-msgr2") }} {{- $v2port = $port.port }} {{- else if (eq $port.name "mon") }} {{- $v1port = $port.port }} {{- end }} {{- end }} {{- range $_,$address := index $s "addresses" }} {{- $v2endpoint := printf "v2:%s:%d/0" $address.ip $v2port }} {{- $v1endpoint := printf "v1:%s:%d/0" $address.ip $v1port }} {{- if (and $v2port $v1port) }} {{- printf "%s[%s,%s]" $sep $v2endpoint $v1endpoint }} {{- $sep = "," }} {{- else if $v2port }} {{- printf "%s[%s]" $sep $v2endpoint }} {{- $sep = "," }} {{- else if $v1port }} {{- printf "%s[%s]" $sep $v1endpoint }} {{- $sep = "," }} {{- end }} {{- end }} {{- end }}' } `}} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_prometheus_pod_annotations.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # Appends annotations for configuring prometheus scrape jobs via pod # annotations. The required annotations are: # * `prometheus.io/scrape`: Only scrape pods that have a value of `true` # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the # pod's declared ports (default is a port-free target if none are declared). {{- define "helm-toolkit.snippets.prometheus_pod_annotations" -}} {{- $config := index . 0 -}} {{- if $config.scrape }} prometheus.io/scrape: {{ $config.scrape | quote }} {{- end }} {{- if $config.path }} prometheus.io/path: {{ $config.path | quote }} {{- end }} {{- if $config.port }} prometheus.io/port: {{ $config.port | quote }} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_prometheus_service_annotations.tpl ================================================ {{/* you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # Appends annotations for configuring prometheus scrape endpoints via # annotations. The required annotations are: # * `prometheus.io/scrape`: Only scrape services that have a value of `true` # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need # to set this to `https` & most likely set the `tls_config` of the scrape config. # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. # * `prometheus.io/port`: If the metrics are exposed on a different port to the # service then set this appropriately. {{- define "helm-toolkit.snippets.prometheus_service_annotations" -}} {{- $config := index . 0 -}} {{- if $config.scrape }} prometheus.io/scrape: {{ $config.scrape | quote }} {{- end }} {{- if $config.scheme }} prometheus.io/scheme: {{ $config.scheme | quote }} {{- end }} {{- if $config.path }} prometheus.io/path: {{ $config.path | quote }} {{- end }} {{- if $config.port }} prometheus.io/port: {{ $config.port | quote }} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_release_uuid.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Reneders an attonation key and value for a release values: | release_uuid: null usage: | {{ tuple . | include "helm-toolkit.snippets.release_uuid" }} return: | "openstackhelm.openstack.org/release_uuid": "" */}} {{- define "helm-toolkit.snippets.release_uuid" -}} {{- $envAll := index . 0 -}} "openstackhelm.openstack.org/release_uuid": {{ $envAll.Values.release_uuid | default "" | quote }} {{- end -}} ================================================ FILE: helm-toolkit/templates/snippets/_rgw_s3_admin_env_vars.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.rgw_s3_admin_env_vars" }} {{- $s3AdminSecret := .s3AdminSecret }} - name: S3_ADMIN_USERNAME valueFrom: secretKeyRef: name: {{ $s3AdminSecret }} key: S3_ADMIN_USERNAME - name: S3_ADMIN_ACCESS_KEY valueFrom: secretKeyRef: name: {{ $s3AdminSecret }} key: S3_ADMIN_ACCESS_KEY - name: S3_ADMIN_SECRET_KEY valueFrom: secretKeyRef: name: {{ $s3AdminSecret }} key: S3_ADMIN_SECRET_KEY {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_rgw_s3_bucket_user_env_vars_rook.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.rgw_s3_bucket_user_env_vars_rook" }} {{- range $s3Bucket := .Values.storage.s3.buckets }} - name: {{ printf "%s_S3_ACCESS_KEY" ($s3Bucket.client | replace "-" "_" | upper) }} valueFrom: secretKeyRef: name: {{ $s3Bucket.name }} key: AWS_ACCESS_KEY_ID - name: {{ printf "%s_S3_SECRET_KEY" ($s3Bucket.client | replace "-" "_" | upper) }} valueFrom: secretKeyRef: name: {{ $s3Bucket.name }} key: AWS_SECRET_ACCESS_KEY {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_rgw_s3_secret_creds.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.rgw_s3_secret_creds" }} {{- range $client, $config := .Values.storage.s3.clients -}} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-s3-user-secret" ( $client | replace "_" "-" | lower ) }} type: Opaque data: {{- range $key, $value := $config.auth }} {{ $key | upper }}: {{ $value | toString | b64enc}} {{- end }} {{ end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_rgw_s3_user_env_vars.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.snippets.rgw_s3_user_env_vars" }} {{- range $client, $user := .Values.storage.s3.clients }} {{- $s3secret := printf "%s-s3-user-secret" ( $client | replace "_" "-" | lower ) }} - name: {{ printf "%s_S3_USERNAME" ($client | replace "-" "_" | upper) }} valueFrom: secretKeyRef: name: {{ $s3secret }} key: USERNAME - name: {{ printf "%s_S3_ACCESS_KEY" ($client | replace "-" "_" | upper) }} valueFrom: secretKeyRef: name: {{ $s3secret }} key: ACCESS_KEY - name: {{ printf "%s_S3_SECRET_KEY" ($client | replace "-" "_" | upper) }} valueFrom: secretKeyRef: name: {{ $s3secret }} key: SECRET_KEY {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_service_params.tpl ================================================ {{/* Copyright 2017 The Openstack-Helm Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Inserts kubernetes service parameters from values as is. values: | network: serviceExample: service: type: loadBalancer loadBalancerIP: 1.1.1.1 usage: | --- apiVersion: v1 kind: Service metadata: name: 'serviceExample' spec: ports: - name: s-example port: 1111 {{ .Values.network.serviceExample | include "helm-toolkit.snippets.service_params" | indent 2 }} return: | type: loadBalancer loadBalancerIP: 1.1.1.1 */}} {{- define "helm-toolkit.snippets.service_params" }} {{- $serviceParams := dict }} {{- if hasKey . "service" }} {{- $serviceParams = .service }} {{- end }} {{- if hasKey . "node_port" }} {{- if hasKey .node_port "enabled" }} {{- if .node_port.enabled }} {{- $_ := set $serviceParams "type" "NodePort" }} {{- end }} {{- end }} {{- end }} {{- if hasKey . "external_policy_local" }} {{- if .external_policy_local }} {{- $_ := set $serviceParams "externalTrafficPolicy" "Local" }} {{- end }} {{- end }} {{- if $serviceParams }} {{- $serviceParams | toYaml }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_tls_volume.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders a secret volume for tls. Dictionary Parameters: enabled: boolean check if you want to conditional disable this snippet (optional) name: name of the volume (required) secretName: name of a kuberentes/tls secret, if not specified, use the volume name (optional) values: | manifests: certificates: true usage: | {{- $opts := dict "enabled" "true" "name" "glance-tls-api" -}} {{- $opts | include "helm-toolkit.snippets.tls_volume" -}} return: | - name: glance-tls-api secret: secretName: glance-tls-api defaultMode: 292 */}} {{- define "helm-toolkit.snippets.tls_volume" }} {{- $enabled := index . "enabled" -}} {{- $name := index . "name" -}} {{- $secretName := index . "secretName" | default $name -}} {{- if and $enabled (ne $name "") }} - name: {{ $name }} secret: secretName: {{ $secretName }} defaultMode: 292 {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_tls_volume_mount.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders a volume mount for TLS key, cert and CA. Dictionary Parameters: enabled: boolean check if you want to conditional disable this snippet (optional) name: name that of the volume and should match the volume name (required) path: path to place tls.crt tls.key ca.crt, do not suffix with '/' (required) certs: a tuple containing a nonempty subset of {tls.crt, tls.key, ca.crt}. the default is the full set. (optional) values: | manifests: certificates: true usage: | {{- $opts := dict "enabled" .Values.manifests.certificates "name" "glance-tls-api" "path" "/etc/glance/certs" -}} {{- $opts | include "helm-toolkit.snippets.tls_volume_mount" -}} return: | - name: glance-tls-api mountPath: /etc/glance/certs/tls.crt subPath: tls.crt readOnly: true - name: glance-tls-api mountPath: /etc/glance/certs/tls.key subPath: tls.key readOnly: true - name: glance-tls-api mountPath: /etc/glance/certs/ca.crt subPath: ca.crt readOnly: true abstract: | This mounts a specific issuing CA only for service validation usage: | {{- $opts := dict "enabled" .Values.manifests.certificates "name" "glance-tls-api" "ca" true -}} {{- $opts | include "helm-toolkit.snippets.tls_volume_mount" -}} return: | - name: glance-tls-api mountPath: /etc/ssl/certs/openstack-helm.crt subPath: ca.crt readOnly: true */}} {{- define "helm-toolkit.snippets.tls_volume_mount" }} {{- $enabled := index . "enabled" -}} {{- $name := index . "name" -}} {{- $path := index . "path" | default "" -}} {{- $certs := index . "certs" | default ( tuple "tls.crt" "tls.key" "ca.crt" ) }} {{- if $enabled }} {{- if and (eq $path "") (ne $name "") }} - name: {{ $name }} mountPath: "/etc/ssl/certs/openstack-helm.crt" subPath: ca.crt readOnly: true {{- else }} {{- if ne $name "" }} {{- range $key, $value := $certs }} - name: {{ $name }} mountPath: {{ printf "%s/%s" $path $value }} subPath: {{ $value }} readOnly: true {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/snippets/_values_template_renderer.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Renders out configuration sections into a format suitable for incorporation into a config-map. Allowing various forms of input to be rendered out as appropriate. values: | conf: inputs: - foo - bar some: config_to_render: | #We can use all of gotpl here: eg macros, ranges etc. {{ include "helm-toolkit.utils.joinListWithComma" .Values.conf.inputs }} config_to_complete: #here we can fill out params, but things need to be valid yaml as input '{{ .Release.Name }}': '{{ printf "%s-%s" .Release.Namespace "namespace" }}' static_config: #this is just passed though as yaml to the configmap foo: bar usage: | {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: application-etc data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.some.config_to_render "key" "config_to_render.conf") | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.some.config_to_complete "key" "config_to_complete.yaml") | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.some.static_config "key" "static_config.yaml") | indent 2 }} return: | --- apiVersion: v1 kind: ConfigMap metadata: name: application-etc data: config_to_render.conf: | #We can use all of gotpl here: eg macros, ranges etc. foo,bar config_to_complete.yaml: | 'RELEASE-NAME': 'default-namespace' static_config.yaml: | foo: bar */}} {{- define "helm-toolkit.snippets.values_template_renderer" -}} {{- $envAll := index . "envAll" -}} {{- $template := index . "template" -}} {{- $key := index . "key" -}} {{- $format := index . "format" | default "configMap" -}} {{- with $envAll -}} {{- $templateRendered := tpl ( $template | toYaml ) . }} {{- if eq $format "Secret" }} {{- if hasPrefix "|\n" $templateRendered }} {{ $key }}: {{ regexReplaceAllLiteral "\n " ( $templateRendered | trimPrefix "|\n" | trimPrefix " " ) "\n" | b64enc }} {{- else }} {{ $key }}: {{ $templateRendered | b64enc }} {{- end -}} {{- else }} {{- if hasPrefix "|\n" $templateRendered }} {{ $key }}: | {{ regexReplaceAllLiteral "\n " ( $templateRendered | trimPrefix "|\n" | trimPrefix " " ) "\n" | indent 2 }} {{- else }} {{ $key }}: | {{ $templateRendered | indent 2 }} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/tls/_tls_generate_certs.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Produces a certificate from a certificate authority. If the "encode" parameter is true, base64 encode the values for inclusion in a Kubernetes secret. values: | test: hosts: names: - barbican.openstackhelm.example - barbican.openstack.svc.cluster.local ips: - 127.0.0.1 - 192.168.0.1 life: 3 # Use ca.crt and ca.key to build a customized ca, if they are provided. # Use hosts.names[0] and life to auto-generate a ca, if ca is not provided. ca: crt: | key: | usage: | {{ include "helm-toolkit.utils.tls_generate_certs" (dict "params" .Values.test) }} return: | ca: | crt: | exp: 2018-09-01T10:56:07.895392915-00:00 key: | */}} {{- define "helm-toolkit.utils.tls_generate_certs" -}} {{- $params := index . "params" -}} {{- $encode := index . "encode" | default false -}} {{- $local := dict -}} {{- $_hosts := $params.hosts.names | default list }} {{- if kindIs "string" $params.hosts.names }} {{- $_ := set $local "certHosts" (list $params.hosts.names) }} {{- else }} {{- $_ := set $local "certHosts" $_hosts }} {{- end }} {{- $_ips := $params.hosts.ips | default list }} {{- if kindIs "string" $params.hosts.ips }} {{- $_ := set $local "certIps" (list $params.hosts.ips) }} {{- else }} {{- $_ := set $local "certIps" $_ips }} {{- end }} {{- if hasKey $params "ca" }} {{- if and (hasKey $params.ca "crt") (hasKey $params.ca "key") }} {{- $ca := buildCustomCert ($params.ca.crt | b64enc ) ($params.ca.key | b64enc ) }} {{- $_ := set $local "ca" $ca }} {{- end }} {{- else }} {{- $ca := genCA (first $local.certHosts) (int $params.life) }} {{- $_ := set $local "ca" $ca }} {{- end }} {{- $expDate := date_in_zone "2006-01-02T15:04:05Z07:00" ( date_modify (printf "+%sh" (mul $params.life 24 |toString)) now ) "UTC" }} {{- $rawCert := genSignedCert (first $local.certHosts) ($local.certIps) ($local.certHosts) (int $params.life) $local.ca }} {{- $certificate := dict -}} {{- if $encode -}} {{- $_ := b64enc $rawCert.Cert | set $certificate "crt" -}} {{- $_ := b64enc $rawCert.Key | set $certificate "key" -}} {{- $_ := b64enc $local.ca.Cert | set $certificate "ca" -}} {{- $_ := b64enc $local.ca.Key | set $certificate "caKey" -}} {{- $_ := b64enc $expDate | set $certificate "exp" -}} {{- else -}} {{- $_ := set $certificate "crt" $rawCert.Cert -}} {{- $_ := set $certificate "key" $rawCert.Key -}} {{- $_ := set $certificate "ca" $local.ca.Cert -}} {{- $_ := set $certificate "caKey" $local.ca.Key -}} {{- $_ := set $certificate "exp" $expDate -}} {{- end -}} {{- $certificate | toYaml }} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_comma_joined_service_list.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns a comma separated list of namespace:service pairs. values: | dependencies: static: api: services: - endpoint: internal service: oslo_cache - endpoint: internal service: oslo_db endpoints: oslo_db: namespace: foo hosts: default: mariadb oslo_cache: namespace: bar hosts: default: memcache usage: | {{ tuple .Values.dependencies.static.api.services . | include "helm-toolkit.utils.comma_joined_service_list" }} return: | bar:memcache,foo:mariadb */}} {{- define "helm-toolkit.utils.comma_joined_service_list" -}} {{- $deps := index . 0 -}} {{- $envAll := index . 1 -}} {{- range $k, $v := $deps -}}{{- if $k -}},{{- end -}}{{ tuple $v.service $v.endpoint $envAll | include "helm-toolkit.endpoints.service_name_endpoint_with_namespace_lookup" }}{{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_configmap_templater.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.utils.configmap_templater" }} {{- $keyRoot := index . 0 -}} {{- $configTemplate := index . 1 -}} {{- $context := index . 2 -}} {{ if $keyRoot.override -}} {{ $keyRoot.override | indent 4 }} {{- else -}} {{- if $keyRoot.prefix -}} {{ $keyRoot.prefix | indent 4 }} {{- end }} {{ tuple $configTemplate $context | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- if $keyRoot.append -}} {{ $keyRoot.append | indent 4 }} {{- end }} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_daemonset_overrides.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.utils.daemonset_overrides" }} {{- $daemonset := index . 0 }} {{- $daemonset_yaml := index . 1 }} {{- $configmap_include := index . 2 }} {{- $configmap_name := index . 3 }} {{- $context := index . 4 }} {{- $_ := unset $context ".Files" }} {{- $daemonset_root_name := printf (print $context.Chart.Name "_" $daemonset) }} {{- $_ := set $context.Values "__daemonset_list" list }} {{- $_ := set $context.Values "__default" dict }} {{- if hasKey $context.Values.conf "overrides" }} {{- range $key, $val := $context.Values.conf.overrides }} {{- if eq $key $daemonset_root_name }} {{- range $type, $type_data := . }} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{/* dictionary that will contain all info needed to generate this iteration of the daemonset */}} {{- $current_dict := dict }} {{/* set daemonset name */}} {{/* Note: long hostnames can cause the 63 char name limit to be exceeded. Truncate the hostname if hostname > 20 char */}} {{- if gt (len $host_data.name) 20 }} {{- $_ := set $current_dict "name" (substr 0 20 $host_data.name) }} {{- else }} {{- $_ := set $current_dict "name" $host_data.name }} {{- end }} {{/* apply overrides */}} {{- $override_conf_copy := $host_data.conf }} {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}} {{- $root_conf_copy := omit ($context.Values.conf | toYaml | fromYaml) "overrides" }} {{- $merged_dict := mergeOverwrite $root_conf_copy $override_conf_copy }} {{- $root_conf_copy2 := dict "conf" $merged_dict }} {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "conf") "__daemonset_list" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $current_dict "nodeData" $root_conf_copy4 }} {{/* Schedule to this host explicitly. */}} {{- $nodeSelector_dict := dict }} {{- $_ := set $nodeSelector_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $nodeSelector_dict "operator" "In" }} {{- $values_list := list $host_data.name }} {{- $_ := set $nodeSelector_dict "values" $values_list }} {{- $list_aggregate := list $nodeSelector_dict }} {{- $_ := set $current_dict "matchExpressions" $list_aggregate }} {{/* store completed daemonset entry/info into global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $current_dict }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- end }} {{- end }} {{- if eq $type "labels" }} {{- $_ := set $context.Values "__label_list" . }} {{- range $label_data := . }} {{/* dictionary that will contain all info needed to generate this iteration of the daemonset. */}} {{- $_ := set $context.Values "__current_label" dict }} {{/* set daemonset name */}} {{- $_ := set $context.Values.__current_label "name" $label_data.label.key }} {{/* apply overrides */}} {{- $override_conf_copy := $label_data.conf }} {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}} {{- $root_conf_copy := omit ($context.Values.conf | toYaml | fromYaml) "overrides" }} {{- $merged_dict := mergeOverwrite $root_conf_copy $override_conf_copy }} {{- $root_conf_copy2 := dict "conf" $merged_dict }} {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "conf") "__daemonset_list" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__current_label "nodeData" $root_conf_copy4 }} {{/* Schedule to the provided label value(s) */}} {{- $label_dict := omit $label_data.label "NULL" }} {{- $_ := set $label_dict "operator" "In" }} {{- $list_aggregate := list $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{/* Do not schedule to other specified labels, with higher precedence as the list position increases. Last defined label is highest priority. */}} {{- $other_labels := without $context.Values.__label_list $label_data }} {{- range $label_data2 := $other_labels }} {{- $label_dict := omit $label_data2.label "NULL" }} {{- $_ := set $label_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{- end }} {{- $_ := set $context.Values "__label_list" $other_labels }} {{/* Do not schedule to any other specified hosts */}} {{- range $type, $type_data := $val }} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{- $label_dict := dict }} {{- $_ := set $label_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $label_dict "operator" "NotIn" }} {{- $values_list := list $host_data.name }} {{- $_ := set $label_dict "values" $values_list }} {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{- end }} {{/* store completed daemonset entry/info into global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__current_label }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- $_ := unset $context.Values "__current_label" }} {{- end }} {{- end }} {{- end }} {{/* scheduler exceptions for the default daemonset */}} {{- $_ := set $context.Values.__default "matchExpressions" list }} {{- range $type, $type_data := . }} {{/* Do not schedule to other specified labels */}} {{- if eq $type "labels" }} {{- range $label_data := . }} {{- $default_dict := omit $label_data.label "NULL" }} {{- $_ := set $default_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }} {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{/* Do not schedule to other specified hosts */}} {{- if eq $type "hosts" }} {{- range $host_data := . }} {{- $default_dict := dict }} {{- $_ := set $default_dict "key" "kubernetes.io/hostname" }} {{- $_ := set $default_dict "operator" "NotIn" }} {{- $values_list := list $host_data.name }} {{- $_ := set $default_dict "values" $values_list }} {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }} {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{/* generate the default daemonset */}} {{/* set name */}} {{- $_ := set $context.Values.__default "name" "default" }} {{/* no overrides apply, so copy as-is */}} {{- $root_conf_copy1 := omit $context.Values.conf "overrides" }} {{- $root_conf_copy2 := dict "conf" $root_conf_copy1 }} {{- $context_values := omit $context.Values "conf" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__default "nodeData" $root_conf_copy4 }} {{/* add to global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__default }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- range $current_dict := $context.Values.__daemonset_list }} {{- $context_novalues := omit $context "Values" }} {{- $merged_dict := mergeOverwrite $context_novalues $current_dict.nodeData }} {{- $_ := set $current_dict "nodeData" $merged_dict }} {{/* Deep copy original daemonset_yaml */}} {{- $_ := set $context.Values "__daemonset_yaml" ($daemonset_yaml | toYaml | fromYaml) }} {{/* name needs to be a DNS-1123 compliant name. Ensure lower case */}} {{- $name_format1 := printf (print $daemonset_root_name "-" $current_dict.name) | lower }} {{/* labels may contain underscores which would be invalid here, so we replace them with dashes there may be other valid label names which would make for an invalid DNS-1123 name but these will be easier to handle in future with sprig regex* functions (not availabile in helm 2.5.1) */}} {{- $name_format2 := $name_format1 | replace "_" "-" }} {{/* To account for the case where the same label is defined multiple times in overrides (but with different label values), we add a sha of the scheduling data to ensure name uniqueness */}} {{- $_ := set $current_dict "dns_1123_name" dict }} {{- if hasKey $current_dict "matchExpressions" }} {{- $_ := set $current_dict "dns_1123_name" (printf (print $name_format2 "-" ($current_dict.matchExpressions | quote | sha256sum | trunc 8))) }} {{- else }} {{- $_ := set $current_dict "dns_1123_name" $name_format2 }} {{- end }} {{/* set daemonset metadata name */}} {{- if not $context.Values.__daemonset_yaml.metadata }}{{- $_ := set $context.Values.__daemonset_yaml "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.metadata.name }}{{- $_ := set $context.Values.__daemonset_yaml.metadata "name" dict }}{{- end }} {{- $_ := set $context.Values.__daemonset_yaml.metadata "name" $current_dict.dns_1123_name }} {{/* cross-reference configmap name to container volume definitions */}} {{- $_ := set $context.Values "__volume_list" list }} {{- range $current_volume := $context.Values.__daemonset_yaml.spec.template.spec.volumes }} {{- $_ := set $context.Values "__volume" $current_volume }} {{- if hasKey $context.Values.__volume "secret" }} {{- if eq $context.Values.__volume.secret.secretName $configmap_name }} {{- $_ := set $context.Values.__volume.secret "secretName" $current_dict.dns_1123_name }} {{- end }} {{- end }} {{- $updated_list := append $context.Values.__volume_list $context.Values.__volume }} {{- $_ := set $context.Values "__volume_list" $updated_list }} {{- end }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "volumes" $context.Values.__volume_list }} {{/* populate scheduling restrictions */}} {{- if hasKey $current_dict "matchExpressions" }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "affinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity "nodeAffinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity "requiredDuringSchedulingIgnoredDuringExecution" dict }}{{- end }} {{- $match_exprs := dict }} {{- $_ := set $match_exprs "matchExpressions" $current_dict.matchExpressions }} {{- $appended_match_expr := list $match_exprs }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution "nodeSelectorTerms" $appended_match_expr }} {{- end }} {{/* input value hash for current set of values overrides */}} {{- if not $context.Values.__daemonset_yaml.spec }}{{- $_ := set $context.Values.__daemonset_yaml "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template }}{{- $_ := set $context.Values.__daemonset_yaml.spec "template" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata.annotations }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata "annotations" dict }}{{- end }} {{- $cmap := list $current_dict.dns_1123_name $current_dict.nodeData | include $configmap_include }} {{- $values_hash := $cmap | quote | sha256sum }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata.annotations "configmap-etc-hash" $values_hash }} {{/* generate configmap */}} --- {{ $cmap }} {{/* generate daemonset yaml */}} --- {{ $context.Values.__daemonset_yaml | toYaml }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/utils/_daemonset_overrides_root.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* The helm-toolkit.utils.daemonset_overrides function have some limitations: * it allows to override only conf values specifid in configmap-etc * it doesn't allow to override values for daemonsets passed via env variables or via damoenset definition. As result it is impossible to have mixed deployment when one compute is configured with dpdk while other not. * it is impossible to override interface names/other information stored in -bin configmap * It allows to schedule on both hosts and labels, which adds some uncertainty This implementation is intended to handle those limitations: * it allows to schedule only based on labels * it creates -bin per daemonset override * it allows to override values when rendering daemonsets It picks data from the following structure: .Values: overrides: mychart_mydaemonset: labels: label::value: values: override_root_option: override_root_value conf: ovs_dpdk: enabled: true neutron: DEFAULT: foo: bar */}} {{- define "helm-toolkit.utils.daemonset_overrides_root" }} {{- $daemonset := index . 0 }} {{- $daemonSetTemplateName := index . 1 }} {{ $serviceAccountName := index . 2 }} {{- $configmap_include := index . 3 }} {{- $configmap_name := index . 4 }} {{- $configbin_include := index . 5 }} {{- $configbin_name := index . 6 }} {{- $context := index . 7 }} {{- $_ := unset $context ".Files" }} {{- $daemonset_root_name := printf (print $context.Chart.Name "_" $daemonset) }} {{- $_ := set $context.Values "__daemonset_list" list }} {{- $_ := set $context.Values "__default" dict }} {{- $default_enabled := true }} {{- if hasKey $context.Values "overrides" }} {{- range $key, $val := $context.Values.overrides }} {{- if eq $key $daemonset_root_name }} {{- range $type, $type_data := . }} {{- if eq $type "overrides_default" }} {{- $default_enabled = $type_data }} {{- end }} {{- if eq $type "labels" }} {{- $_ := set $context.Values "__label_dict" . }} {{- range $lname, $ldata := . }} {{ $label_name := (split "::" $lname)._0 }} {{ $label_value := (split "::" $lname)._1 }} {{/* dictionary that will contain all info needed to generate this iteration of the daemonset. */}} {{- $_ := set $context.Values "__current_label" dict }} {{/* set daemonset name */}} {{- $_ := set $context.Values.__current_label "name" $label_name }} {{/* set daemonset metadata annotation */}} {{- $_ := set $context.Values.__current_label "daemonset_override" $lname }} {{/* apply overrides */}} {{- $override_root_copy := $ldata.values }} {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}} {{- $root_copy := omit ($context.Values | toYaml | fromYaml) "overrides" }} {{- $merged_dict := mergeOverwrite $root_copy $override_root_copy }} {{- $root_conf_copy2 := dict "values" $merged_dict }} {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "values") "__daemonset_list" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2.values }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__current_label "nodeData" $root_conf_copy4 }} {{/* Schedule to the provided label value(s) */}} {{- $label_dict := dict "key" $label_name }} {{- $_ := set $label_dict "values" (list $label_value) }} {{- $_ := set $label_dict "operator" "In" }} {{- $list_aggregate := list $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{/* Do not schedule to other specified labels, with higher precedence as the list position increases. Last defined label is highest priority. */}} {{- $other_labels := omit $context.Values.__label_dict $lname }} {{- range $lname2, $ldata2 := $other_labels }} {{ $label_name2 := (split "::" $lname2)._0 }} {{ $label_value2 := (split "::" $lname2)._1 }} {{- $label_dict := dict "key" $label_name2 }} {{- $_ := set $label_dict "values" (list $label_value2) }} {{- $_ := set $label_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }} {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }} {{- end }} {{/* store completed daemonset entry/info into global list */}} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__current_label }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- $_ := unset $context.Values "__current_label" }} {{- end }} {{- end }} {{- end }} {{/* scheduler exceptions for the default daemonset */}} {{- $_ := set $context.Values.__default "matchExpressions" list }} {{- range $type, $type_data := . }} {{/* Do not schedule to other specified labels */}} {{- if eq $type "labels" }} {{- range $lname, $ldata := . }} {{ $label_name := (split "::" $lname)._0 }} {{ $label_value := (split "::" $lname)._1 }} {{- $default_dict := dict "key" $label_name }} {{- $_ := set $default_dict "values" (list $label_value) }} {{- $_ := set $default_dict "operator" "NotIn" }} {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }} {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{- end }} {{/* generate the default daemonset */}} {{/* set name */}} {{- $_ := set $context.Values.__default "name" "default" }} {{/* no overrides apply, so copy as-is */}} {{- $root_conf_copy1 := omit $context.Values.conf "overrides" }} {{- $root_conf_copy2 := dict "conf" $root_conf_copy1 }} {{- $context_values := omit $context.Values "conf" }} {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }} {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }} {{- $_ := set $context.Values.__default "nodeData" $root_conf_copy4 }} {{/* add to global list */}} {{- if $default_enabled }} {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__default }} {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }} {{- end }} {{- range $current_dict := $context.Values.__daemonset_list }} {{- $context_novalues := omit $context "Values" }} {{- $merged_dict := mergeOverwrite $context_novalues $current_dict.nodeData }} {{- $_ := set $current_dict "nodeData" $merged_dict }} {{/* Deep copy original daemonset_yaml */}} {{- $daemonset_yaml := list $daemonset $configmap_name $serviceAccountName $merged_dict | include $daemonSetTemplateName | toString | fromYaml }} {{- $_ := set $context.Values "__daemonset_yaml" ($daemonset_yaml | toYaml | fromYaml) }} {{/* Use the following name format $daemonset_root_name + sha256summ($current_dict.matchExpressions) as labels might be too long and contain wrong characters like / */}} {{- $_ := set $current_dict "dns_1123_name" dict }} {{- $name_format := "" }} {{- if eq $current_dict.name "default" }} {{- $name_format = (printf "%s-%s" $daemonset_root_name "default") | replace "_" "-" }} {{- else }} {{- $name_format = (printf "%s-%s" $daemonset_root_name ($current_dict.matchExpressions | quote | sha256sum | trunc 16)) | replace "_" "-" }} {{- end }} {{- $_ := set $current_dict "dns_1123_name" $name_format }} {{/* set daemonset metadata name */}} {{- if not $context.Values.__daemonset_yaml.metadata }}{{- $_ := set $context.Values.__daemonset_yaml "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.metadata.name }}{{- $_ := set $context.Values.__daemonset_yaml.metadata "name" dict }}{{- end }} {{- $_ := set $context.Values.__daemonset_yaml.metadata "name" $current_dict.dns_1123_name }} {{/* cross-reference configmap name to container volume definitions */}} {{- $_ := set $context.Values "__volume_list" list }} {{- range $current_volume := $context.Values.__daemonset_yaml.spec.template.spec.volumes }} {{- $_ := set $context.Values "__volume" $current_volume }} {{- if hasKey $context.Values.__volume "secret" }} {{- if eq $context.Values.__volume.secret.secretName $configmap_name }} {{- $_ := set $context.Values.__volume.secret "secretName" (printf "%s-etc" $current_dict.dns_1123_name) }} {{- end }} {{- end }} {{- if hasKey $context.Values.__volume "configMap" }} {{- if eq $context.Values.__volume.configMap.name $configbin_name }} {{- $_ := set $context.Values.__volume.configMap "name" (printf "%s-bin" $current_dict.dns_1123_name) }} {{- end }} {{- end }} {{- $updated_list := append $context.Values.__volume_list $context.Values.__volume }} {{- $_ := set $context.Values "__volume_list" $updated_list }} {{- end }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "volumes" $context.Values.__volume_list }} {{/* populate scheduling restrictions */}} {{- if hasKey $current_dict "matchExpressions" }} {{- $length := len $current_dict.matchExpressions }} {{- if gt $length 0 }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "affinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity "nodeAffinity" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity "requiredDuringSchedulingIgnoredDuringExecution" dict }}{{- end }} {{- $expressions_modified := list }} {{- if hasKey $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution "nodeSelectorTerms" }} {{- range $orig_expression := $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms }} {{- $match_expressions_modified := list }} {{- $match_expressions_modified = concat $match_expressions_modified $current_dict.matchExpressions }} {{- if hasKey $orig_expression "matchExpressions" }} {{- $match_expressions_modified = concat $match_expressions_modified $orig_expression.matchExpressions }} {{- $expressions_modified = append $expressions_modified (dict "matchExpressions" $match_expressions_modified) }} {{- end }} {{- end }} {{- else }} {{- $expressions_modified = (list (dict "matchExpressions" $current_dict.matchExpressions)) }} {{- end }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution "nodeSelectorTerms" $expressions_modified }} {{- end }} {{- end }} {{/* input value hash for current set of values overrides */}} {{- if not $context.Values.__daemonset_yaml.spec }}{{- $_ := set $context.Values.__daemonset_yaml "spec" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template }}{{- $_ := set $context.Values.__daemonset_yaml.spec "template" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "metadata" dict }}{{- end }} {{- if not $context.Values.__daemonset_yaml.spec.template.metadata.annotations }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata "annotations" dict }}{{- end }} {{- $cmap := list (printf "%s-etc" $current_dict.dns_1123_name) $current_dict.nodeData | include $configmap_include }} {{- $cmap_bin := list (printf "%s-bin" $current_dict.dns_1123_name) $current_dict.nodeData | include $configbin_include }} {{- $values_cmap_hash := $cmap | quote | sha256sum }} {{- $values_cmap_bin_hash := $cmap_bin | quote | sha256sum }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata.annotations "configmap-etc-hash" $values_cmap_hash }} {{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata.annotations "configmap-bin-hash" $values_cmap_bin_hash }} {{/* Do not set override for default daemonset */}} {{- if $current_dict.daemonset_override }} {{- $_ := set $context.Values.__daemonset_yaml.metadata.annotations "daemonset_override" $current_dict.daemonset_override }} {{- end }} {{/* generate configmap */}} --- {{ $cmap }} {{/* generate -bin yaml */}} --- {{ $cmap_bin }} {{/* generate daemonset yaml */}} --- {{ $context.Values.__daemonset_yaml | toYaml }} {{- end }} {{- end }} ================================================ FILE: helm-toolkit/templates/utils/_dependency_jobs.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* Filter dependency jobs when the corresponding manifests.job_* flag is disabled. The manifest key is derived from the dependency job name by dropping the chart prefix up to the first dash and converting the remainder from kebab-case to snake_case. If no matching manifest key exists, the job is kept. */}} {{- define "helm-toolkit.utils.dependency_jobs_filter" -}} {{- $envAll := index . "envAll" -}} {{- $deps := index . "deps" -}} {{- if and $deps (hasKey $deps "jobs") $deps.jobs -}} {{- if kindIs "string" (index $deps.jobs 0) -}} {{- $jobs := list -}} {{- range $job := $deps.jobs -}} {{- $jobParts := splitList "-" $job -}} {{- if gt (len $jobParts) 1 -}} {{- $manifestKey := printf "job_%s" (join "_" (rest $jobParts)) -}} {{- if or (not (hasKey $envAll.Values.manifests $manifestKey)) (index $envAll.Values.manifests $manifestKey) -}} {{- $jobs = append $jobs $job -}} {{- end -}} {{- else -}} {{- $jobs = append $jobs $job -}} {{- end -}} {{- end -}} {{- $_ := set $deps "jobs" $jobs -}} {{- end -}} {{- end -}} {{ $deps | toYaml }} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_dependency_resolver.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.utils.dependency_resolver" }} {{- $envAll := index . "envAll" -}} {{- $dependencyMixinParam := index . "dependencyMixinParam" -}} {{- $dependencyKey := index . "dependencyKey" -}} {{- if $dependencyMixinParam -}} {{- $_ := set $envAll.Values "pod_dependency" dict -}} {{- if kindIs "string" $dependencyMixinParam }} {{- if ( index $envAll.Values.dependencies.dynamic.targeted $dependencyMixinParam ) }} {{- $_ := include "helm-toolkit.utils.merge" (tuple $envAll.Values.pod_dependency ( index $envAll.Values.dependencies.static $dependencyKey ) ( index $envAll.Values.dependencies.dynamic.targeted $dependencyMixinParam $dependencyKey ) ) -}} {{- else }} {{- $_ := set $envAll.Values "pod_dependency" ( index $envAll.Values.dependencies.static $dependencyKey ) }} {{- end }} {{- else if kindIs "slice" $dependencyMixinParam }} {{- $_ := set $envAll.Values "__deps" ( index $envAll.Values.dependencies.static $dependencyKey ) }} {{- range $k, $v := $dependencyMixinParam -}} {{- if ( index $envAll.Values.dependencies.dynamic.targeted $v ) }} {{- $_ := include "helm-toolkit.utils.merge" (tuple $envAll.Values.pod_dependency $envAll.Values.__deps ( index $envAll.Values.dependencies.dynamic.targeted $v $dependencyKey ) ) -}} {{- $_ := set $envAll.Values "__deps" $envAll.Values.pod_dependency -}} {{- end }} {{- end }} {{- end }} {{- else -}} {{- $_ := set $envAll.Values "pod_dependency" ( index $envAll.Values.dependencies.static $dependencyKey ) -}} {{- end -}} {{- $_ := include "helm-toolkit.utils.dependency_jobs_filter" (dict "envAll" $envAll "deps" $envAll.Values.pod_dependency) | toString | fromYaml -}} {{ $envAll.Values.pod_dependency | toYaml }} {{- end }} ================================================ FILE: helm-toolkit/templates/utils/_hash.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.utils.hash" -}} {{- $name := index . 0 -}} {{- $context := index . 1 -}} {{- $last := base $context.Template.Name }} {{- $wtf := $context.Template.Name | replace $last $name -}} {{- include $wtf $context | sha256sum | quote -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_hash2.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.utils.hash2" -}} {{- $name := index . 0 -}} {{- $context := index . 1 -}} {{- $last := base $context.Template.Name }} {{- $wtf := $context.Template.Name | replace $last $name -}} {{- printf "%s" $wtf | quote -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_host_list.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns a list of unique hosts for an endpoint, in yaml. values: | endpoints: cluster_domain_suffix: cluster.local oslo_db: hosts: default: mariadb host_fqdn_override: default: mariadb usage: | {{ tuple "oslo_db" "internal" . | include "helm-toolkit.utils.host_list" }} return: | hosts: - mariadb - mariadb.default */}} {{- define "helm-toolkit.utils.host_list" -}} {{- $type := index . 0 -}} {{- $endpoint := index . 1 -}} {{- $context := index . 2 -}} {{- $host_fqdn := tuple $type $endpoint $context | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- $host_namespaced := tuple $type $endpoint $context | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $host_short := tuple $type $endpoint $context | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{/* It is important that the FQDN host is 1st in this list, to ensure other function can use the 1st element for cert gen CN etc */}} {{- $host_list := list $host_fqdn $host_namespaced $host_short | uniq }} {{- dict "hosts" $host_list | toYaml }} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_image_sync_list.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.utils.image_sync_list" -}} {{- $imageExcludeList := .Values.images.local_registry.exclude -}} {{- $imageDict := .Values.images.tags -}} {{- $local := dict "first" true -}} {{- range $k, $v := $imageDict -}} {{- if not $local.first -}},{{- end -}} {{- if (not (has $k $imageExcludeList )) -}} {{- index $imageDict $k -}} {{- $_ := set $local "first" false -}} {{- end -}}{{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_joinListWithComma.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Joins a list of values into a comma separated string values: | test: - foo - bar usage: | {{ include "helm-toolkit.utils.joinListWithComma" .Values.test }} return: | foo,bar */}} {{- define "helm-toolkit.utils.joinListWithComma" -}} {{- $local := dict "first" true -}} {{- range $k, $v := . -}}{{- if not $local.first -}},{{- end -}}{{- $v -}}{{- $_ := set $local "first" false -}}{{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_joinListWithCommaAndSingleQuotes.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Joins a list of values into a comma seperated string with single quotes around each value. values: | test: - foo - bar usage: | {{ include "helm-toolkit.utils.joinListWithCommaAndSingleQuotes" .Values.test }} return: | 'foo','bar' */}} {{- define "helm-toolkit.utils.joinListWithCommaAndSingleQuotes" -}} {{- $local := dict "first" true -}} {{- range $k, $v := . -}}{{- if not $local.first -}},{{- end -}}'{{- $v -}}'{{- $_ := set $local "first" false -}}{{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_joinListWithPrefix.tpl ================================================ {/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Joins a list of prefixed values into a space separated string values: | test: - foo - bar usage: | {{ tuple "prefix" .Values.test | include "helm-toolkit.utils.joinListWithPrefix" }} return: | prefixfoo prefixbar */}} {{- define "helm-toolkit.utils.joinListWithPrefix" -}} {{- $prefix := index . 0 -}} {{- $local := dict "first" true -}} {{- range $k, $v := index . 1 -}}{{- if not $local.first -}}{{- " " -}}{{- end -}}{{- $prefix -}}{{- $v -}}{{- $_ := set $local "first" false -}}{{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_joinListWithSpace.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Joins a list of values into a space separated string values: | test: - foo - bar usage: | {{ include "helm-toolkit.utils.joinListWithSpace" .Values.test }} return: | foo bar */}} {{- define "helm-toolkit.utils.joinListWithSpace" -}} {{- $local := dict "first" true -}} {{- range $k, $v := . -}}{{- if not $local.first -}}{{- " " -}}{{- end -}}{{- $v -}}{{- $_ := set $local "first" false -}}{{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_merge.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* Takes a tuple of values and merges into the first (target) one each subsequent (source) one in order. If all values to merge are maps, then the tuple can be passed as is and the target will be the result, otherwise pass a map with a "values" key containing the tuple of values to merge, and the merge result will be assigned to the "result" key of the passed map. When merging maps, for each key in the source, if the target does not define that key, the source value is assigned. If both define the key, then the key values are merged using this algorithm (recursively) and the result is assigned to the target key. Slices are merged by appending them and removing any duplicates, and when passing a map to this function and including a "merge_same_named" key set to true, then map items from the slices with the same value for the "name" key will be merged with each other. Any other values are merged by simply keeping the source, and throwing away the target. */}} {{- define "helm-toolkit.utils.merge" -}} {{- $local := dict -}} {{- $_ := set $local "merge_same_named" false -}} {{- if kindIs "map" $ -}} {{- $_ := set $local "values" $.values -}} {{- if hasKey $ "merge_same_named" -}} {{- $_ := set $local "merge_same_named" $.merge_same_named -}} {{- end -}} {{- else -}} {{- $_ := set $local "values" $ -}} {{- end -}} {{- $target := first $local.values -}} {{- range $item := rest $local.values -}} {{- $call := dict "target" $target "source" . "merge_same_named" $local.merge_same_named -}} {{- $_ := include "helm-toolkit.utils._merge" $call -}} {{- $_ := set $local "result" $call.result -}} {{- end -}} {{- if kindIs "map" $ -}} {{- $_ := set $ "result" $local.result -}} {{- end -}} {{- end -}} {{- define "helm-toolkit.utils._merge" -}} {{- $local := dict -}} {{- $_ := set $ "result" $.source -}} {{/* TODO: Should we `fail` when trying to merge a collection (map or slice) with either a different kind of collection or a scalar? */}} {{- if and (kindIs "map" $.target) (kindIs "map" $.source) -}} {{- range $key, $sourceValue := $.source -}} {{- if not (hasKey $.target $key) -}} {{- $_ := set $local "newTargetValue" $sourceValue -}} {{- if kindIs "map" $sourceValue -}} {{- $copy := dict -}} {{- $call := dict "target" $copy "source" $sourceValue -}} {{- $_ := include "helm-toolkit.utils._merge.shallow" $call -}} {{- $_ := set $local "newTargetValue" $copy -}} {{- end -}} {{- else -}} {{- $targetValue := index $.target $key -}} {{- $call := dict "target" $targetValue "source" $sourceValue "merge_same_named" $.merge_same_named -}} {{- $_ := include "helm-toolkit.utils._merge" $call -}} {{- $_ := set $local "newTargetValue" $call.result -}} {{- end -}} {{- $_ := set $.target $key $local.newTargetValue -}} {{- end -}} {{- $_ := set $ "result" $.target -}} {{- else if and (kindIs "slice" $.target) (kindIs "slice" $.source) -}} {{- $call := dict "target" $.target "source" $.source -}} {{- $_ := include "helm-toolkit.utils._merge.append_slice" $call -}} {{- if $.merge_same_named -}} {{- $_ := set $local "result" list -}} {{- $_ := set $local "named_items" dict -}} {{- range $item := $call.result -}} {{- $_ := set $local "has_name_key" false -}} {{- if kindIs "map" $item -}} {{- if hasKey $item "name" -}} {{- $_ := set $local "has_name_key" true -}} {{- end -}} {{- end -}} {{- if $local.has_name_key -}} {{- if hasKey $local.named_items $item.name -}} {{- $named_item := index $local.named_items $item.name -}} {{- $call := dict "target" $named_item "source" $item "merge_same_named" $.merge_same_named -}} {{- $_ := include "helm-toolkit.utils._merge" $call -}} {{- else -}} {{- $copy := dict -}} {{- $copy_call := dict "target" $copy "source" $item -}} {{- $_ := include "helm-toolkit.utils._merge.shallow" $copy_call -}} {{- $_ := set $local.named_items $item.name $copy -}} {{- $_ := set $local "result" (append $local.result $copy) -}} {{- end -}} {{- else -}} {{- $_ := set $local "result" (append $local.result $item) -}} {{- end -}} {{- end -}} {{- else -}} {{- $_ := set $local "result" $call.result -}} {{- end -}} {{- $_ := set $ "result" (uniq $local.result) -}} {{- end -}} {{- end -}} {{- define "helm-toolkit.utils._merge.shallow" -}} {{- range $key, $value := $.source -}} {{- $_ := set $.target $key $value -}} {{- end -}} {{- end -}} {{- define "helm-toolkit.utils._merge.append_slice" -}} {{- $local := dict -}} {{- $_ := set $local "result" $.target -}} {{- range $value := $.source -}} {{- $_ := set $local "result" (append $local.result $value) -}} {{- end -}} {{- $_ := set $ "result" $local.result -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_template.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "helm-toolkit.utils.template" -}} {{- $name := index . 0 -}} {{- $context := index . 1 -}} {{- $last := base $context.Template.Name }} {{- $wtf := $context.Template.Name | replace $last $name -}} {{ include $wtf $context }} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_to_ini.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns INI formatted output from yaml input values: | conf: paste: filter:debug: use: egg:oslo.middleware#debug filter:request_id: use: egg:oslo.middleware#request_id filter:build_auth_context: use: egg:keystone#build_auth_context usage: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste }} return: | [filter:build_auth_context] use = egg:keystone#build_auth_context [filter:debug] use = egg:oslo.middleware#debug [filter:request_id] use = egg:oslo.middleware#request_id */}} {{- define "helm-toolkit.utils.to_ini" -}} {{- range $section, $values := . -}} {{- if kindIs "map" $values -}} [{{ $section }}] {{range $key, $value := $values -}} {{- if kindIs "slice" $value -}} {{ $key }} = {{ include "helm-toolkit.utils.joinListWithComma" $value }} {{else -}} {{ $key }} = {{ $value }} {{end -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_to_k8s_env_secret_vars.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns yaml formatted to be used in k8s templates as container env vars injected via secrets. This requires a secret- template to be defined in the chart that can be used to house the desired secret variables. For reference, see the fluentd chart. values: | test: secrets: foo: bar usage: | {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.test }} return: | - name: foo valueFrom: secretKeyRef: name: "my-release-name-env-secret" key: foo */}} {{- define "helm-toolkit.utils.to_k8s_env_secret_vars" -}} {{- $context := index . 0 -}} {{- $secrets := index . 1 -}} {{ range $key, $config := $secrets -}} - name: {{ $key }} valueFrom: secretKeyRef: name: {{ printf "%s-%s" $context.Release.Name "env-secret" | quote }} key: {{ $key }} {{ end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_to_k8s_env_vars.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns key value pair formatted to be used in k8s templates as container env vars. values: | test: foo: bar usage: | {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.test }} return: | - name: foo value: "bar" */}} {{- define "helm-toolkit.utils.to_k8s_env_vars" -}} {{range $key, $value := . -}} {{- if kindIs "slice" $value -}} - name: {{ $key }} value: {{ include "helm-toolkit.utils.joinListWithComma" $value | quote }} {{else -}} - name: {{ $key }} value: {{ $value | quote }} {{ end -}} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_to_kv_list.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns key value pair in INI format (key = value) values: | conf: libvirt: log_level: 3 usage: | {{ include "helm-toolkit.utils.to_kv_list" .Values.conf.libvirt }} return: | log_level = 3 */}} {{- define "helm-toolkit.utils.to_kv_list" -}} {{- range $key, $value := . -}} {{- if kindIs "slice" $value }} {{ $key }} = {{ include "helm-toolkit.utils.joinListWithComma" $value | quote }} {{- else if kindIs "string" $value }} {{- if regexMatch "^[0-9]+$" $value }} {{ $key }} = {{ $value }} {{- else }} {{ $key }} = {{ $value | quote }} {{- end }} {{- else }} {{ $key }} = {{ $value }} {{- end }} {{- end -}} {{- end -}} ================================================ FILE: helm-toolkit/templates/utils/_to_oslo_conf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Returns OSLO.conf formatted output from yaml input values: | conf: keystone: DEFAULT: # Keys at this level are used for section headings max_token_size: 255 oslo_messaging_notifications: driver: # An example of a multistring option's syntax type: multistring values: - messagingv2 - log oslo_messaging_notifications_stein: driver: # An example of a csv option's syntax type: csv values: - messagingv2 - log security_compliance: password_expires_ignore_user_ids: # Values in a list will be converted to a comma separated key - "123" - "456" usage: | {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.keystone }} return: | [DEFAULT] max_token_size = 255 [oslo_messaging_notifications] driver = messagingv2 driver = log [oslo_messaging_notifications_stein] driver = messagingv2,log [security_compliance] password_expires_ignore_user_ids = 123,456 */}} {{- define "helm-toolkit.utils.to_oslo_conf" -}} {{- range $section, $values := . -}} {{- if kindIs "map" $values -}} [{{ $section }}] {{ range $key, $value := $values -}} {{- if kindIs "slice" $value -}} {{ $key }} = {{ include "helm-toolkit.utils.joinListWithComma" $value }} {{ else if kindIs "map" $value -}} {{- if eq $value.type "multistring" }} {{- range $k, $multistringValue := $value.values -}} {{ $key }} = {{ $multistringValue }} {{ end -}} {{ else if eq $value.type "csv" -}} {{ $key }} = {{ include "helm-toolkit.utils.joinListWithComma" $value.values }} {{ end -}} {{- else -}} {{ $key }} = {{ $value }} {{ end -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: horizon/.helmignore ================================================ values_overrides ================================================ FILE: horizon/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Horizon name: horizon version: 2025.2.0 home: https://docs.openstack.org/horizon/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Horizon/OpenStack_Project_Horizon_vertical.png sources: - https://opendev.org/openstack/horizon - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: horizon/releasenotes/notes/horizon-023da44e7958de05.yaml ================================================ --- features: - | Added support for openstack keystone domain dropdown ... ================================================ FILE: horizon/releasenotes/notes/horizon-4c5d5e3b58c700a0.yaml ================================================ --- features: - | Added support for customizing the SESSION_ENGINE. This enables deployers to select different Django session storage options, such as database-backed or cache-based sessions, according to their environment needs. ... ================================================ FILE: horizon/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex SITE_PACKAGES_ROOT=$(python -c "from sysconfig import get_path; print(get_path('platlib'))") rm -f ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/local_settings.py ln -s /etc/openstack-dashboard/local_settings ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/local_settings.py exec /tmp/manage.py migrate --noinput ================================================ FILE: horizon/templates/bin/_django.wsgi.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* NOTE (Portdirect): This file is required to support Horizon regardless of the image used, and to provide PyMySQL support. */}} import logging import os import sys import pymysql pymysql.version_info = (2, 2, 4, 'final', 0) pymysql.install_as_MySQLdb() from django.core.wsgi import get_wsgi_application from django.conf import settings # Add this file path to sys.path in order to import settings sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..')) os.environ['DJANGO_SETTINGS_MODULE'] = 'openstack_dashboard.settings' sys.stdout = sys.stderr DEBUG = False application = get_wsgi_application() ================================================ FILE: horizon/templates/bin/_horizon.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { SITE_PACKAGES_ROOT=$(python -c "from sysconfig import get_path; print(get_path('platlib'))") rm -f ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/local_settings.py ln -s /etc/openstack-dashboard/local_settings ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/local_settings.py ln -s ${SITE_PACKAGES_ROOT}/openstack_dashboard/conf/default_policies /etc/openstack-dashboard/default_policies {{- range $key, $value := .Values.conf.horizon.local_settings_d }} ln -s /etc/openstack-dashboard/local_settings.d/{{ $key }}.py ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/local_settings.d/{{ $key }}.py {{- end }} {{- range $key, $value := .Values.conf.horizon.custom_panels }} ln -s /etc/openstack-dashboard/custom_panels/{{ $key }}.py ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/enabled/{{ $key }}.py {{- end }} # wsgi/horizon-http needs open files here, including secret_key_store chown -R horizon ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/ {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars # The directory below has to be created due to the fact that # libapache2-mod-wsgi-py3 doesn't create it in contrary by libapache2-mod-wsgi if [ ! -d ${APACHE_RUN_DIR} ]; then mkdir -p ${APACHE_RUN_DIR} fi fi rm -rf /var/run/apache2/* APACHE_DIR="apache2" # Add extra panels if available {{- range .Values.conf.horizon.extra_panels }} PANEL_DIR="${SITE_PACKAGES_ROOT}/{{ . }}/enabled" if [ -d ${PANEL_DIR} ];then for panel in `ls -1 ${PANEL_DIR}/_[1-9]*.py` do ln -s ${panel} ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/enabled/$(basename ${panel}) done fi unset PANEL_DIR PANEL_DIR="${SITE_PACKAGES_ROOT}/{{ . }}/local/enabled" if [ -d ${PANEL_DIR} ];then for panel in `ls -1 ${PANEL_DIR}/_[1-9]*.py` do ln -s ${panel} ${SITE_PACKAGES_ROOT}/openstack_dashboard/local/enabled/$(basename ${panel}) done fi unset PANEL_DIR {{- end }} # If the image has support for it, compile the translations if type -p gettext >/dev/null 2>/dev/null; then cd ${SITE_PACKAGES_ROOT}/openstack_dashboard; /tmp/manage.py compilemessages # if there are extra panels and the image has support for it, compile the translations {{- range .Values.conf.horizon.extra_panels }} PANEL_DIR="${SITE_PACKAGES_ROOT}/{{ . }}" if [ -d ${PANEL_DIR} ]; then cd ${PANEL_DIR}; /tmp/manage.py compilemessages fi {{- end }} unset PANEL_DIR fi # Copy custom logo images {{- if .Values.manifests.configmap_logo }} if [[ -f /tmp/favicon.ico ]]; then cp /tmp/favicon.ico ${SITE_PACKAGES_ROOT}/openstack_dashboard/static/dashboard/img/favicon.ico fi if [[ -f /tmp/logo.svg ]]; then cp /tmp/logo.svg ${SITE_PACKAGES_ROOT}/openstack_dashboard/static/dashboard/img/logo.svg fi if [[ -f /tmp/logo-splash.svg ]]; then cp /tmp/logo-splash.svg ${SITE_PACKAGES_ROOT}/openstack_dashboard/static/dashboard/img/logo-splash.svg fi {{- end }} # Compress Horizon's assets. /tmp/manage.py collectstatic --noinput /tmp/manage.py compress --force rm -rf /tmp/_tmp_.secret_key_store.lock /tmp/.secret_key_store chmod +x ${SITE_PACKAGES_ROOT}/django/core/wsgi.py exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} } function stop () { {{ .Values.conf.software.apache2.binary }} -k graceful-stop } $COMMAND ================================================ FILE: horizon/templates/bin/_manage.py.tpl ================================================ #!/usr/bin/env python {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* NOTE (Portdirect): This file is required to support Horizon regardless of the image used, and to provide PyMySQL support. */}} import os import sys import pymysql pymysql.version_info = (2, 2, 4, 'final', 0) pymysql.install_as_MySQLdb() from django.core.management import execute_from_command_line if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "openstack_dashboard.settings") execute_from_command_line(sys.argv) ================================================ FILE: horizon/templates/bin/_selenium-test.py.tpl ================================================ #!/usr/bin/env python3 {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} import os import sys import logging from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options {{- if .Values.selenium_v4 }} from selenium.webdriver.chrome.service import Service {{- end }} from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import NoSuchElementException # Create logger, console handler and formatter logger = logging.getLogger('Horizon Selenium Tests') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) ch.setFormatter(formatter) logger.addHandler(ch) def get_variable(env_var): if env_var in os.environ: logger.info('Found "{}"'.format(env_var)) return os.environ[env_var] else: logger.critical('Variable "{}" is not defined!'.format(env_var)) sys.exit(1) keystone_user = get_variable('OS_USERNAME') keystone_password = get_variable('OS_PASSWORD') horizon_uri = get_variable('HORIZON_URI') user_domain_name = get_variable('OS_USER_DOMAIN_NAME') # Add options to make chrome browser headless options = Options() options.add_argument('--headless') options.add_argument('--no-sandbox') chrome_driver = '/etc/selenium/chromedriver' {{- if .Values.selenium_v4 }} service = Service(executable_path=chrome_driver) browser = webdriver.Chrome(service=service, options=options) {{- else }} browser = webdriver.Chrome(chrome_driver, chrome_options=options) {{- end }} try: logger.info('Attempting to connect to Horizon') browser.get(horizon_uri) el = WebDriverWait(browser, 15).until( EC.title_contains('OpenStack Dashboard') ) logger.info('Connected to Horizon') except TimeoutException: logger.critical('Timed out waiting for Horizon') browser.quit() sys.exit(1) try: logger.info('Attempting to log into Horizon') {{- if .Values.selenium_v4 }} browser.find_element(By.NAME, 'domain').send_keys(user_domain_name) browser.find_element(By.NAME, 'username').send_keys(keystone_user) browser.find_element(By.NAME, 'password').send_keys(keystone_password) browser.find_element(By.ID, 'loginBtn').click() {{- else }} browser.find_element_by_name('domain').send_keys(user_domain_name) browser.find_element_by_name('username').send_keys(keystone_user) browser.find_element_by_name('password').send_keys(keystone_password) browser.find_element_by_id('loginBtn').click() {{- end }} WebDriverWait(browser, 15).until( EC.presence_of_element_located((By.ID, 'navbar-collapse')) ) logger.info("Successfully logged into Horizon") except (TimeoutException, NoSuchElementException): logger.error('Failed to login to Horizon') browser.quit() sys.exit(1) browser.quit() ================================================ FILE: horizon/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "dashboard" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: horizon/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: horizon-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} horizon.sh: | {{ tuple "bin/_horizon.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} manage.py: | {{ tuple "bin/_manage.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} django.wsgi: | {{ tuple "bin/_django.wsgi.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} selenium-test.py: | {{ tuple "bin/_selenium-test.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: horizon/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: horizon-etc type: Opaque data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.horizon.apache "key" "horizon.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.horizon.local_settings.template "key" "local_settings" "format" "Secret" ) | indent 2 }} {{- if .Values.conf.horizon.security }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.horizon.security "key" "security.conf" "format" "Secret" ) | indent 2 }} {{- end }} {{- range $key, $value := .Values.conf.horizon.custom_panels }} {{ printf "%s.py" $key }}: {{ $value | b64enc }} {{- end }} {{- range $key, $value := .Values.conf.horizon.policy }} {{ printf "%s_policy.json" $key }}: {{ $value | toPrettyJson | b64enc }} {{- end }} {{- range $key, $value := .Values.conf.horizon.policy }} {{ printf "%s_policy.yaml" $key }}: {{ toYaml $value | b64enc }} {{- end }} {{- range $key, $value := .Values.conf.horizon.local_settings_d }} {{ printf "%s.py" $key }}: {{ $value | b64enc }} {{- end }} {{- end }} ================================================ FILE: horizon/templates/configmap-logo.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_logo }} --- apiVersion: v1 kind: ConfigMap metadata: name: horizon-logo binaryData: {{- if .Values.conf.horizon.branding.favicon }} favicon.ico: | {{- .Values.conf.horizon.branding.favicon | nindent 4 }} {{- end }} {{- if .Values.conf.horizon.branding.logo }} logo.svg: | {{- .Values.conf.horizon.branding.logo | nindent 4 }} {{- end }} {{- if .Values.conf.horizon.branding.logo_splash }} logo-splash.svg: | {{- .Values.conf.horizon.branding.logo_splash | nindent 4 }} {{- end }} {{- end }} ================================================ FILE: horizon/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $mounts_horizon := .Values.pod.mounts.horizon.horizon }} {{- $mounts_horizon_init := .Values.pod.mounts.horizon.init_container }} {{- $serviceAccountName := "horizon" }} {{ tuple $envAll "dashboard" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: horizon annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "horizon" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.server }} selector: matchLabels: {{ tuple $envAll "horizon" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "horizon" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "horizon" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{- if .Values.manifests.configmap_logo }} configmap-logo-hash: {{ tuple "configmap-logo.yaml" . | include "helm-toolkit.utils.hash" }} {{- end }} {{ dict "envAll" $envAll "podName" "horizon" "containerNames" (list "horizon" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "horizon" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "horizon" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "horizon" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "horizon" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.dashboard.node_selector_key }}: {{ .Values.labels.dashboard.node_selector_value }} {{ if $envAll.Values.pod.tolerations.horizon.enabled }} {{ tuple $envAll "horizon" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.horizon.timeout | default "30" }} initContainers: {{ tuple $envAll "dashboard" $mounts_horizon_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: horizon {{ tuple $envAll "horizon" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "horizon" "container" "horizon" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/horizon.sh - start env: - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/openstack-dashboard/certs/ca.crt" {{- end }} lifecycle: preStop: exec: command: - /tmp/horizon.sh - stop ports: - name: web containerPort: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 15 periodSeconds: 10 timeoutSeconds: 5 livenessProbe: httpGet: scheme: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 180 periodSeconds: 60 timeoutSeconds: 5 volumeMounts: - name: pod-tmp mountPath: /tmp - name: static-horizon mountPath: /var/www/html/ - name: horizon-bin mountPath: /tmp/horizon.sh subPath: horizon.sh readOnly: true - name: horizon-bin mountPath: /tmp/manage.py subPath: manage.py readOnly: true - name: horizon-etc mountPath: {{ .Values.conf.software.apache2.site_dir }}/000-default.conf subPath: horizon.conf readOnly: true {{- if .Values.conf.horizon.security }} - name: horizon-etc mountPath: {{ .Values.conf.software.apache2.conf_dir }}/security.conf subPath: security.conf readOnly: true {{- end }} - name: horizon-bin mountPath: /var/www/cgi-bin/horizon/django.wsgi subPath: django.wsgi readOnly: true - name: horizon-etc mountPath: /etc/openstack-dashboard/local_settings subPath: local_settings readOnly: true {{- range $key, $value := $envAll.Values.conf.horizon.custom_panels }} {{- $customPanelsFile := printf "/etc/openstack-dashboard/custom_panels/%s.py" $key }} - name: horizon-etc mountPath: {{ $customPanelsFile }} subPath: {{ base $customPanelsFile }} readOnly: true {{- end }} {{- range $key, $value := $envAll.Values.conf.horizon.policy }} {{- $policyYamlFile := printf "/etc/openstack-dashboard/%s_policy.yaml" $key }} - name: horizon-etc mountPath: {{ $policyYamlFile }} subPath: {{ base $policyYamlFile }} readOnly: true {{- end }} {{- range $key, $value := $envAll.Values.conf.horizon.policy }} {{- $policyJsonFile := printf "/etc/openstack-dashboard/%s_policy.json" $key }} - name: horizon-etc mountPath: {{ $policyJsonFile }} subPath: {{ base $policyJsonFile }} readOnly: true {{- end }} {{- range $key, $value := $envAll.Values.conf.horizon.local_settings_d }} {{- $localSettingsFile := printf "/etc/openstack-dashboard/local_settings.d/%s.py" $key }} - name: horizon-etc mountPath: {{ $localSettingsFile }} subPath: {{ base $localSettingsFile }} readOnly: true {{- end }} {{- if .Values.manifests.configmap_logo }} - name: horizon-logo mountPath: /tmp/logo.svg subPath: logo.svg - name: horizon-logo mountPath: /tmp/logo-splash.svg subPath: logo-splash.svg - name: horizon-logo mountPath: /tmp/favicon.ico subPath: favicon.ico {{- end }} {{- dict "enabled" (or $envAll.Values.manifests.certificates $envAll.Values.tls.identity) "name" $envAll.Values.secrets.tls.dashboard.dashboard.internal "path" "/etc/openstack-dashboard/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_horizon.volumeMounts }}{{ toYaml $mounts_horizon.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: wsgi-horizon emptyDir: {} - name: static-horizon emptyDir: {} - name: horizon-bin configMap: name: horizon-bin defaultMode: 0555 - name: horizon-etc secret: secretName: horizon-etc defaultMode: 0444 {{- if .Values.manifests.configmap_logo }} - name: horizon-logo configMap: name: horizon-logo {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or $envAll.Values.manifests.certificates $envAll.Values.tls.identity) "name" $envAll.Values.secrets.tls.dashboard.dashboard.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_horizon.volumes }}{{ toYaml $mounts_horizon.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: horizon/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: horizon/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.dashboard.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "dashboard" "backendServiceType" "dashboard" "backendPort" "web" -}} {{- $secretName := $envAll.Values.secrets.tls.dashboard.dashboard.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.dashboard.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: horizon/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbToDrop := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.horizon -}} {{- $dbDropJob := dict "envAll" . "serviceName" "horizon" "dbToDrop" $dbToDrop -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.horizon.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: horizon/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbToInit := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.horizon -}} {{- $dbInitJob := dict "envAll" . "serviceName" "horizon" "dbToInit" $dbToInit -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.horizon.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: horizon/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_sync }} {{- $envAll := . }} {{- $mounts_horizon_db_sync := .Values.pod.mounts.horizon_db_sync.horizon_db_sync }} {{- $mounts_horizon_db_sync_init := .Values.pod.mounts.horizon_db_sync.init_container }} {{- $serviceAccountName := "horizon-db-sync" }} {{ tuple $envAll "db_sync" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: horizon-db-sync labels: {{ tuple $envAll "horizon" "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "horizon" "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "horizon-db-sync" "containerNames" (list "horizon-db-sync" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "db_sync" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "db_sync" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "db_sync" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.horizon.enabled }} {{ tuple $envAll "horizon" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "db_sync" $mounts_horizon_db_sync_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: horizon-db-sync {{ tuple $envAll "horizon_db_sync" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "db_sync" "container" "horizon_db_sync" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/db-sync.sh volumeMounts: - name: horizon-etc mountPath: /etc/openstack-dashboard/local_settings subPath: local_settings readOnly: true - name: horizon-bin mountPath: /tmp/db-sync.sh subPath: db-sync.sh readOnly: true - name: horizon-bin mountPath: /tmp/manage.py subPath: manage.py readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 10 }} {{ if $mounts_horizon_db_sync.volumeMounts }}{{ toYaml $mounts_horizon_db_sync.volumeMounts | indent 10 }}{{ end }} volumes: - name: horizon-etc secret: secretName: horizon-etc defaultMode: 0444 - name: horizon-bin configMap: name: horizon-bin defaultMode: 0555 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 6 }} {{ if $mounts_horizon_db_sync.volumes }}{{ toYaml $mounts_horizon_db_sync.volumes | indent 6 }}{{ end }} {{- end }} ================================================ FILE: horizon/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "horizon" -}} {{- if .Values.pod.tolerations.horizon.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: horizon/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "horizon" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: horizon/templates/pdb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: horizon spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.horizon.min_available }} selector: matchLabels: {{ tuple $envAll "horizon" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: horizon/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_helm_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.horizon_tests.horizon_tests }} {{- $mounts_tests_init := .Values.pod.mounts.horizon_tests.init_container }} {{- $serviceAccountName := print $envAll.Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.Release.Name "-test" }} labels: {{ tuple $envAll "horizon" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "horizon-test" "containerNames" (list "init" "horizon-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} restartPolicy: Never {{ tuple "horizon_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "horizon_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.horizon.enabled }} {{ tuple $envAll "horizon" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: horizon-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "horizon_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/selenium-test.py env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: HORIZON_URI value: {{ tuple "dashboard" "public" "web" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: horizon-bin mountPath: /tmp/selenium-test.py subPath: selenium-test.py readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" .Values.secrets.tls.dashboard.dashboard.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: horizon-bin configMap: name: horizon-bin defaultMode: 0555 {{- dict "enabled" $envAll.Values.manifests.certificates "name" .Values.secrets.tls.dashboard.dashboard.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: horizon/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "horizon" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: horizon/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendService" "dashboard" "backendServiceType" "dashboard" ) }} {{- end }} ================================================ FILE: horizon/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.identity.admin }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" "admin" $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple "admin" "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} ================================================ FILE: horizon/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: horizon/templates/service-ingress.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.dashboard.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "dashboard" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: horizon/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "dashboard" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: {{ if .Values.network.node_port.enabled }} - name: web protocol: TCP nodePort: {{ .Values.network.node_port.port }} port: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ else }} - name: web protocol: TCP port: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ end }} selector: {{ tuple $envAll "horizon" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.node_port.enabled }} type: NodePort {{ if .Values.network.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: horizon/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for horizon. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble horizon_db_sync: quay.io/airshipit/horizon:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble horizon: quay.io/airshipit/horizon:2025.1-ubuntu_noble test: quay.io/airshipit/osh-selenium:latest-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync # Use selenium v4 syntax selenium_v4: true release_group: null labels: dashboard: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled network: dashboard: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/proxy-body-size: "0" haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 31000 conf: software: apache2: binary: apache2 start_parameters: -DFOREGROUND site_dir: /etc/apache2/sites-available conf_dir: /etc/apache2/conf-available mods_dir: /etc/apache2/mods-available a2enmod: - headers - rewrite a2dismod: - status horizon: branding: # favicon must be a base64 encoded .ico string # logo and logo_splash must be base64 encoded .svg string logo: logo_splash: favicon: apache: | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded WSGIApplicationGroup %{GLOBAL} WSGIScriptReloading On WSGIDaemonProcess horizon-http processes=5 threads=1 user=horizon group=horizon display-name=%{GROUP} WSGIProcessGroup horizon-http WSGIScriptAlias / /var/www/cgi-bin/horizon/django.wsgi WSGIPassAuthorization On RewriteEngine on RewriteCond %{REQUEST_METHOD} !^(POST|PUT|GET|DELETE|PATCH) RewriteRule .* - [F] Require all granted Alias /static /var/www/html/horizon SetHandler static ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout TransferLog /dev/stdout SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded security: | # # Disable access to the entire file system except for the directories that # are explicitly allowed later. # # This currently breaks the configurations that come with some web application # Debian packages. # # # AllowOverride None # Require all denied # # Changing the following options will not really affect the security of the # server, but might make attacks slightly more difficult in some cases. # # ServerTokens # This directive configures what you return as the Server HTTP response # Header. The default is 'Full' which sends information about the OS-Type # and compiled in modules. # Set to one of: Full | OS | Minimal | Minor | Major | Prod # where Full conveys the most information, and Prod the least. ServerTokens Prod # # Optionally add a line containing the server version and virtual host # name to server-generated pages (internal error documents, FTP directory # listings, mod_status and mod_info output etc., but not CGI generated # documents or custom error documents). # Set to "EMail" to also include a mailto: link to the ServerAdmin. # Set to one of: On | Off | EMail ServerSignature Off # # Allow TRACE method # # Set to "extended" to also reflect the request body (only for testing and # diagnostic purposes). # # Set to one of: On | Off | extended TraceEnable Off # # Forbid access to version control directories # # If you use version control systems in your document root, you should # probably deny access to their directories. For example, for subversion: # # # Require all denied # #Security-Settings # Setting this header will prevent MSIE from interpreting files as something # else than declared by the content type in the HTTP headers. # Requires mod_headers to be enabled. # Header set X-Content-Type-Options: "nosniff" Header set X-Permitted-Cross-Domain-Policies: "none" # Setting this header will prevent other sites from embedding pages from this # site as frames. This defends against clickjacking attacks. # Requires mod_headers to be enabled. # custom_panels: {} ## For example, _5000_disable_project_vg_snapshots.py # _5000_disable_project_vg_snapshots: | # PANEL = 'vg_snapshots' # PANEL_DASHBOARD = 'project' # PANEL_GROUP = 'volumes' # REMOVE_PANEL = True ## https://docs.openstack.org/horizon/latest/configuration/pluggable_panels.html#id2 local_settings_d: {} local_settings: config: # Use "True" and "False" as Titlecase strings with quotes, boolean # values will not work horizon_secret_key: 9aee62c0-5253-4a86-b189-e0fb71fa503c debug: "False" use_ssl: "False" endpoint_type: "internalURL" keystone_multidomain_support: "True" keystone_multidomain_dropdown: "False" keystone_domains: Default: "Default" example_domain: "example" keystone_default_domain: Default disable_password_reveal: "True" show_openrc_file: "True" csrf_cookie_secure: "False" csrf_cookie_httponly: "False" csrf_trusted_origins: [] enforce_password_check: "True" # Set enable_pwd_validator to true to enforce password validator settings. enable_pwd_validator: false pwd_validator_regex: '(?=.*[a-zA-Z])(?=.*\d).{8,}|(?=.*\d)(?=.*\W).{8,}|(?=.*\W)(?=.*[a-zA-Z]).{8,}' pwd_validator_help_text: '_("Your password must be at least eight (8) characters in length and must include characters from at least two (2) of these groupings: alpha, numeric, and special characters.")' session_cookie_secure: "False" session_cookie_httponly: "False" session_engine: 'django.contrib.sessions.backends.cache' cache_backend: 'django.core.cache.backends.memcached.PyMemcacheCache' secure_proxy_ssl_header: false password_autocomplete: "False" disallow_iframe_embed: "False" ssl_no_verify: "True" allowed_hosts: - '*' horizon_images_upload_mode: 'legacy' openstack_cinder_features: enable_backup: "True" openstack_neutron_network: enable_router: "True" enable_quotas: "True" enable_ipv6: "True" enable_distributed_router: "False" enable_ha_router: "False" enable_lb: "True" enable_firewall: "True" enable_vpn: "True" enable_fip_topology_check: "True" openstack_enable_password_retrieve: "False" auth: sso: enabled: False initial_choice: "credentials" idp_mapping: - name: "acme_oidc" label: "Acme Corporation - OpenID Connect" idp: "myidp1" protocol: "oidc" - name: "acme_saml2" label: "Acme Corporation - SAML2" idp: "myidp2" protocol: "saml2" log_level: "DEBUG" # Pass any settings to the end of local_settings.py raw: {} openstack_api_versions: container_infra: "1.10" template: | import os from django.utils.translation import gettext_lazy as _ from openstack_dashboard import exceptions DEBUG = {{ .Values.conf.horizon.local_settings.config.debug }} TEMPLATE_DEBUG = DEBUG COMPRESS_OFFLINE = True COMPRESS_CSS_HASHING_METHOD = "hash" # WEBROOT is the location relative to Webserver root # should end with a slash. WEBROOT = '/' # LOGIN_URL = WEBROOT + 'auth/login/' # LOGOUT_URL = WEBROOT + 'auth/logout/' # # LOGIN_REDIRECT_URL can be used as an alternative for # HORIZON_CONFIG.user_home, if user_home is not set. # Do not set it to '/home/', as this will cause circular redirect loop # LOGIN_REDIRECT_URL = WEBROOT # Required for Django 1.5. # If horizon is running in production (DEBUG is False), set this # with the list of host/domain names that the application can serve. # For more information see: # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts ALLOWED_HOSTS = [{{ include "helm-toolkit.utils.joinListWithCommaAndSingleQuotes" .Values.conf.horizon.local_settings.config.allowed_hosts }},'%s' % (os.environ.get("MY_POD_IP"))] # Set SSL proxy settings: # For Django 1.4+ pass this header from the proxy after terminating the SSL, # and don't forget to strip it from the client's request. # For more information see: # https://docs.djangoproject.com/en/1.4/ref/settings/#secure-proxy-ssl-header #SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https') # https://docs.djangoproject.com/en/1.5/ref/settings/#secure-proxy-ssl-header {{- if .Values.conf.horizon.local_settings.config.secure_proxy_ssl_header }} SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') {{- end }} # If Horizon is being served through SSL, then uncomment the following two # settings to better secure the cookies from security exploits USE_SSL = {{ .Values.conf.horizon.local_settings.config.use_ssl }} CSRF_COOKIE_SECURE = {{ .Values.conf.horizon.local_settings.config.csrf_cookie_secure }} CSRF_COOKIE_HTTPONLY = {{ .Values.conf.horizon.local_settings.config.csrf_cookie_httponly }} SESSION_COOKIE_SECURE = {{ .Values.conf.horizon.local_settings.config.session_cookie_secure }} SESSION_COOKIE_HTTPONLY = {{ .Values.conf.horizon.local_settings.config.session_cookie_httponly }} # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins CSRF_TRUSTED_ORIGINS = [{{ include "helm-toolkit.utils.joinListWithCommaAndSingleQuotes" .Values.conf.horizon.local_settings.config.csrf_trusted_origins }}] # Overrides for OpenStack API versions. Use this setting to force the # OpenStack dashboard to use a specific API version for a given service API. # Versions specified here should be integers or floats, not strings. # NOTE: The version should be formatted as it appears in the URL for the # service API. For example, The identity service APIs have inconsistent # use of the decimal point, so valid options would be 2.0 or 3. #OPENSTACK_API_VERSIONS = { # "data-processing": 1.1, # "identity": 3, # "volume": 2, #} OPENSTACK_API_VERSIONS = { "identity": 3, "container-infra": "{{ .Values.conf.horizon.local_settings.config.openstack_api_versions.container_infra }}" } # Set this to True if running on multi-domain model. When this is enabled, it # will require user to enter the Domain name in addition to username for login. OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = {{ .Values.conf.horizon.local_settings.config.keystone_multidomain_support }} OPENSTACK_KEYSTONE_DOMAIN_DROPDOWN = {{ .Values.conf.horizon.local_settings.config.keystone_multidomain_dropdown }} {{- $multiDomainDropdown := eq (lower .Values.conf.horizon.local_settings.config.keystone_multidomain_dropdown) "true" }} {{- if $multiDomainDropdown }} OPENSTACK_KEYSTONE_DOMAIN_CHOICES = ( {{- range $key, $label := .Values.conf.horizon.local_settings.config.keystone_domains }} ('{{ $key }}', _('{{ $label }}')), {{- end }} ) {{- end }} # Overrides the default domain used when running on single-domain model # with Keystone V3. All entities will be created in the default domain. OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = '{{ .Values.conf.horizon.local_settings.config.keystone_default_domain }}' # Set Console type: # valid options are "AUTO"(default), "VNC", "SPICE", "RDP", "SERIAL" or None # Set to None explicitly if you want to deactivate the console. #CONSOLE_TYPE = "AUTO" # Default OpenStack Dashboard configuration. HORIZON_CONFIG = { 'user_home': 'openstack_dashboard.views.get_user_home', 'ajax_queue_limit': 10, 'auto_fade_alerts': { 'delay': 3000, 'fade_duration': 1500, 'types': ['alert-success', 'alert-info'] }, 'help_url': "http://docs.openstack.org", 'exceptions': {'recoverable': exceptions.RECOVERABLE, 'not_found': exceptions.NOT_FOUND, 'unauthorized': exceptions.UNAUTHORIZED}, 'modal_backdrop': 'static', 'angular_modules': [], 'js_files': [], 'js_spec_files': [], } {{- if .Values.conf.horizon.local_settings.config.enable_pwd_validator }} # Specify a regular expression to validate user passwords. HORIZON_CONFIG["password_validator"] = { "regex": '{{ .Values.conf.horizon.local_settings.config.pwd_validator_regex }}', "help_text": {{ .Values.conf.horizon.local_settings.config.pwd_validator_help_text }}, } {{- end }} # Disable simplified floating IP address management for deployments with # multiple floating IP pools or complex network requirements. #HORIZON_CONFIG["simple_ip_management"] = False # Turn off browser autocompletion for forms including the login form and # the database creation workflow if so desired. HORIZON_CONFIG["password_autocomplete"] = '{{ .Values.conf.horizon.local_settings.config.password_autocomplete }}' # Setting this to True will disable the reveal button for password fields, # including on the login form. HORIZON_CONFIG["disable_password_reveal"] = {{ .Values.conf.horizon.local_settings.config.disable_password_reveal }} LOCAL_PATH = '/tmp' # Set custom secret key: # You can either set it to a specific value or you can let horizon generate a # default secret key that is unique on this machine, e.i. regardless of the # amount of Python WSGI workers (if used behind Apache+mod_wsgi): However, # there may be situations where you would want to set this explicitly, e.g. # when multiple dashboard instances are distributed on different machines # (usually behind a load-balancer). Either you have to make sure that a session # gets all requests routed to the same dashboard instance or you set the same # SECRET_KEY for all of them. SECRET_KEY='{{ .Values.conf.horizon.local_settings.config.horizon_secret_key }}' CACHES = { 'default': { 'BACKEND': '{{ .Values.conf.horizon.local_settings.config.cache_backend }}', 'LOCATION': '{{ tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }}', } } DATABASES = { 'default': { # Database configuration here 'ENGINE': 'django.db.backends.mysql', 'NAME': '{{ .Values.endpoints.oslo_db.path | base }}', 'USER': '{{ .Values.endpoints.oslo_db.auth.horizon.username }}', 'PASSWORD': '{{ .Values.endpoints.oslo_db.auth.horizon.password }}', 'HOST': '{{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }}', 'default-character-set': 'utf8', {{- if .Values.manifests.certificates }} 'OPTIONS':{ 'ssl': { 'ca': '/etc/mysql/certs/ca.crt', 'cert': '/etc/mysql/certs/tls.crt', 'key': '/etc/mysql/certs/tls.key' } }, {{- end }} 'PORT': '{{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}' } } SESSION_ENGINE = '{{ .Values.conf.horizon.local_settings.config.session_engine }}' # Send email to the console by default EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # Or send them to /dev/null #EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend' # Configure these for your outgoing email host #EMAIL_HOST = 'smtp.my-company.com' #EMAIL_PORT = 25\\ #EMAIL_HOST_USER = 'djangomail' #EMAIL_HOST_PASSWORD = 'top-secret!' # For multiple regions uncomment this configuration, and add (endpoint, title). #AVAILABLE_REGIONS = [ # ('http://cluster1.example.com:5000/v2.0', 'cluster1'), # ('http://cluster2.example.com:5000/v2.0', 'cluster2'), #] OPENSTACK_KEYSTONE_URL = "{{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }}" OPENSTACK_KEYSTONE_DEFAULT_ROLE = "member" # This setting specifies the name of the header with remote IP address. If not present, # then REMOTE_ADDR header is used. The commom value for this setting is HTTP_X_REAL_IP # or HTTP_X_FORWARDED_FORx SECURE_PROXY_ADDR_HEADER = 'HTTP_X_FORWARDED_FOR' {{- if .Values.conf.horizon.local_settings.config.auth.sso.enabled }} # Enables keystone web single-sign-on if set to True. WEBSSO_ENABLED = True # Determines which authentication choice to show as default. WEBSSO_INITIAL_CHOICE = "{{ .Values.conf.horizon.local_settings.config.auth.sso.initial_choice }}" {{- if .Values.conf.horizon.local_settings.config.auth.sso.websso_keystone_url }} # The full auth URL for the Keystone endpoint used for web single-sign-on authentication. WEBSSO_KEYSTONE_URL = "{{ .Values.conf.horizon.local_settings.config.auth.sso.websso_keystone_url }}" {{- end }} # The list of authentication mechanisms # which include keystone federation protocols. # Current supported protocol IDs are 'saml2' and 'oidc' # which represent SAML 2.0, OpenID Connect respectively. # Do not remove the mandatory credentials mechanism. WEBSSO_CHOICES = ( ("credentials", _("Keystone Credentials")), {{- range $i, $sso := .Values.conf.horizon.local_settings.config.auth.idp_mapping }} ({{ $sso.name | quote }}, {{ $sso.label | quote }}), {{- end }} ) WEBSSO_IDP_MAPPING = { {{- range $i, $sso := .Values.conf.horizon.local_settings.config.auth.idp_mapping }} {{ $sso.name | quote}}: ({{ $sso.idp | quote }}, {{ $sso.protocol | quote }}), {{- end }} } {{- end }} # Disable SSL certificate checks (useful for self-signed certificates): OPENSTACK_SSL_NO_VERIFY = {{ .Values.conf.horizon.local_settings.config.ssl_no_verify }} {{- if .Values.manifests.certificates }} # The CA certificate to use to verify SSL connections OPENSTACK_SSL_CACERT = '/etc/openstack-dashboard/certs/ca.crt' {{- end }} # The OPENSTACK_KEYSTONE_BACKEND settings can be used to identify the # capabilities of the auth backend for Keystone. # If Keystone has been configured to use LDAP as the auth backend then set # can_edit_user to False and name to 'ldap'. # # TODO(tres): Remove these once Keystone has an API to identify auth backend. OPENSTACK_KEYSTONE_BACKEND = { 'name': 'native', 'can_edit_user': True, 'can_edit_group': True, 'can_edit_project': True, 'can_edit_domain': True, 'can_edit_role': True, } # Setting this to True, will add a new "Retrieve Password" action on instance, # allowing Admin session password retrieval/decryption. OPENSTACK_ENABLE_PASSWORD_RETRIEVE = {{ .Values.conf.horizon.local_settings.config.openstack_enable_password_retrieve }} # Controls whether the keystone openrc file is accessible from the user menu and the api access panel. SHOW_OPENRC_FILE = {{ .Values.conf.horizon.local_settings.config.show_openrc_file }} # The Launch Instance user experience has been significantly enhanced. # You can choose whether to enable the new launch instance experience, # the legacy experience, or both. The legacy experience will be removed # in a future release, but is available as a temporary backup setting to ensure # compatibility with existing deployments. Further development will not be # done on the legacy experience. Please report any problems with the new # experience via the StoryBoard tracking system. # # Toggle LAUNCH_INSTANCE_LEGACY_ENABLED and LAUNCH_INSTANCE_NG_ENABLED to # determine the experience to enable. Set them both to true to enable # both. #LAUNCH_INSTANCE_LEGACY_ENABLED = True #LAUNCH_INSTANCE_NG_ENABLED = False # The Xen Hypervisor has the ability to set the mount point for volumes # attached to instances (other Hypervisors currently do not). Setting # can_set_mount_point to True will add the option to set the mount point # from the UI. OPENSTACK_HYPERVISOR_FEATURES = { 'can_set_mount_point': False, 'can_set_password': False, } # The OPENSTACK_CINDER_FEATURES settings can be used to enable optional # services provided by cinder that is not exposed by its extension API. OPENSTACK_CINDER_FEATURES = { 'enable_backup': {{ .Values.conf.horizon.local_settings.config.openstack_cinder_features.enable_backup }}, } # The OPENSTACK_NEUTRON_NETWORK settings can be used to enable optional # services provided by neutron. Options currently available are load # balancer service, security groups, quotas, VPN service. OPENSTACK_NEUTRON_NETWORK = { 'enable_router': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_router }}, 'enable_quotas': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_quotas }}, 'enable_ipv6': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_ipv6 }}, 'enable_distributed_router': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_distributed_router }}, 'enable_ha_router': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_ha_router }}, 'enable_lb': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_lb }}, 'enable_firewall': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_firewall }}, 'enable_vpn': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_vpn }}, 'enable_fip_topology_check': {{ .Values.conf.horizon.local_settings.config.openstack_neutron_network.enable_fip_topology_check }}, # The profile_support option is used to detect if an external router can be # configured via the dashboard. When using specific plugins the # profile_support can be turned on if needed. 'profile_support': None, #'profile_support': 'cisco', # Set which provider network types are supported. Only the network types # in this list will be available to choose from when creating a network. # Network types include local, flat, vlan, gre, and vxlan. 'supported_provider_types': ['*'], # Set which VNIC types are supported for port binding. Only the VNIC # types in this list will be available to choose from when creating a # port. # VNIC types include 'normal', 'macvtap' and 'direct'. 'supported_vnic_types': ['*'] } # The OPENSTACK_IMAGE_BACKEND settings can be used to customize features # in the OpenStack Dashboard related to the Image service, such as the list # of supported image formats. #OPENSTACK_IMAGE_BACKEND = { # 'image_formats': [ # ('', _('Select format')), # ('aki', _('AKI - Amazon Kernel Image')), # ('ami', _('AMI - Amazon Machine Image')), # ('ari', _('ARI - Amazon Ramdisk Image')), # ('docker', _('Docker')), # ('iso', _('ISO - Optical Disk Image')), # ('ova', _('OVA - Open Virtual Appliance')), # ('qcow2', _('QCOW2 - QEMU Emulator')), # ('raw', _('Raw')), # ('vdi', _('VDI - Virtual Disk Image')), # ('vhd', ('VHD - Virtual Hard Disk')), # ('vmdk', _('VMDK - Virtual Machine Disk')), # ] #} # The IMAGE_CUSTOM_PROPERTY_TITLES settings is used to customize the titles for # image custom property attributes that appear on image detail pages. IMAGE_CUSTOM_PROPERTY_TITLES = { "architecture": _("Architecture"), "kernel_id": _("Kernel ID"), "ramdisk_id": _("Ramdisk ID"), "image_state": _("Euca2ools state"), "project_id": _("Project ID"), "image_type": _("Image Type"), } # The IMAGE_RESERVED_CUSTOM_PROPERTIES setting is used to specify which image # custom properties should not be displayed in the Image Custom Properties # table. IMAGE_RESERVED_CUSTOM_PROPERTIES = [] # Set to 'legacy' or 'direct' to allow users to upload images to glance via # Horizon server. When enabled, a file form field will appear on the create # image form. If set to 'off', there will be no file form field on the create # image form. See documentation for deployment considerations. HORIZON_IMAGES_UPLOAD_MODE = '{{ .Values.conf.horizon.local_settings.config.horizon_images_upload_mode }}' # OPENSTACK_ENDPOINT_TYPE specifies the endpoint type to use for the endpoints # in the Keystone service catalog. Use this setting when Horizon is running # external to the OpenStack environment. The default is 'publicURL'. OPENSTACK_ENDPOINT_TYPE = "{{ .Values.conf.horizon.local_settings.config.endpoint_type }}" # SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the # case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints # in the Keystone service catalog. Use this setting when Horizon is running # external to the OpenStack environment. The default is None. This # value should differ from OPENSTACK_ENDPOINT_TYPE if used. SECONDARY_ENDPOINT_TYPE = "publicURL" # The number of objects (Swift containers/objects or images) to display # on a single page before providing a paging element (a "more" link) # to paginate results. API_RESULT_LIMIT = 1000 API_RESULT_PAGE_SIZE = 20 # The size of chunk in bytes for downloading objects from Swift SWIFT_FILE_TRANSFER_CHUNK_SIZE = 512 * 1024 # Specify a maximum number of items to display in a dropdown. DROPDOWN_MAX_ITEMS = 30 # The timezone of the server. This should correspond with the timezone # of your entire OpenStack installation, and hopefully be in UTC. TIME_ZONE = "UTC" # When launching an instance, the menu of available flavors is # sorted by RAM usage, ascending. If you would like a different sort order, # you can provide another flavor attribute as sorting key. Alternatively, you # can provide a custom callback method to use for sorting. You can also provide # a flag for reverse sort. For more info, see # http://docs.python.org/2/library/functions.html#sorted #CREATE_INSTANCE_FLAVOR_SORT = { # 'key': 'name', # # or # 'key': my_awesome_callback_method, # 'reverse': False, #} # Set this to True to display an 'Admin Password' field on the Change Password # form to verify that it is indeed the admin logged-in who wants to change # the password. ENFORCE_PASSWORD_CHECK = {{ .Values.conf.horizon.local_settings.config.enforce_password_check }} # Modules that provide /auth routes that can be used to handle different types # of user authentication. Add auth plugins that require extra route handling to # this list. #AUTHENTICATION_URLS = [ # 'openstack_auth.urls', #] # The Horizon Policy Enforcement engine uses these values to load per service # policy rule files. The content of these files should match the files the # OpenStack services are using to determine role based access control in the # target installation. # Path to directory containing policy.yaml files POLICY_FILES_PATH = '/etc/openstack-dashboard' # Map of local copy of service policy files #POLICY_FILES = { # 'identity': 'keystone_policy.yaml', # 'compute': 'nova_policy.yaml', # 'volume': 'cinder_policy.yaml', # 'image': 'glance_policy.yaml', # 'orchestration': 'heat_policy.yaml', # 'network': 'neutron_policy.yaml', #} # Trove user and database extension support. By default support for # creating users and databases on database instances is turned on. # To disable these extensions set the permission here to something # unusable such as ["!"]. # TROVE_ADD_USER_PERMS = [] # TROVE_ADD_DATABASE_PERMS = [] # Change this patch to the appropriate static directory containing # two files: _variables.scss and _styles.scss #CUSTOM_THEME_PATH = 'static/themes/default' LOGGING = { 'version': 1, # When set to True this will disable all logging except # for loggers specified in this configuration dictionary. Note that # if nothing is specified here and disable_existing_loggers is True, # django.db.backends will still log unless it is disabled explicitly. 'disable_existing_loggers': False, 'handlers': { 'null': { 'level': 'DEBUG', 'class': 'logging.NullHandler', }, 'console': { # Set the level to "DEBUG" for verbose output logging. 'level': 'INFO', 'class': 'logging.StreamHandler', }, }, 'loggers': { # Logging from django.db.backends is VERY verbose, send to null # by default. 'django.db.backends': { 'handlers': ['null'], 'propagate': False, }, 'requests': { 'handlers': ['null'], 'propagate': False, }, 'horizon': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'openstack_dashboard': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'novaclient': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'cinderclient': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'glanceclient': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'neutronclient': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'heatclient': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'troveclient': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'swiftclient': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'openstack_auth': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'nose.plugins.manager': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'django': { 'handlers': ['console'], 'level': '{{ .Values.conf.horizon.local_settings.config.log_level }}', 'propagate': False, }, 'iso8601': { 'handlers': ['null'], 'propagate': False, }, 'scss': { 'handlers': ['null'], 'propagate': False, }, } } # 'direction' should not be specified for all_tcp/udp/icmp. # It is specified in the form. SECURITY_GROUP_RULES = { 'all_tcp': { 'name': _('All TCP'), 'ip_protocol': 'tcp', 'from_port': '1', 'to_port': '65535', }, 'all_udp': { 'name': _('All UDP'), 'ip_protocol': 'udp', 'from_port': '1', 'to_port': '65535', }, 'all_icmp': { 'name': _('All ICMP'), 'ip_protocol': 'icmp', 'from_port': '-1', 'to_port': '-1', }, 'ssh': { 'name': 'SSH', 'ip_protocol': 'tcp', 'from_port': '22', 'to_port': '22', }, 'smtp': { 'name': 'SMTP', 'ip_protocol': 'tcp', 'from_port': '25', 'to_port': '25', }, 'dns': { 'name': 'DNS', 'ip_protocol': 'tcp', 'from_port': '53', 'to_port': '53', }, 'http': { 'name': 'HTTP', 'ip_protocol': 'tcp', 'from_port': '80', 'to_port': '80', }, 'pop3': { 'name': 'POP3', 'ip_protocol': 'tcp', 'from_port': '110', 'to_port': '110', }, 'imap': { 'name': 'IMAP', 'ip_protocol': 'tcp', 'from_port': '143', 'to_port': '143', }, 'ldap': { 'name': 'LDAP', 'ip_protocol': 'tcp', 'from_port': '389', 'to_port': '389', }, 'https': { 'name': 'HTTPS', 'ip_protocol': 'tcp', 'from_port': '443', 'to_port': '443', }, 'smtps': { 'name': 'SMTPS', 'ip_protocol': 'tcp', 'from_port': '465', 'to_port': '465', }, 'imaps': { 'name': 'IMAPS', 'ip_protocol': 'tcp', 'from_port': '993', 'to_port': '993', }, 'pop3s': { 'name': 'POP3S', 'ip_protocol': 'tcp', 'from_port': '995', 'to_port': '995', }, 'ms_sql': { 'name': 'MS SQL', 'ip_protocol': 'tcp', 'from_port': '1433', 'to_port': '1433', }, 'mysql': { 'name': 'MYSQL', 'ip_protocol': 'tcp', 'from_port': '3306', 'to_port': '3306', }, 'rdp': { 'name': 'RDP', 'ip_protocol': 'tcp', 'from_port': '3389', 'to_port': '3389', }, } # Deprecation Notice: # # The setting FLAVOR_EXTRA_KEYS has been deprecated. # Please load extra spec metadata into the Glance Metadata Definition Catalog. # # The sample quota definitions can be found in: # /etc/metadefs/compute-quota.json # # The metadata definition catalog supports CLI and API: # $glance --os-image-api-version 2 help md-namespace-import # $glance-manage db_load_metadefs # # See Metadata Definitions on: https://docs.openstack.org/glance/latest/ # Indicate to the Sahara data processing service whether or not # automatic floating IP allocation is in effect. If it is not # in effect, the user will be prompted to choose a floating IP # pool for use in their cluster. False by default. You would want # to set this to True if you were running Nova Networking with # auto_assign_floating_ip = True. #SAHARA_AUTO_IP_ALLOCATION_ENABLED = False # The hash algorithm to use for authentication tokens. This must # match the hash algorithm that the identity server and the # auth_token middleware are using. Allowed values are the # algorithms supported by Python's hashlib library. #OPENSTACK_TOKEN_HASH_ALGORITHM = 'md5' # AngularJS requires some settings to be made available to # the client side. Some settings are required by in-tree / built-in horizon # features. These settings must be added to REST_API_REQUIRED_SETTINGS in the # form of ['SETTING_1','SETTING_2'], etc. # # You may remove settings from this list for security purposes, but do so at # the risk of breaking a built-in horizon feature. These settings are required # for horizon to function properly. Only remove them if you know what you # are doing. These settings may in the future be moved to be defined within # the enabled panel configuration. # You should not add settings to this list for out of tree extensions. # See: https://wiki.openstack.org/wiki/Horizon/RESTAPI REST_API_REQUIRED_SETTINGS = ['OPENSTACK_HYPERVISOR_FEATURES', 'LAUNCH_INSTANCE_DEFAULTS', 'OPENSTACK_IMAGE_FORMATS'] # Additional settings can be made available to the client side for # extensibility by specifying them in REST_API_ADDITIONAL_SETTINGS # !! Please use extreme caution as the settings are transferred via HTTP/S # and are not encrypted on the browser. This is an experimental API and # may be deprecated in the future without notice. #REST_API_ADDITIONAL_SETTINGS = [] # DISALLOW_IFRAME_EMBED can be used to prevent Horizon from being embedded # within an iframe. Legacy browsers are still vulnerable to a Cross-Frame # Scripting (XFS) vulnerability, so this option allows extra security hardening # where iframes are not used in deployment. Default setting is True. # For more information see: # http://tinyurl.com/anticlickjack DISALLOW_IFRAME_EMBED = {{ .Values.conf.horizon.local_settings.config.disallow_iframe_embed }} STATIC_ROOT = '/var/www/html/horizon' {{- range $option, $value := .Values.conf.horizon.local_settings.config.raw }} {{ $option }} = {{ toJson $value }} {{- end }} policy: ceilometer: context_is_admin: 'role:admin' context_is_owner: 'user_id:%(target.user_id)s' context_is_project: 'project_id:%(target.project_id)s' segregation: 'rule:context_is_admin' heat: 'actions:action': 'rule:deny_stack_user' 'build_info:build_info': 'rule:deny_stack_user' 'cloudformation:CancelUpdateStack': 'rule:deny_stack_user' 'cloudformation:CreateStack': 'rule:deny_stack_user' 'cloudformation:DeleteStack': 'rule:deny_stack_user' 'cloudformation:DescribeStackEvents': 'rule:deny_stack_user' 'cloudformation:DescribeStackResource': '' 'cloudformation:DescribeStackResources': 'rule:deny_stack_user' 'cloudformation:DescribeStacks': 'rule:deny_stack_user' 'cloudformation:EstimateTemplateCost': 'rule:deny_stack_user' 'cloudformation:GetTemplate': 'rule:deny_stack_user' 'cloudformation:ListStackResources': 'rule:deny_stack_user' 'cloudformation:ListStacks': 'rule:deny_stack_user' 'cloudformation:UpdateStack': 'rule:deny_stack_user' 'cloudformation:ValidateTemplate': 'rule:deny_stack_user' context_is_admin: 'role:admin' deny_everybody: '!' deny_stack_user: 'not role:heat_stack_user' 'events:index': 'rule:deny_stack_user' 'events:show': 'rule:deny_stack_user' 'resource:index': 'rule:deny_stack_user' 'resource:mark_unhealthy': 'rule:deny_stack_user' 'resource:metadata': '' 'resource:show': 'rule:deny_stack_user' 'resource:signal': '' 'resource_types:OS::Cinder::EncryptedVolumeType': 'rule:context_is_admin' 'resource_types:OS::Cinder::VolumeType': 'rule:context_is_admin' 'resource_types:OS::Manila::ShareType': 'rule:context_is_admin' 'resource_types:OS::Neutron::QoSBandwidthLimitRule': 'rule:context_is_admin' 'resource_types:OS::Neutron::QoSPolicy': 'rule:context_is_admin' 'resource_types:OS::Nova::Flavor': 'rule:context_is_admin' 'resource_types:OS::Nova::HostAggregate': 'rule:context_is_admin' 'service:index': 'rule:context_is_admin' 'software_configs:create': 'rule:deny_stack_user' 'software_configs:delete': 'rule:deny_stack_user' 'software_configs:global_index': 'rule:deny_everybody' 'software_configs:index': 'rule:deny_stack_user' 'software_configs:show': 'rule:deny_stack_user' 'software_deployments:create': 'rule:deny_stack_user' 'software_deployments:delete': 'rule:deny_stack_user' 'software_deployments:index': 'rule:deny_stack_user' 'software_deployments:metadata': '' 'software_deployments:show': 'rule:deny_stack_user' 'software_deployments:update': 'rule:deny_stack_user' 'stacks:abandon': 'rule:deny_stack_user' 'stacks:create': 'rule:deny_stack_user' 'stacks:delete': 'rule:deny_stack_user' 'stacks:delete_snapshot': 'rule:deny_stack_user' 'stacks:detail': 'rule:deny_stack_user' 'stacks:environment': 'rule:deny_stack_user' 'stacks:export': 'rule:deny_stack_user' 'stacks:generate_template': 'rule:deny_stack_user' 'stacks:global_index': 'rule:deny_everybody' 'stacks:index': 'rule:deny_stack_user' 'stacks:list_outputs': 'rule:deny_stack_user' 'stacks:list_resource_types': 'rule:deny_stack_user' 'stacks:list_snapshots': 'rule:deny_stack_user' 'stacks:list_template_functions': 'rule:deny_stack_user' 'stacks:list_template_versions': 'rule:deny_stack_user' 'stacks:lookup': '' 'stacks:preview': 'rule:deny_stack_user' 'stacks:preview_update': 'rule:deny_stack_user' 'stacks:preview_update_patch': 'rule:deny_stack_user' 'stacks:resource_schema': 'rule:deny_stack_user' 'stacks:restore_snapshot': 'rule:deny_stack_user' 'stacks:show': 'rule:deny_stack_user' 'stacks:show_output': 'rule:deny_stack_user' 'stacks:show_snapshot': 'rule:deny_stack_user' 'stacks:snapshot': 'rule:deny_stack_user' 'stacks:template': 'rule:deny_stack_user' 'stacks:update': 'rule:deny_stack_user' 'stacks:update_patch': 'rule:deny_stack_user' 'stacks:validate_template': 'rule:deny_stack_user' # list of panels to enable for horizon # this requires that the panels are already installed in the horizon image, if they are not # nothing will be added # the name of the panel should be the name of the dir where the panel is installed # for example heat_dashboard, cloudkittydashboard or neutron_taas_dashboard extra_panels: - heat_dashboard - neutron_taas_dashboard dependencies: dynamic: common: local_image_registry: jobs: - horizon-image-repo-sync services: - endpoint: node service: local_image_registry static: dashboard: jobs: - horizon-db-sync services: - endpoint: internal service: oslo_cache - endpoint: internal service: oslo_db - endpoint: internal service: identity db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - horizon-db-init services: - endpoint: internal service: oslo_db image_repo_sync: services: - endpoint: internal service: local_image_registry tests: services: - endpoint: internal service: dashboard pod: security_context: horizon: pod: runAsUser: 42424 container: horizon: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 0 db_sync: pod: runAsUser: 42424 container: horizon_db_sync: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 0 test: pod: runAsUser: 42424 container: horizon_test: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: horizon: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: horizon_db_init: init_container: null horizon_db_init: volumeMounts: volumes: horizon_db_sync: init_container: null horizon_db_sync: volumeMounts: volumes: horizon: init_container: null horizon: volumeMounts: volumes: horizon_tests: init_container: null horizon_tests: volumeMounts: volumes: replicas: server: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: horizon: min_available: 0 termination_grace_period: horizon: timeout: 30 resources: enabled: false server: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: horizon-keystone-admin oslo_db: admin: horizon-db-admin horizon: horizon-db-user tls: dashboard: dashboard: public: horizon-tls-public internal: horizon-tls-web oci_image_registry: horizon: horizon-oci-image-registry tls: identity: false # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false horizon: username: horizon password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 oslo_cache: hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 dashboard: name: horizon hosts: default: horizon-int public: horizon host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: http port: web: default: 80 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct horizon: username: horizon password: password hosts: default: mariadb host_fqdn_override: default: null path: /horizon scheme: mysql+pymysql port: mysql: default: 3306 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 network_policy: horizon: ingress: - {} egress: - {} manifests: certificates: false configmap_bin: true configmap_etc: true configmap_logo: false deployment: true ingress_api: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true pdb: true pod_helm_test: true network_policy: false secret_db: true secret_ingress_tls: true secret_keystone: true secret_registry: true service_ingress: true service: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ironic/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Ironic name: ironic version: 2025.2.0 home: https://docs.openstack.org/ironic/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Ironic/OpenStack_Project_Ironic_vertical.png sources: - https://opendev.org/openstack/ironic - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ironic/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ $source_base := .Values.bootstrap.image.source_base | default "" }} {{ range $name, $opts := .Values.bootstrap.image.structured }} {{ $source := empty $source_base | ternary $opts.source (printf "%s/%s" $source_base $opts.source) }} openstack image show {{ $name | quote }} -fvalue -cid || ( IMAGE_LOC=$(mktemp) curl --fail -sSL {{ $source }} -o ${IMAGE_LOC} openstack image create {{ $name | quote }} \ --disk-format {{ $opts.disk_format }} \ --container-format {{ $opts.container_format }} \ --file ${IMAGE_LOC} \ {{ if $opts.properties -}} {{ range $k, $v := $opts.properties }}--property {{$k}}={{$v}} {{ end }}{{ end -}} \ --{{ $opts.visibility | default "public" }} rm -f ${IMAGE_LOC} ) {{ else }} {{ .Values.bootstrap.image.script | default "echo 'Not Enabled'" }} {{ end }} ================================================ FILE: ironic/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # https://docs.openstack.org/ironic/latest/admin/upgrade-guide.html ironic-dbsync upgrade ironic-dbsync online_data_migrations echo 'Finished DB migrations' ================================================ FILE: ironic/templates/bin/_ironic-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/ironic/ironic-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: ironic/templates/bin/_ironic-conductor-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex if [ "x" == "x${PROVISIONER_INTERFACE}" ]; then echo "Provisioner interface is not set" exit 1 fi function net_pxe_addr { ip addr | awk "/inet / && /${PROVISIONER_INTERFACE}/{print \$2; exit }" } function net_pxe_ip { echo $(net_pxe_addr) | awk -F '/' '{ print $1; exit }' } PXE_IP=$(net_pxe_ip) if [ "x" == "x${PXE_IP}" ]; then echo "Could not find IP for pxe to bind to" exit 1 fi # ensure the tempdir exists, read it from the config ironictmpdir=$(python -c 'from configparser import ConfigParser;cfg = ConfigParser();cfg.read("/etc/ironic/ironic.conf");print(cfg.get("DEFAULT", "tempdir", fallback=""))') if [ -n "${ironictmpdir}" -a ! -d "${ironictmpdir}" ]; then mkdir -p "${ironictmpdir}" chmod 1777 "${ironictmpdir}" fi tee /tmp/pod-shared/conductor-local-ip.conf << EOF [DEFAULT] # IP address of this host. If unset, will determine the IP # programmatically. If unable to do so, will use "127.0.0.1". # (string value) my_ip = ${PXE_IP} [pxe] # IP address of ironic-conductor node's TFTP server. (string # value) tftp_server = ${PXE_IP} [deploy] # ironic-conductor node's HTTP server URL. Example: # http://192.1.2.3:8080 (string value) # from .deploy.ironic.http_url http_url = http://${PXE_IP}:{{ tuple "baremetal" "internal" "pxe_http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} EOF ================================================ FILE: ironic/templates/bin/_ironic-conductor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex mkdir -p /var/lib/openstack-helm/ironic/images mkdir -p /var/lib/openstack-helm/ironic/master_images {{- if and (.Values.bootstrap.object_store.enabled) (.Values.bootstrap.object_store.openstack.enabled) }} OPTIONS=" --config-file /tmp/pod-shared/swift.conf" {{- end }} exec ironic-conductor \ --config-file /etc/ironic/ironic.conf \ --config-file /tmp/pod-shared/conductor-local-ip.conf \ ${OPTIONS} \ --config-dir /etc/ironic/ironic.conf.d ================================================ FILE: ironic/templates/bin/_manage-cleaning-network.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex if ! openstack network show ${neutron_network_name}; then IRONIC_NEUTRON_CLEANING_NET_ID=$(openstack network create -f value -c id \ --share \ --provider-network-type flat \ --provider-physical-network ${neutron_provider_network} \ ${neutron_network_name}) else IRONIC_NEUTRON_CLEANING_NET_ID=$(openstack network show ${neutron_network_name} -f value -c id) fi SUBNETS=$(openstack network show $IRONIC_NEUTRON_CLEANING_NET_ID -f value -c subnets) if [ "x${SUBNETS}" != "x[]" ]; then for SUBNET in ${SUBNETS}; do CURRENT_SUBNET=$(openstack subnet show $SUBNET -f value -c name) if [ "x${CURRENT_SUBNET}" == "x${neutron_subnet_name}" ]; then openstack subnet show ${neutron_subnet_name} SUBNET_EXISTS=true fi done fi if [ "x${SUBNET_EXISTS}" != "xtrue" ]; then openstack subnet create \ --gateway ${neutron_subnet_gateway%/*} \ --allocation-pool start=${neutron_subnet_alloc_start},end=${neutron_subnet_alloc_end} \ --dns-nameserver ${neutron_subnet_dns_nameserver} \ --subnet-range ${neutron_subnet_cidr} \ --network ${neutron_network_name} \ ${neutron_subnet_name} fi ================================================ FILE: ironic/templates/bin/_retreive-swift-config.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex OS_SWIFT_ENDPOINT="$(openstack endpoint list \ --service swift \ --interface public \ -f value \ -c URL | head -1 )" OS_SWIFT_HOST_AND_PATH_PREFIX="$(echo "${OS_SWIFT_ENDPOINT}" | awk -F "/${OS_SWIFT_API_VERSION}" '{ print $1 }')" OS_SWIFT_ACCOUNT_PREFIX="$(echo "${OS_SWIFT_ENDPOINT}" | awk -F "/${OS_SWIFT_API_VERSION}/" '{ print $NF }' | awk -F '$' '{ print $1 }')" OS_PROJECT_ID="$(openstack project show ${OS_PROJECT_NAME} -f value -c id)" OS_SWIFT_ACCOUNT="$(echo "${OS_SWIFT_ACCOUNT_PREFIX}${OS_PROJECT_ID}")" tee /tmp/pod-shared/swift.conf < /tmp/pod-shared/nginx.conf script: | #!/bin/bash set -ex mkdir -p /var/lib/openstack-helm/httpboot cp -v /tmp/pod-shared/nginx.conf /etc/nginx/nginx.conf exec nginx -g 'daemon off;' pxe: enabled: true init_script: | #!/bin/bash set -ex # default to Ubuntu path FILEPATH=${FILEPATH:-/usr/lib/ipxe} mkdir -p /var/lib/openstack-helm/tftpboot mkdir -p /var/lib/openstack-helm/tftpboot/master_images for FILE in undionly.kpxe ipxe.efi pxelinux.0 snponly.efi; do # copy in default file if [ -f $FILEPATH/$FILE ]; then cp -v $FILEPATH/$FILE /var/lib/openstack-helm/tftpboot fi done script: | #!/bin/bash set -ex function net_pxe_addr { ip addr | awk "/inet / && /${PROVISIONER_INTERFACE}/{print \$2; exit }" } function net_pxe_ip { echo $(net_pxe_addr) | awk -F '/' '{ print $1; exit }' } PXE_IP=$(net_pxe_ip) if [ "x" == "x${PXE_IP}" ]; then echo "Could not find IP for pxe to bind to" exit 1 fi ln -s /var/lib/openstack-helm/tftpboot /tftpboot exec /usr/sbin/in.tftpd \ --verbose \ --foreground \ --user root \ --address ${PXE_IP}:69 \ --map-file /tftp-map-file /tftpboot network: pxe: device: ironic-pxe neutron_network_name: baremetal neutron_subnet_name: baremetal neutron_provider_network: ironic neutron_subnet_gateway: 172.24.6.1/24 neutron_subnet_cidr: 172.24.6.0/24 neutron_subnet_alloc_start: 172.24.6.100 neutron_subnet_alloc_end: 172.24.6.200 neutron_subnet_dns_nameserver: 10.96.0.10 api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30511 bootstrap: image: enabled: true openstack: enabled: true ks_user: ironic # NOTE: if source_base is null the source will be used as is source_base: http://tarballs.openstack.org/ironic-python-agent/tinyipa/files structured: ironic-agent.initramfs: source: tinyipa-stable-2025.1.gz disk_format: ari container_format: ari ironic-agent.kernel: source: tinyipa-stable-2025.1.vmlinuz disk_format: aki container_format: aki object_store: enabled: true openstack: enabled: true dependencies: dynamic: common: local_image_registry: jobs: - ironic-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - ironic-db-sync - ironic-ks-user - ironic-ks-endpoints - ironic-manage-cleaning-network - ironic-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging bootstrap: jobs: null services: - endpoint: internal service: identity - endpoint: internal service: image - endpoint: internal service: baremetal conductor: jobs: - ironic-db-sync - ironic-ks-user - ironic-ks-endpoints - ironic-manage-cleaning-network - ironic-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: baremetal - endpoint: internal service: oslo_messaging db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - ironic-db-init services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - ironic-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - endpoint: internal service: oslo_messaging manage_cleaning_network: services: - endpoint: internal service: network image_repo_sync: services: - endpoint: internal service: local_image_registry # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: ironic-keystone-admin ironic: ironic-keystone-user glance: ironic-glance-keystone-user oslo_db: admin: ironic-db-admin ironic: ironic-db-user oslo_messaging: admin: ironic-rabbitmq-admin ironic: ironic-rabbitmq-user oci_image_registry: ironic: ironic-oci-image-registry tls: baremetal: api: public: ironic-tls-public internal: ironic-tls-api # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ironic: username: ironic password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default glance: role: admin,service region_name: RegionOne username: glance password: password project_name: service user_domain_name: service project_domain_name: service ironic: role: admin,service region_name: RegionOne username: ironic password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 baremetal: name: ironic hosts: default: ironic-api public: ironic host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 6385 public: 80 pxe_http: default: 8080 volumev3: name: cinderv3 hosts: default: cinder-api public: cinder host_fqdn_override: default: null path: default: '/v3/%(tenant_id)s' healthcheck: /healthcheck scheme: default: http port: api: default: 8776 public: 80 compute: name: nova hosts: default: nova-api public: nova host_fqdn_override: default: null path: default: "/v2.1/%(tenant_id)s" scheme: default: 'http' port: api: default: 8774 public: 80 novncproxy: default: 6080 image: name: glance hosts: default: glance-api public: glance host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 9292 public: 80 oslo_db: auth: admin: username: root password: password ironic: username: ironic password: password hosts: default: mariadb host_fqdn_override: default: null path: /ironic scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 oslo_messaging: auth: admin: username: rabbitmq password: password ironic: username: ironic password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /ironic scheme: rabbit port: amqp: default: 5672 http: default: 15672 network: name: neutron hosts: default: neutron-server public: neutron host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9696 public: 80 object_store: name: swift namespace: ceph auth: glance: tmpurlkey: supersecret hosts: default: ceph-rgw host_fqdn_override: default: null path: default: /swift/v1/KEY_$(tenant_id)s scheme: default: http port: api: default: 8088 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: ironic: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: ironic_api: init_container: null ironic_api: volumeMounts: volumes: ironic_conductor: init_container: null ironic_conductor: volumeMounts: volumes: ironic_bootstrap: init_container: null ironic_bootstrap: volumeMounts: volumes: ironic_db_sync: ironic_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/ironic/ironic.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: ironic_api: [] ironic_conductor: [] ironic_db_sync: [] replicas: api: 1 conductor: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conductor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" useHostNetwork: conductor: true useHostIPC: conductor: false network_policy: ironic: ingress: - {} egress: - {} manifests: configmap_bin: true configmap_etc: true deployment_api: true ingress_api: true job_bootstrap: true job_db_drop: false job_db_init: true job_db_sync: true job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_manage_cleaning_network: true job_rabbit_init: true pdb_api: true network_policy: false secret_db: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_api: true service_ingress_api: true statefulset_conductor: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: keystone/.helmignore ================================================ values_overrides ================================================ FILE: keystone/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Keystone name: keystone version: 2025.2.0 home: https://docs.openstack.org/keystone/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Keystone/OpenStack_Project_Keystone_vertical.png sources: - https://opendev.org/openstack/keystone - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: keystone/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: keystone/templates/bin/_cred-clean.py.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} #!/usr/bin/python # Drops db and user for an OpenStack Service: # Set ROOT_DB_CONNECTION and DB_CONNECTION environment variables to contain # SQLAlchemy strings for the root connection to the database and the one you # wish the service to use. Alternatively, you can use an ini formatted config # at the location specified by OPENSTACK_CONFIG_FILE, and extract the string # from the key OPENSTACK_CONFIG_DB_KEY, in the section specified by # OPENSTACK_CONFIG_DB_SECTION. import os import sys try: import ConfigParser PARSER_OPTS = {} except ImportError: import configparser as ConfigParser PARSER_OPTS = {"strict": False} import logging from sqlalchemy import create_engine from sqlalchemy import text # Create logger, console handler and formatter logger = logging.getLogger('OpenStack-Helm DB Drop') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) # Get the connection string for the service db root user if "ROOT_DB_CONNECTION" in os.environ: db_connection = os.environ['ROOT_DB_CONNECTION'] logger.info('Got DB root connection') else: logger.critical('environment variable ROOT_DB_CONNECTION not set') sys.exit(1) mysql_x509 = os.getenv('MARIADB_X509', "") ssl_args = {} if mysql_x509: ssl_args = {'ssl': {'ca': '/etc/mysql/certs/ca.crt', 'key': '/etc/mysql/certs/tls.key', 'cert': '/etc/mysql/certs/tls.crt'}} # Get the connection string for the service db if "OPENSTACK_CONFIG_FILE" in os.environ: os_conf = os.environ['OPENSTACK_CONFIG_FILE'] if "OPENSTACK_CONFIG_DB_SECTION" in os.environ: os_conf_section = os.environ['OPENSTACK_CONFIG_DB_SECTION'] else: logger.critical( 'environment variable OPENSTACK_CONFIG_DB_SECTION not set') sys.exit(1) if "OPENSTACK_CONFIG_DB_KEY" in os.environ: os_conf_key = os.environ['OPENSTACK_CONFIG_DB_KEY'] else: logger.critical('environment variable OPENSTACK_CONFIG_DB_KEY not set') sys.exit(1) try: config = ConfigParser.RawConfigParser(**PARSER_OPTS) logger.info("Using {0} as db config source".format(os_conf)) config.read(os_conf) logger.info("Trying to load db config from {0}:{1}".format( os_conf_section, os_conf_key)) user_db_conn = config.get(os_conf_section, os_conf_key) logger.info("Got config from {0}".format(os_conf)) except: logger.critical( "Tried to load config from {0} but failed.".format(os_conf)) raise elif "DB_CONNECTION" in os.environ: user_db_conn = os.environ['DB_CONNECTION'] logger.info('Got config from DB_CONNECTION env var') else: logger.critical( 'Could not get db config, either from config file or env var') sys.exit(1) # Root DB engine try: root_engine_full = create_engine(db_connection) root_user = root_engine_full.url.username root_password = root_engine_full.url.password drivername = root_engine_full.url.drivername host = root_engine_full.url.host port = root_engine_full.url.port root_engine_url = ''.join([drivername, '://', root_user, ':', root_password, '@', host, ':', str(port)]) root_engine = create_engine(root_engine_url, connect_args=ssl_args) connection = root_engine.connect() connection.close() logger.info("Tested connection to DB @ {0}:{1} as {2}".format( host, port, root_user)) except: logger.critical('Could not connect to database as root user') raise # User DB engine try: user_engine = create_engine(user_db_conn, connect_args=ssl_args) # Get our user data out of the user_engine database = user_engine.url.database user = user_engine.url.username password = user_engine.url.password logger.info('Got user db config') except: logger.critical('Could not get user database config') raise # Delete all entries from credential table try: cmd = text("DELETE FROM credential") with user_engine.connect() as connection: connection.execute(cmd) try: connection.commit() except AttributeError: pass logger.info('Deleted all entries in credential table') except: logger.critical('Failed to clean up credential table in keystone db') raise logger.info('Finished DB Management') ================================================ FILE: keystone/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex keystone-manage \ --config-file=/etc/keystone/keystone.conf \ --config-dir=/etc/keystone/keystone.conf.d \ db_sync keystone-manage \ --config-file=/etc/keystone/keystone.conf \ --config-dir=/etc/keystone/keystone.conf.d \ bootstrap \ --bootstrap-username ${OS_USERNAME} \ --bootstrap-password ${OS_PASSWORD} \ --bootstrap-project-name ${OS_PROJECT_NAME} \ --bootstrap-admin-url ${OS_BOOTSTRAP_ADMIN_URL} \ --bootstrap-public-url ${OS_BOOTSTRAP_PUBLIC_URL} \ --bootstrap-internal-url ${OS_BOOTSTRAP_INTERNAL_URL} \ --bootstrap-region-id ${OS_REGION_NAME} ================================================ FILE: keystone/templates/bin/_domain-manage-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- range $k, $v := .Values.conf.ks_domains }} openstack --debug domain create --or-show {{ $k }} {{- end }} ================================================ FILE: keystone/templates/bin/_domain-manage.py.tpl ================================================ #!/usr/bin/python {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} import json import os import requests import sys def main(args): base_url, token, domainId, filename = args[1], args[2], args[3], args[5] url = "%s/domains/%s/config" % (base_url, domainId) print("Connecting to url: %r" % url) headers = { 'Content-Type': "application/json", 'X-Auth-Token': token, 'Cache-Control': "no-cache" } verify = os.getenv('OS_CACERT', True) response = requests.request("GET", url, headers=headers, verify=verify) if response.status_code == 404: print("domain config not found - put") action = "PUT" else: print("domain config found - patch") action = "PATCH" with open(filename, "rb") as f: data = {"config": json.load(f)} response = requests.request(action, url, data=json.dumps(data), headers=headers, verify=verify) print("Response code on action [%s]: %s" % (action, response.status_code)) # Put and Patch can return 200 or 201. If it is not a 2XX code, error out. if (response.status_code // 100) != 2: sys.exit(1) if __name__ == "__main__": if len(sys.argv) != 6: sys.exit(1) main(sys.argv) ================================================ FILE: keystone/templates/bin/_domain-manage.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e endpt={{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} path={{ .Values.conf.keystone.identity.domain_config_dir | default "/etc/keystone/domains" }} {{- range $k, $v := .Values.conf.ks_domains }} filename=${path}/keystone.{{ $k }}.json python /tmp/domain-manage.py \ $endpt \ $(openstack token issue -f value -c id) \ $(openstack domain show {{ $k }} -f value -c id) \ {{ $k }} $filename {{- end }} ================================================ FILE: keystone/templates/bin/_fernet-manage.py.tpl ================================================ #!/usr/bin/env python {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} import argparse import base64 import errno import grp import logging import os import pwd import re import subprocess #nosec import sys import time import requests FERNET_DIR = os.environ['KEYSTONE_KEYS_REPOSITORY'] KEYSTONE_USER = os.environ['KEYSTONE_USER'] KEYSTONE_GROUP = os.environ['KEYSTONE_GROUP'] NAMESPACE = os.environ['KUBERNETES_NAMESPACE'] # k8s connection data KUBE_HOST = None KUBE_CERT = '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt' KUBE_TOKEN = None LOG_DATEFMT = "%Y-%m-%d %H:%M:%S" LOG_FORMAT = "%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s" logging.basicConfig(format=LOG_FORMAT, datefmt=LOG_DATEFMT) LOG = logging.getLogger(__name__) LOG.setLevel(logging.INFO) def read_kube_config(): global KUBE_HOST, KUBE_TOKEN KUBE_HOST = "https://%s:%s" % ('kubernetes.default', os.environ['KUBERNETES_SERVICE_PORT']) with open('/var/run/secrets/kubernetes.io/serviceaccount/token', 'r') as f: KUBE_TOKEN = f.read() def get_secret_definition(name): url = '%s/api/v1/namespaces/%s/secrets/%s' % (KUBE_HOST, NAMESPACE, name) resp = requests.get(url, headers={'Authorization': 'Bearer %s' % KUBE_TOKEN}, verify=KUBE_CERT) if resp.status_code != 200: LOG.error('Cannot get secret %s.', name) LOG.error(resp.text) return None return resp.json() def update_secret(name, secret): url = '%s/api/v1/namespaces/%s/secrets/%s' % (KUBE_HOST, NAMESPACE, name) resp = requests.put(url, json=secret, headers={'Authorization': 'Bearer %s' % KUBE_TOKEN}, verify=KUBE_CERT) if resp.status_code != 200: LOG.error('Cannot update secret %s.', name) LOG.error(resp.text) return False return True def read_from_files(): keys = [name for name in os.listdir(FERNET_DIR) if os.path.isfile(FERNET_DIR + name) and re.match("^\d+$", name)] data = {} for key in keys: with open(FERNET_DIR + key, 'r') as f: data[key] = f.read() if len(list(keys)): LOG.debug("Keys read from files: %s", keys) else: LOG.warning("No keys were read from files.") return data def get_keys_data(): keys = read_from_files() return dict([(key, base64.b64encode(value.encode()).decode()) for (key, value) in keys.items()]) def write_to_files(data): if not os.path.exists(os.path.dirname(FERNET_DIR)): try: os.makedirs(os.path.dirname(FERNET_DIR)) except OSError as exc: # Guard against race condition if exc.errno != errno.EEXIST: raise uid = pwd.getpwnam(KEYSTONE_USER).pw_uid gid = grp.getgrnam(KEYSTONE_GROUP).gr_gid os.chown(FERNET_DIR, uid, gid) for (key, value) in data.items(): with open(FERNET_DIR + key, 'w') as f: decoded_value = base64.b64decode(value).decode() f.write(decoded_value) LOG.debug("Key %s: %s", key, decoded_value) LOG.info("%s keys were written", len(data)) def execute_command(cmd): LOG.info("Executing 'keystone-manage %s --keystone-user=%s " "--keystone-group=%s' command.", cmd, KEYSTONE_USER, KEYSTONE_GROUP) subprocess.call(['keystone-manage', cmd, #nosec '--keystone-user=%s' % KEYSTONE_USER, '--keystone-group=%s' % KEYSTONE_GROUP]) def main(): parser = argparse.ArgumentParser() parser.add_argument('command', choices=['fernet_setup', 'fernet_rotate', 'credential_setup', 'credential_rotate']) args = parser.parse_args() is_credential = args.command.startswith('credential') SECRET_NAME = ('keystone-credential-keys' if is_credential else 'keystone-fernet-keys') read_kube_config() secret = get_secret_definition(SECRET_NAME) if not secret: LOG.error("Secret '%s' does not exist.", SECRET_NAME) sys.exit(1) if args.command in ('fernet_rotate', 'credential_rotate'): LOG.info("Copying existing %s keys from secret '%s' to %s.", 'credential' if is_credential else 'fernet', SECRET_NAME, FERNET_DIR) write_to_files(secret['data']) if args.command in ('credential_setup', 'fernet_setup'): if secret.get('data', False): LOG.info('Keys already exist, skipping setup...') sys.exit(0) execute_command(args.command) LOG.info("Updating data for '%s' secret.", SECRET_NAME) updated_keys = get_keys_data() secret['data'] = updated_keys if not update_secret(SECRET_NAME, secret): sys.exit(1) LOG.info("%s fernet keys have been placed to secret '%s'", len(updated_keys), SECRET_NAME) LOG.debug("Placed keys: %s", updated_keys) LOG.info("%s keys %s has been completed", "Credential" if is_credential else 'Fernet', "rotation" if args.command.endswith('_rotate') else "generation") if args.command == 'credential_rotate': # `credential_rotate` needs doing `credential_migrate` as well once all # of the nodes have the new keys. So we'll sleep configurable amount of # time to make sure k8s reloads the secrets in all pods and then # execute `credential_migrate`. migrate_wait = int(os.getenv('KEYSTONE_CREDENTIAL_MIGRATE_WAIT', "60")) LOG.info("Waiting %d seconds to execute `credential_migrate`.", migrate_wait) time.sleep(migrate_wait) execute_command('credential_migrate') if __name__ == "__main__": main() ================================================ FILE: keystone/templates/bin/_keystone-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars fi if [ -f /var/run/apache2/apache2.pid ]; then # Remove the stale pid for debian/ubuntu images rm -f /var/run/apache2/apache2.pid fi # Start Apache2 exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} } function stop () { if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop } $COMMAND ================================================ FILE: keystone/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal -}} {{ dict "envAll" . "service" "identity" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: keystone/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: keystone-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} cred-clean.py: | {{ tuple "bin/_cred-clean.py.tpl" . | include "helm-toolkit.utils.template" |indent 4}} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_script "key" "wsgi.py" "format" "ConfigMap" ) | indent 2 }} keystone-api.sh: | {{ tuple "bin/_keystone-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} fernet-manage.py: | {{ tuple "bin/_fernet-manage.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} domain-manage-init.sh: | {{ tuple "bin/_domain-manage-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} domain-manage.sh: | {{ tuple "bin/_domain-manage.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} domain-manage.py: | {{ tuple "bin/_domain-manage.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: keystone/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if and (not (kindIs "invalid" .Values.conf.keystone.database.connection)) (empty .Values.conf.keystone.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "keystone" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if and .Values.manifests.certificates .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.keystone.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.keystone.database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.keystone.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "keystone" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.keystone.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.keystone.cache.memcache_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.keystone.cache "memcache_servers" -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .deployment_name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: keystone-etc type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} keystone.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.keystone | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.logging | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} access_rules.json: {{ toJson .Values.conf.access_rules | b64enc }} ports.conf: '' {{- range $k, $v := .Values.conf.ks_domains }} keystone.{{ $k }}.json: {{ toJson $v | b64enc }} {{- end }} {{- if .Values.conf.security }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.security "key" "security.conf" "format" "Secret" ) | indent 2 }} {{- end}} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.mpm_event "key" "mpm_event.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_keystone "key" "wsgi-keystone.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.sso_callback_template "key" "sso_callback_template.html" "format" "Secret" ) | indent 2 }} {{- end }} ================================================ FILE: keystone/templates/cron-job-credential-rotate.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_credential_rotate }} {{- $envAll := . }} {{- $mounts_keystone_credential_rotate := .Values.pod.mounts.keystone_credential_rotate.keystone_credential_rotate }} {{- $mounts_keystone_credential_rotate_init := .Values.pod.mounts.keystone_credential_rotate.init_container }} {{- $serviceAccountName := "keystone-credential-rotate" }} {{ tuple $envAll "credential_rotate" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.keystone_credential_rotate }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - list - create - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: CronJob metadata: name: keystone-credential-rotate annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.credential_rotate.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.credential_rotate.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.credential_rotate.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "keystone" "credential-rotate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "keystone" "credential-rotate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ tuple "keystone_credential_rotate" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "keystone_credential_rotate" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "credential_rotate" $mounts_keystone_credential_rotate_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.keystone.enabled }} {{ tuple $envAll "keystone" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} containers: - name: keystone-credential-rotate {{ tuple $envAll "keystone_credential_rotate" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.credential_rotate | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} env: - name: KEYSTONE_USER value: {{ .Values.jobs.credential_rotate.user | quote }} - name: KEYSTONE_GROUP value: {{ .Values.jobs.credential_rotate.group | quote }} - name: KUBERNETES_NAMESPACE value: {{ .Release.Namespace | quote }} - name: KEYSTONE_KEYS_REPOSITORY value: {{ .Values.conf.keystone.credential.key_repository | quote }} - name: KEYSTONE_CREDENTIAL_MIGRATE_WAIT value: {{ .Values.jobs.credential_rotate.migrate_wait | quote }} command: - python - /tmp/fernet-manage.py - credential_rotate volumeMounts: - name: pod-tmp mountPath: /tmp - name: etckeystone mountPath: /etc/keystone - name: keystone-etc mountPath: /etc/keystone/keystone.conf subPath: keystone.conf readOnly: true - name: keystone-etc-snippets mountPath: /etc/keystone/keystone.conf.d/ readOnly: true {{- if .Values.conf.keystone.DEFAULT.log_config_append }} - name: keystone-etc mountPath: {{ .Values.conf.keystone.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.keystone.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: keystone-bin mountPath: /tmp/fernet-manage.py subPath: fernet-manage.py readOnly: true {{ if $mounts_keystone_credential_rotate.volumeMounts }}{{ toYaml $mounts_keystone_credential_rotate.volumeMounts | indent 16 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etckeystone emptyDir: {} - name: keystone-etc secret: secretName: keystone-etc defaultMode: 0444 - name: keystone-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} - name: keystone-bin configMap: name: keystone-bin defaultMode: 0555 {{ if $mounts_keystone_credential_rotate.volumes }}{{ toYaml $mounts_keystone_credential_rotate.volumes | indent 12 }}{{ end }} {{- end }} ================================================ FILE: keystone/templates/cron-job-fernet-rotate.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_fernet_rotate }} {{- if eq .Values.conf.keystone.token.provider "fernet" }} {{- $envAll := . }} {{- $mounts_keystone_fernet_rotate := .Values.pod.mounts.keystone_fernet_rotate.keystone_fernet_rotate }} {{- $mounts_keystone_fernet_rotate_init := .Values.pod.mounts.keystone_fernet_rotate.init_container }} {{- $serviceAccountName := "keystone-fernet-rotate" }} {{ tuple $envAll "fernet_rotate" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.keystone_fernet_rotate }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - list - create - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: CronJob metadata: name: keystone-fernet-rotate annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.fernet_rotate.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.fernet_rotate.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.fernet_rotate.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "keystone" "fernet-rotate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "keystone" "fernet-rotate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ tuple "keystone_fernet_rotate" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "keystone_fernet_rotate" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "fernet_rotate" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} initContainers: {{ tuple $envAll "fernet_rotate" $mounts_keystone_fernet_rotate_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.keystone.enabled }} {{ tuple $envAll "keystone" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} containers: - name: keystone-fernet-rotate {{ tuple $envAll "keystone_fernet_rotate" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.fernet_rotate | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "fernet_rotate" "container" "keystone_fernet_rotate" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14}} env: - name: KEYSTONE_USER value: {{ .Values.jobs.fernet_rotate.user | quote }} - name: KEYSTONE_GROUP value: {{ .Values.jobs.fernet_rotate.group | quote }} - name: KUBERNETES_NAMESPACE value: {{ .Release.Namespace | quote }} - name: KEYSTONE_KEYS_REPOSITORY value: {{ .Values.conf.keystone.fernet_tokens.key_repository | quote }} command: - python - /tmp/fernet-manage.py - fernet_rotate volumeMounts: - name: pod-tmp mountPath: /tmp - name: etckeystone mountPath: /etc/keystone - name: keystone-etc mountPath: /etc/keystone/keystone.conf subPath: keystone.conf readOnly: true - name: keystone-etc-snippets mountPath: /etc/keystone/keystone.conf.d/ readOnly: true {{- if .Values.conf.keystone.DEFAULT.log_config_append }} - name: keystone-etc mountPath: {{ .Values.conf.keystone.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.keystone.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: keystone-bin mountPath: /tmp/fernet-manage.py subPath: fernet-manage.py readOnly: true {{ if $mounts_keystone_fernet_rotate.volumeMounts }}{{ toYaml $mounts_keystone_fernet_rotate.volumeMounts | indent 16 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etckeystone emptyDir: {} - name: keystone-etc secret: secretName: keystone-etc defaultMode: 0444 - name: keystone-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} - name: keystone-bin configMap: name: keystone-bin defaultMode: 0555 {{ if $mounts_keystone_fernet_rotate.volumes }}{{ toYaml $mounts_keystone_fernet_rotate.volumes | indent 12 }}{{ end }} {{- end }} {{- end }} ================================================ FILE: keystone/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "apiProbeTemplate" }} httpGet: scheme: {{ tuple "identity" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: {{ tuple "identity" "healthcheck" "internal" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} port: {{ tuple "identity" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_keystone_api := .Values.pod.mounts.keystone_api.keystone_api }} {{- $mounts_keystone_api_init := .Values.pod.mounts.keystone_api.init_container }} {{- $serviceAccountName := "keystone-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.keystone_api }} --- apiVersion: apps/v1 kind: Deployment metadata: name: keystone-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "keystone" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "keystone" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "keystone" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "keystone_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "keystone-api" "containerNames" (list "keystone-api") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "keystone" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "keystone_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "keystone_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "keystone" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.keystone.enabled }} {{ tuple $envAll "keystone" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_keystone_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: keystone-api {{ tuple $envAll "keystone_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "keystone" "container" "keystone_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/keystone-api.sh - start lifecycle: preStop: exec: command: - /tmp/keystone-api.sh - stop ports: - name: ks-pub containerPort: {{ tuple "identity" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "api" "container" "api" "type" "readiness" "probeTemplate" (include "apiProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "api" "type" "liveness" "probeTemplate" (include "apiProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.keystone.oslo_concurrency.lock_path }} - name: etckeystone mountPath: /etc/keystone - name: logs-apache mountPath: /var/log/apache2 - name: run-apache mountPath: /var/run/apache2 - name: keystone-bin mountPath: /var/www/cgi-bin/keystone/wsgi.py subPath: wsgi.py readOnly: true - name: keystone-etc mountPath: /etc/keystone/keystone.conf subPath: keystone.conf readOnly: true - name: keystone-etc-snippets mountPath: /etc/keystone/keystone.conf.d/ readOnly: true - name: keystone-etc mountPath: /etc/apache2/ports.conf subPath: ports.conf readOnly: true {{- if .Values.conf.keystone.DEFAULT.log_config_append }} - name: keystone-etc mountPath: {{ .Values.conf.keystone.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.keystone.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: keystone-etc mountPath: /etc/keystone/policy.yaml subPath: policy.yaml readOnly: true - name: keystone-etc mountPath: /etc/keystone/access_rules.json subPath: access_rules.json readOnly: true - name: keystone-etc mountPath: /etc/keystone/sso_callback_template.html subPath: sso_callback_template.html readOnly: true - name: keystone-etc mountPath: {{ .Values.conf.software.apache2.conf_dir }}/wsgi-keystone.conf subPath: wsgi-keystone.conf readOnly: true - name: keystone-etc mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf subPath: mpm_event.conf readOnly: true {{- if .Values.conf.security }} - name: keystone-etc mountPath: {{ .Values.conf.software.apache2.conf_dir }}/security.conf subPath: security.conf readOnly: true {{- end }} - name: keystone-bin mountPath: /tmp/keystone-api.sh subPath: keystone-api.sh readOnly: true {{- if .Values.endpoints.ldap.auth.client.tls.ca }} - name: keystone-ldap-tls mountPath: /etc/keystone/ldap/tls.ca subPath: tls.ca readOnly: true {{- end }} {{- if eq .Values.conf.keystone.token.provider "fernet" }} - name: keystone-fernet-keys mountPath: {{ .Values.conf.keystone.fernet_tokens.key_repository }} {{- end }} - name: keystone-credential-keys mountPath: {{ .Values.conf.keystone.credential.key_repository }} {{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.identity.api.internal "path" "/etc/keystone/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.tls.oslo_messaging "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_keystone_api.volumeMounts }}{{ toYaml $mounts_keystone_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: etckeystone emptyDir: {} - name: logs-apache emptyDir: {} - name: run-apache emptyDir: {} - name: keystone-etc secret: secretName: keystone-etc defaultMode: 0444 - name: keystone-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: keystone-bin configMap: name: keystone-bin defaultMode: 0555 {{- if .Values.endpoints.ldap.auth.client.tls.ca }} - name: keystone-ldap-tls secret: secretName: keystone-ldap-tls {{- end }} {{- if eq .Values.conf.keystone.token.provider "fernet" }} - name: keystone-fernet-keys secret: secretName: keystone-fernet-keys {{- end }} - name: keystone-credential-keys secret: secretName: keystone-credential-keys {{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.tls.oslo_messaging "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_keystone_api.volumes }}{{ toYaml $mounts_keystone_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: keystone/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: keystone/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "identity" "backendPort" "ks-pub" -}} {{- $secretName := $envAll.Values.secrets.tls.identity.api.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.identity.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: keystone/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.bootstrap" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "5" {{- end }} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "keystone" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.keystone.DEFAULT.log_config_append "jobAnnotations" (include "metadata.annotations.job.bootstrap" . | fromYaml) -}} {{- if and ( or .Values.manifests.certificates .Values.tls.identity) .Values.secrets.tls.identity.api.internal -}} {{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.identity.api.internal -}} {{- end -}} {{- if .Values.pod.tolerations.keystone.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{- if and .Values.jobs.bootstrap .Values.jobs.bootstrap.backoffLimit }} {{- $_ := set $bootstrapJob "backoffLimit" .Values.jobs.bootstrap.backoffLimit -}} {{- end }} {{- if and .Values.jobs.bootstrap .Values.jobs.bootstrap.activeDeadlineSeconds }} {{- $_ := set $bootstrapJob "activeDeadlineSeconds" .Values.jobs.bootstrap.activeDeadlineSeconds -}} {{- end }} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: keystone/templates/job-credential-cleanup.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_credential_cleanup }} {{- $envAll := index . -}} {{- $serviceName := "keystone" -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $configMapBin := "keystone-bin" -}} {{- $configMapEtc := "keystone-etc" -}} {{- $dbToClean := index . "dbToClean" | default ( dict "adminSecret" $envAll.Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" ) -}} {{ tuple $envAll "credential_cleanup" $serviceName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: "keystone-credential-cleanup" labels: {{ tuple $envAll "keystone" "credential-cleanup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": pre-delete "helm.sh/hook-delete-policy": hook-succeeded, hook-failed {{ tuple "keystone_credential_cleanup" $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll $serviceName "credential-cleanup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "keystone-credential-cleanup" "containerNames" (list "keystone-credential-cleanup") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "keystone_credential_cleanup" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "keystone_credential_cleanup" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceName }} restartPolicy: Never {{ if $envAll.Values.pod.tolerations.keystone.enabled }} {{ tuple $envAll "keystone" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} initContainers: {{ tuple $envAll "credential_cleanup" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{ $dbToCleanType := default "oslo" $dbToClean.inputType }} - name: {{ printf "%s-%s" $serviceName "credential-cleanup" | quote }} image: {{ $envAll.Values.images.tags.keystone_credential_cleanup }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_drop | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: ROOT_DB_CONNECTION valueFrom: secretKeyRef: name: {{ $dbToClean.adminSecret | quote }} key: DB_CONNECTION {{- if eq $dbToCleanType "oslo" }} - name: OPENSTACK_CONFIG_FILE value: {{ $dbToClean.configFile | quote }} - name: OPENSTACK_CONFIG_DB_SECTION value: {{ $dbToClean.configDbSection | quote }} - name: OPENSTACK_CONFIG_DB_KEY value: {{ $dbToClean.configDbKey | quote }} {{- end }} {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} command: - python - /tmp/cred-clean.py volumeMounts: - name: pod-tmp mountPath: /tmp - name: cred-clean-sh mountPath: /tmp/cred-clean.py subPath: cred-clean.py readOnly: true {{- if eq $dbToCleanType "oslo" }} - name: etc-service mountPath: {{ dir $dbToClean.configFile | quote }} - name: cred-clean-conf mountPath: {{ $dbToClean.configFile | quote }} subPath: {{ base $dbToClean.configFile | quote }} readOnly: true - name: cred-clean-conf mountPath: {{ $dbToClean.logConfigFile | quote }} subPath: {{ base $dbToClean.logConfigFile | quote }} readOnly: true {{- end }} {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: cred-clean-sh configMap: name: "keystone-bin" defaultMode: 0555 {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} {{- $local := dict "configMapBinFirst" true -}} {{- $dbToCleanType := default "oslo" $dbToClean.inputType }} {{- if and (eq $dbToCleanType "oslo") $local.configMapBinFirst }} {{- $_ := set $local "configMapBinFirst" false }} - name: etc-service emptyDir: {} - name: cred-clean-conf secret: secretName: "keystone-etc" defaultMode: 0444 {{- end -}} {{- end -}} ================================================ FILE: keystone/templates/job-credential-setup.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_credential_setup }} {{- $envAll := . }} {{- $mounts_keystone_credential_setup := .Values.pod.mounts.keystone_credential_setup.keystone_credential_setup }} {{- $mounts_keystone_credential_setup_init := .Values.pod.mounts.keystone_credential_setup.init_container }} {{- $serviceAccountName := "keystone-credential-setup" }} {{ tuple $envAll "credential_setup" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.keystone_credential_setup }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - list - create - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: keystone-credential-setup labels: {{ tuple $envAll "keystone" "credential-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-weight": "-5" "helm.sh/hook-delete-policy": before-hook-creation {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ tuple "keystone_credential_setup" $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "keystone" "credential-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "keystone-credential-setup" "containerNames" (list "keystone-credential-setup") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "keystone_credential_setup" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "keystone_credential_setup" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "credential_setup" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} initContainers: {{ tuple $envAll "credential_setup" $mounts_keystone_credential_setup_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.keystone.enabled }} {{ tuple $envAll "keystone" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} containers: - name: keystone-credential-setup {{ tuple $envAll "keystone_credential_setup" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.credential_setup | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "credential_setup" "container" "keystone_credential_setup" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: KEYSTONE_USER value: {{ .Values.jobs.credential_setup.user | quote }} - name: KEYSTONE_GROUP value: {{ .Values.jobs.credential_setup.group | quote }} - name: KUBERNETES_NAMESPACE value: {{ .Release.Namespace | quote }} - name: KEYSTONE_KEYS_REPOSITORY value: {{ .Values.conf.keystone.credential.key_repository | quote }} command: - python - /tmp/fernet-manage.py - credential_setup volumeMounts: - name: pod-tmp mountPath: /tmp - name: etckeystone mountPath: /etc/keystone - name: credential-keys mountPath: {{ .Values.conf.keystone.credential.key_repository | quote }} - name: keystone-etc mountPath: /etc/keystone/keystone.conf subPath: keystone.conf readOnly: true - name: keystone-etc-snippets mountPath: /etc/keystone/keystone.conf.d/ readOnly: true {{- if .Values.conf.keystone.DEFAULT.log_config_append }} - name: keystone-etc mountPath: {{ .Values.conf.keystone.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.keystone.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: keystone-bin mountPath: /tmp/fernet-manage.py subPath: fernet-manage.py readOnly: true {{ if $mounts_keystone_credential_setup.volumeMounts }}{{ toYaml $mounts_keystone_credential_setup.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etckeystone emptyDir: {} - name: credential-keys emptyDir: {} - name: keystone-etc secret: secretName: keystone-etc defaultMode: 0444 - name: keystone-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: keystone-bin configMap: name: keystone-bin defaultMode: 0555 {{ if $mounts_keystone_credential_setup.volumes }}{{ toYaml $mounts_keystone_credential_setup.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: keystone/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "keystone" -}} {{- if and .Values.manifests.certificates .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.keystone.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: keystone/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "keystone" "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) -}} {{- if and .Values.manifests.certificates .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.keystone.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: keystone/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- define "keystone.templates._job_db_sync.env_vars" -}} {{- $envAll := index . 0 -}} env: - name: OS_BOOTSTRAP_ADMIN_URL value: {{ tuple "identity" "admin" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} - name: OS_BOOTSTRAP_INTERNAL_URL value: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} - name: OS_BOOTSTRAP_PUBLIC_URL value: {{ tuple "identity" "public" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 2}} {{- end }} {{- end }} {{- define "keystone.templates._job_db_sync.pod_vol_mounts" -}} {{- $envAll := index . 0 -}} volumeMounts: - name: keystone-fernet-keys mountPath: {{ $envAll.Values.conf.keystone.fernet_tokens.key_repository }} readOnly: true {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 2 }} {{- end }} {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 2 }} {{- end }} {{- end }} {{- define "keystone.templates._job_db_sync.pod_vols" -}} {{- $envAll := index . 0 -}} volumes: - name: keystone-fernet-keys secret: secretName: keystone-fernet-keys {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 2 }} {{- end }} {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 2 }} {{- end }} {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $local := dict "podVolMounts" false "podVols" false -}} {{- if eq .Values.conf.keystone.token.provider "fernet" }} {{- $_ := set $local "podVolMounts" ( index ( tuple . | include "keystone.templates._job_db_sync.pod_vol_mounts" | toString | fromYaml ) "volumeMounts" ) }} {{- $_ := set $local "podVols" ( index ( tuple . | include "keystone.templates._job_db_sync.pod_vols" | toString | fromYaml ) "volumes" ) }} {{- end }} {{- $podEnvVars := tuple . | include "keystone.templates._job_db_sync.env_vars" | toString | fromYaml }} {{- $dbSyncJob := dict "envAll" . "serviceName" "keystone" "podVolMounts" $local.podVolMounts "podVols" $local.podVols "podEnvVars" $podEnvVars.env "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) -}} {{- if .Values.pod.tolerations.keystone.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: keystone/templates/job-domain-manage.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_domain_manage }} {{- $envAll := . }} {{- $mounts_keystone_domain_manage := .Values.pod.mounts.keystone_domain_manage.keystone_domain_manage }} {{- $mounts_keystone_domain_manage_init := .Values.pod.mounts.keystone_domain_manage.init_container }} {{- $serviceAccountName := "keystone-domain-manage" }} {{ tuple $envAll "domain_manage" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.keystone_domain_manage }} --- apiVersion: batch/v1 kind: Job metadata: name: keystone-domain-manage labels: {{ tuple $envAll "keystone" "domain-manage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-delete-policy": before-hook-creation {{ tuple $serviceAccountName $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "keystone" "domain-manage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "keystone-domain-manage" "containerNames" (list "keystone-domain-manage" "keystone-domain-manage-init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "keystone_domain_manage" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "keystone_domain_manage" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "domain_manage" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.keystone.enabled }} {{ tuple $envAll "keystone" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "domain_manage" $mounts_keystone_domain_manage_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: keystone-domain-manage-init {{ tuple $envAll "bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.domain_manage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "domain_manage" "container" "keystone_domain_manage_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" (and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/domain-manage-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: keystone-bin mountPath: /tmp/domain-manage-init.sh subPath: domain-manage-init.sh readOnly: true {{- if and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} containers: - name: keystone-domain-manage {{ tuple $envAll "keystone_domain_manage" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.domain_manage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "domain_manage" "container" "keystone_domain_manage" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" (and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/domain-manage.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etckeystonedomains mountPath: {{ .Values.conf.keystone.identity.domain_config_dir | default "/etc/keystone/domains" }} - name: etckeystone mountPath: /etc/keystone - name: keystone-bin mountPath: /tmp/domain-manage.sh subPath: domain-manage.sh readOnly: true - name: keystone-bin mountPath: /tmp/domain-manage.py subPath: domain-manage.py readOnly: true - name: keystone-etc mountPath: /etc/keystone/keystone.conf subPath: keystone.conf readOnly: true - name: keystone-etc-snippets mountPath: /etc/keystone/keystone.conf.d/ readOnly: true {{- if .Values.conf.keystone.DEFAULT.log_config_append }} - name: keystone-etc mountPath: {{ .Values.conf.keystone.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.keystone.DEFAULT.log_config_append }} readOnly: true {{- end }} {{- range $k, $v := .Values.conf.ks_domains }} - name: keystone-etc mountPath: {{ $envAll.Values.conf.keystone.identity.domain_config_dir | default "/etc/keystone/domains" }}/keystone.{{ $k }}.json subPath: keystone.{{ $k }}.json readOnly: true {{- end }} {{- if eq .Values.conf.keystone.token.provider "fernet" }} - name: keystone-fernet-keys mountPath: {{ .Values.conf.keystone.fernet_tokens.key_repository }} {{- end }} - name: keystone-credential-keys mountPath: {{ .Values.conf.keystone.credential.key_repository }} {{- if and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} {{ if $mounts_keystone_domain_manage.volumeMounts }}{{ toYaml $mounts_keystone_domain_manage.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etckeystone emptyDir: {} - name: etckeystonedomains emptyDir: {} - name: keystone-etc secret: secretName: keystone-etc defaultMode: 0444 - name: keystone-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: keystone-bin configMap: name: keystone-bin defaultMode: 0555 {{- if eq .Values.conf.keystone.token.provider "fernet" }} - name: keystone-fernet-keys secret: secretName: keystone-fernet-keys {{- end }} - name: keystone-credential-keys secret: secretName: keystone-credential-keys {{- if and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} {{ if $mounts_keystone_domain_manage.volumes }}{{ toYaml $mounts_keystone_domain_manage.volumes | indent 9 }}{{ end }} {{- end }} ================================================ FILE: keystone/templates/job-fernet-setup.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_fernet_setup }} {{- if eq .Values.conf.keystone.token.provider "fernet" }} {{- $envAll := . }} {{- $mounts_keystone_fernet_setup := .Values.pod.mounts.keystone_fernet_setup.keystone_fernet_setup }} {{- $mounts_keystone_fernet_setup_init := .Values.pod.mounts.keystone_fernet_setup.init_container }} {{- $serviceAccountName := "keystone-fernet-setup" }} {{ tuple $envAll "fernet_setup" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.keystone_fernet_setup }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - list - create - update --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: keystone-fernet-setup labels: {{ tuple $envAll "keystone" "fernet-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": post-install,post-upgrade "helm.sh/hook-weight": "-5" "helm.sh/hook-delete-policy": before-hook-creation {{ tuple "keystone_fernet_setup" $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "keystone" "fernet-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "keystone-fernet-setup" "containerNames" (list "keystone-fernet-setup") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "keystone_fernet_setup" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "keystone_fernet_setup" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "fernet_setup" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} initContainers: {{ tuple $envAll "fernet_setup" $mounts_keystone_fernet_setup_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.keystone.enabled }} {{ tuple $envAll "keystone" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} containers: - name: keystone-fernet-setup {{ tuple $envAll "keystone_fernet_setup" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.fernet_setup | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "fernet_setup" "container" "keystone_fernet_setup" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: KEYSTONE_USER value: {{ .Values.jobs.fernet_setup.user | quote }} - name: KEYSTONE_GROUP value: {{ .Values.jobs.fernet_setup.group | quote }} - name: KUBERNETES_NAMESPACE value: {{ .Release.Namespace | quote }} - name: KEYSTONE_KEYS_REPOSITORY value: {{ .Values.conf.keystone.fernet_tokens.key_repository | quote }} command: - python - /tmp/fernet-manage.py - fernet_setup volumeMounts: - name: pod-tmp mountPath: /tmp - name: etckeystone mountPath: /etc/keystone - name: fernet-keys mountPath: {{ .Values.conf.keystone.fernet_tokens.key_repository | quote }} - name: keystone-etc mountPath: /etc/keystone/keystone.conf subPath: keystone.conf readOnly: true - name: keystone-etc-snippets mountPath: /etc/keystone/keystone.conf.d/ readOnly: true {{- if .Values.conf.keystone.DEFAULT.log_config_append }} - name: keystone-etc mountPath: {{ .Values.conf.keystone.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.keystone.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: keystone-bin mountPath: /tmp/fernet-manage.py subPath: fernet-manage.py readOnly: true {{ if $mounts_keystone_fernet_setup.volumeMounts }}{{ toYaml $mounts_keystone_fernet_setup.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etckeystone emptyDir: {} - name: fernet-keys emptyDir: {} - name: keystone-etc secret: secretName: keystone-etc defaultMode: 0444 - name: keystone-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: keystone-bin configMap: name: keystone-bin defaultMode: 0555 {{ if $mounts_keystone_fernet_setup.volumes }}{{ toYaml $mounts_keystone_fernet_setup.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} ================================================ FILE: keystone/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "keystone" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} {{- if .Values.pod.tolerations.keystone.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: keystone/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "keystone" "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) -}} {{- if and .Values.tls.oslo_messaging .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- $_ := set $rmqUserJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.keystone.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: keystone/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "keystone" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: keystone/templates/pdb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: keystone-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "keystone" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: keystone/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.keystone_tests.keystone_tests }} {{- $mounts_tests_init := .Values.pod.mounts.keystone_tests.init_container }} {{- $serviceAccountName := print $envAll.deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.deployment_name "-test" }} labels: {{ tuple $envAll "keystone" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "keystone-test" "containerNames" (list "init" "keystone-test" "keystone-test-ks-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: restartPolicy: Never {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ tuple "keystone_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "keystone_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: keystone-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "keystone_test_ks_user" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: keystone-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{- if and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{- end }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" (and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: keystone-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "keystone_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6}} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" (and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.deployment_name}} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: keystone-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: keystone-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally - name: rally-work mountPath: /home/rally/.rally {{- if and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{- end }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: keystone-etc secret: secretName: keystone-etc defaultMode: 0444 - name: keystone-bin configMap: name: keystone-bin defaultMode: 0555 - name: rally-db emptyDir: {} - name: rally-work emptyDir: {} {{- if and .Values.manifests.certificates .Values.secrets.tls.identity.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: keystone/templates/secret-credential-keys.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_credential_keys }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: keystone-credential-keys annotations: "helm.sh/hook": pre-install "helm.sh/resource-policy": keep type: Opaque data: {{- end }} ================================================ FILE: keystone/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "keystone" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: keystone/templates/secret-fernet-keys.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_fernet_keys }} {{- $envAll := . }} {{- if eq .Values.conf.keystone.token.provider "fernet" }} --- apiVersion: v1 kind: Secret metadata: name: keystone-fernet-keys annotations: "helm.sh/hook": pre-install "helm.sh/resource-policy": keep type: Opaque data: {{- end }} {{- end }} ================================================ FILE: keystone/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "identity" ) }} {{- end }} ================================================ FILE: keystone/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: keystone/templates/secret-ldap-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.endpoints.ldap.auth.client.tls.ca }} --- apiVersion: v1 kind: Secret metadata: name: {{ .Values.secrets.ldap.tls }} annotations: {{ tuple "ldap" "tls" . | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: tls.ca: {{ .Values.endpoints.ldap.auth.client.tls.ca | default "" | b64enc }} {{- end }} ================================================ FILE: keystone/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if and $envAll.Values.manifests.certificates $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "keystone" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: keystone/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: keystone/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "identity" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: ks-pub port: {{ tuple "identity" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "keystone" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if or (.Values.network.api.node_port.enabled) (.Values.network.admin.node_port.enabled) }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: keystone/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "identity" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: keystone/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for keystone. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble test: docker.io/xrally/xrally-openstack:2.0.0 db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble keystone_db_sync: quay.io/airshipit/keystone:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management keystone_fernet_setup: quay.io/airshipit/keystone:2025.1-ubuntu_noble keystone_fernet_rotate: quay.io/airshipit/keystone:2025.1-ubuntu_noble keystone_credential_setup: quay.io/airshipit/keystone:2025.1-ubuntu_noble keystone_credential_rotate: quay.io/airshipit/keystone:2025.1-ubuntu_noble keystone_credential_cleanup: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble keystone_api: quay.io/airshipit/keystone:2025.1-ubuntu_noble keystone_domain_manage: quay.io/airshipit/keystone:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync bootstrap: enabled: true ks_user: admin script: | # admin needs the admin role for the default domain openstack role add \ --user="${OS_USERNAME}" \ --domain="${OS_DEFAULT_DOMAIN}" \ "admin" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30500 admin: node_port: enabled: false port: 30357 dependencies: dynamic: common: local_image_registry: jobs: - keystone-image-repo-sync services: - endpoint: node service: local_image_registry rabbit_init: services: - service: oslo_messaging endpoint: internal static: api: jobs: - keystone-db-sync - keystone-credential-setup - keystone-fernet-setup services: - endpoint: internal service: oslo_cache - endpoint: internal service: oslo_db bootstrap: jobs: - keystone-domain-manage services: - endpoint: internal service: identity credential_rotate: jobs: - keystone-credential-setup credential_setup: null credential_cleanup: services: - endpoint: internal service: oslo_db db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - keystone-db-init - keystone-credential-setup - keystone-fernet-setup services: - endpoint: internal service: oslo_db domain_manage: services: - endpoint: internal service: identity fernet_rotate: jobs: - keystone-fernet-setup fernet_setup: null tests: services: - endpoint: internal service: identity image_repo_sync: services: - endpoint: internal service: local_image_registry pod: security_context: keystone: pod: runAsUser: 42424 container: keystone_api: readOnlyRootFilesystem: true allowPrivilegeEscalation: false credential_setup: pod: runAsUser: 42424 container: keystone_credential_setup: readOnlyRootFilesystem: true allowPrivilegeEscalation: false fernet_setup: pod: runAsUser: 42424 container: keystone_fernet_setup: readOnlyRootFilesystem: true allowPrivilegeEscalation: false fernet_rotate: pod: runAsUser: 42424 container: keystone_fernet_rotate: readOnlyRootFilesystem: true allowPrivilegeEscalation: false domain_manage: pod: runAsUser: 42424 container: keystone_domain_manage_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false keystone_domain_manage: readOnlyRootFilesystem: true allowPrivilegeEscalation: false test: pod: runAsUser: 42424 container: keystone_test_ks_user: readOnlyRootFilesystem: true allowPrivilegeEscalation: false keystone_test: runAsUser: 65500 readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: keystone: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: keystone_db_init: init_container: null keystone_db_init: volumeMounts: volumes: keystone_db_sync: init_container: null keystone_db_sync: volumeMounts: volumes: keystone_api: init_container: null keystone_api: volumeMounts: volumes: keystone_tests: init_container: null keystone_tests: volumeMounts: volumes: keystone_bootstrap: init_container: null keystone_bootstrap: volumeMounts: volumes: keystone_fernet_setup: init_container: null keystone_fernet_setup: volumeMounts: volumes: keystone_fernet_rotate: init_container: null keystone_fernet_rotate: volumeMounts: volumes: keystone_credential_setup: init_container: null keystone_credential_setup: volumeMounts: volumes: keystone_credential_rotate: init_container: null keystone_credential_rotate: volumeMounts: volumes: keystone_credential_cleanup: init_container: null keystone_credential_cleanup: volumeMounts: volumes: keystone_domain_manage: init_container: null keystone_domain_manage: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/keystone/keystone.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: keystone_db_sync: [] keystone_api: [] keystone_fernet_setup: [] keystone_fernet_rotate: [] keystone_credential_setup: [] keystone_credential_rotate: [] keystone_domain_manage: [] replicas: api: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" domain_manage: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" fernet_setup: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" fernet_rotate: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" credential_setup: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" credential_rotate: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" credential_cleanup: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" probes: api: api: readiness: enabled: true params: initialDelaySeconds: 15 periodSeconds: 60 timeoutSeconds: 15 liveness: enabled: true params: initialDelaySeconds: 50 periodSeconds: 60 timeoutSeconds: 15 jobs: fernet_setup: user: keystone group: keystone fernet_rotate: # NOTE(rk760n): key rotation frequency, token expiration, active keys, and allow_expired_window should statisfy the formula # max_active_keys = ((token_expiration + allow_expired_window) / rotation_frequency) + 2 # As expiration is 12h, max_active_keys is 7 and allow_expired_window is 48h by default, # rotation_frequency need to be adjusted # 12 hours cron: "0 */12 * * *" user: keystone group: keystone history: success: 3 failed: 1 credential_setup: user: keystone group: keystone credential_rotate: # monthly cron: "0 0 1 * *" migrate_wait: 120 user: keystone group: keystone history: success: 3 failed: 1 network_policy: keystone: ingress: - {} egress: - {} conf: security: | # # Disable access to the entire file system except for the directories that # are explicitly allowed later. # # This currently breaks the configurations that come with some web application # Debian packages. # # # AllowOverride None # Require all denied # # Changing the following options will not really affect the security of the # server, but might make attacks slightly more difficult in some cases. # # ServerTokens # This directive configures what you return as the Server HTTP response # Header. The default is 'Full' which sends information about the OS-Type # and compiled in modules. # Set to one of: Full | OS | Minimal | Minor | Major | Prod # where Full conveys the most information, and Prod the least. ServerTokens Prod # # Optionally add a line containing the server version and virtual host # name to server-generated pages (internal error documents, FTP directory # listings, mod_status and mod_info output etc., but not CGI generated # documents or custom error documents). # Set to "EMail" to also include a mailto: link to the ServerAdmin. # Set to one of: On | Off | EMail ServerSignature Off # # Allow TRACE method # # Set to "extended" to also reflect the request body (only for testing and # diagnostic purposes). # # Set to one of: On | Off | extended TraceEnable Off # # Forbid access to version control directories # # If you use version control systems in your document root, you should # probably deny access to their directories. For example, for subversion: # # # Require all denied # # # Setting this header will prevent MSIE from interpreting files as something # else than declared by the content type in the HTTP headers. # Requires mod_headers to be enabled. # #Header set X-Content-Type-Options: "nosniff" # # Setting this header will prevent other sites from embedding pages from this # site as frames. This defends against clickjacking attacks. # Requires mod_headers to be enabled. # #Header set X-Frame-Options: "sameorigin" software: apache2: binary: apache2 start_parameters: -DFOREGROUND site_dir: /etc/apache2/sites-enable conf_dir: /etc/apache2/conf-enabled mods_dir: /etc/apache2/mods-available a2enmod: null a2dismod: null keystone: DEFAULT: log_config_append: /etc/keystone/logging.conf max_token_size: 255 # NOTE(rk760n): if you need auth notifications to be sent, uncomment it # notification_opt_out: "" token: provider: fernet # 12 hours expiration: 43200 identity: domain_specific_drivers_enabled: True domain_config_dir: /etc/keystone/domains fernet_tokens: key_repository: /etc/keystone/fernet-keys/ max_active_keys: 7 credential: key_repository: /etc/keystone/credential-keys/ database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" cache: enabled: true backend: dogpile.cache.memcached oslo_messaging_notifications: driver: messagingv2 oslo_messaging_rabbit: rabbit_ha_queues: true oslo_middleware: enable_proxy_headers_parsing: true oslo_policy: policy_file: /etc/keystone/policy.yaml oslo_concurrency: lock_path: /var/lock security_compliance: # NOTE(vdrok): The following two options have effect only for SQL backend lockout_failure_attempts: 5 lockout_duration: 1800 # NOTE(lamt) We can leverage multiple domains with different # configurations as outlined in # https://docs.openstack.org/keystone/pike/admin/identity-domain-specific-config.html. # A sample of the value override can be found in sample file: # tools/overrides/example/keystone_domain_config.yaml # ks_domains: policy: {} access_rules: {} rabbitmq: # NOTE(rk760n): adding rmq policy to mirror messages from notification queues and set expiration time for the ones policies: - vhost: "keystone" name: "ha_ttl_keystone" definition: # mirror messges to other nodes in rmq cluster ha-mode: "all" ha-sync-mode: "automatic" # 70s message-ttl: 70000 priority: 0 apply-to: all pattern: '^(?!(amq\.|reply_)).*' rally_tests: run_tempest: false tests: KeystoneBasic.add_and_remove_user_role: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.authenticate_user_and_validate_token: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_add_and_list_user_roles: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_delete_ec2credential: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_list_ec2credentials: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_delete_role: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_delete_service: - args: description: test_description service_type: Rally_test_type runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_get_role: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_list_services: - args: description: test_description service_type: Rally_test_type runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_list_tenants: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_list_users: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_delete_user: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_tenant: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_tenant_with_users: - args: users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_update_and_delete_tenant: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_user: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_user_set_enabled_and_delete: - args: enabled: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 - args: enabled: false runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_user_update_password: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 KeystoneBasic.get_entities: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 mpm_event: | ServerLimit 1024 StartServers 32 MinSpareThreads 32 MaxSpareThreads 256 ThreadsPerChild 25 MaxRequestsPerChild 128 ThreadLimit 720 # -- WSGIScriptAlias for apache2. Copied from keystone/wsgi/api.py ## apache cannot load a module and the path can change depending on python version wsgi_script: | import threading from keystone.server import wsgi application = None lock = threading.Lock() with lock: if application is None: application = wsgi.initialize_public_application() wsgi_keystone: | {{- $portInt := tuple "identity" "service" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen 0.0.0.0:{{ $portInt }} LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout WSGIDaemonProcess keystone-public processes=1 threads=1 user=keystone group=keystone display-name=%{GROUP} WSGIProcessGroup keystone-public WSGIScriptAlias / /var/www/cgi-bin/keystone/wsgi.py WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded sso_callback_template: | Keystone WebSSO redirect
Please wait...
logging: loggers: keys: - root - keystone handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_keystone: level: INFO handlers: - stdout qualname: keystone logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: keystone-keystone-admin test: keystone-keystone-test oslo_db: admin: keystone-db-admin keystone: keystone-db-user oslo_messaging: admin: keystone-rabbitmq-admin keystone: keystone-rabbitmq-user ldap: tls: keystone-ldap-tls tls: identity: api: public: keystone-tls-public internal: keystone-tls-api oci_image_registry: keystone: keystone-oci-image-registry # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false keystone: username: keystone password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: namespace: null name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default default_domain_id: default test: role: admin region_name: RegionOne username: keystone-test password: password project_name: test user_domain_name: default project_domain_name: default default_domain_id: default hosts: default: keystone internal: keystone-api host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: /v3 healthcheck: /healthcheck scheme: default: http service: http port: api: default: 80 # NOTE(portdirect): to retain portability across images, and allow # running under a unprivileged user simply, we default to a port > 1000. internal: 5000 service: 5000 oslo_db: namespace: null auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct keystone: username: keystone password: password hosts: default: mariadb host_fqdn_override: default: null path: /keystone scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: namespace: null auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct keystone: username: keystone password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /keystone scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: namespace: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 ldap: auth: client: tls: # NOTE(lamt): Specify a CA value here will place a LDAPS certificate at # /etc/certs/tls.ca. To ensure keystone uses LDAPS, the # following key will need to be overrided under section [ldap] or the # correct domain-specific setting, else it will not be enabled: # # use_tls: true # tls_req_cert: allow # Valid values: demand, never, allow # tls_cacertfile: /etc/certs/tls.ca # abs path to the CA cert ca: null fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false configmap_bin: true configmap_etc: true cron_credential_rotate: true cron_fernet_rotate: true deployment_api: true ingress_api: true job_bootstrap: true job_credential_cleanup: true job_credential_setup: true job_db_init: true job_db_sync: true job_db_drop: false job_domain_manage: true job_fernet_setup: true job_image_repo_sync: true job_rabbit_init: true pdb_api: true pod_rally_test: true network_policy: false secret_credential_keys: true secret_db: true secret_fernet_keys: true secret_ingress_tls: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_ingress_api: true service_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: kibana/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v8.19.9 description: OpenStack-Helm Kibana name: kibana version: 2025.2.0 home: https://www.elastic.co/products/kibana sources: - https://github.com/elastic/kibana - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: kibana/templates/bin/_apache.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ev COMMAND="${@:-start}" function start () { if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/httpd/apache2/envvars fi # Apache gets grumpy about PID files pre-existing rm -f /etc/httpd/logs/httpd.pid if [ -f /usr/local/apache2/conf/.htpasswd ]; then htpasswd -b /usr/local/apache2/conf/.htpasswd "$ELASTICSEARCH_USERNAME" "$ELASTICSEARCH_PASSWORD" else htpasswd -cb /usr/local/apache2/conf/.htpasswd "$ELASTICSEARCH_USERNAME" "$ELASTICSEARCH_PASSWORD" fi #Launch Apache on Foreground exec httpd -DFOREGROUND } function stop () { apachectl -k graceful-stop } $COMMAND ================================================ FILE: kibana/templates/bin/_create_kibana_index_patterns.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex set -o noglob create_data_view() { local index_name=$1 curl -u "${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ --max-time 30 \ -X POST "${KIBANA_ENDPOINT}/api/data_views/data_view" \ -H "kbn-xsrf: true" \ -H "Content-Type: application/json" \ -d "{ \"data_view\": { \"title\": \"${index_name}-*\", \"timeFieldName\": \"@timestamp\" } }" } data_view_exists() { local index_name=$1 local response=$(curl -s -u "${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ --max-time 30 \ -X GET "${KIBANA_ENDPOINT}/api/data_views" \ -H "kbn-xsrf: true" \ -H "Content-Type: application/json") if echo "$response" | grep -Fq "\"title\":\"${index_name}-*\""; then return 0 fi return 1 } set_default_data_view() { local view_id=$1 curl -u "${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ --max-time 30 \ -X POST "${KIBANA_ENDPOINT}/api/data_views/default" \ -H "kbn-xsrf: true" \ -H "Content-Type: application/json" \ -d "{ \"data_view_id\": \"${view_id}\", \"force\": true }" } find_and_set_python() { pythons="python3 python python2" for p in ${pythons[@]}; do python=$(which ${p}) if [[ $? -eq 0 ]]; then echo found python: ${python} break fi done } get_view_id() { local index_name=$1 local response=$(curl -s -u "${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ --max-time 30 \ -X GET "${KIBANA_ENDPOINT}/api/data_views" \ -H "kbn-xsrf: true" \ -H "Content-Type: application/json" | $python -c "import sys,json; j=json.load(sys.stdin); t=[x['id'] for x in j['data_view'] if x['title'] == '${index_name}-*']; print(t[0] if len(t) else '')" ) echo $response } # Create data views {{- range $objectType, $indices := .Values.conf.create_kibana_indexes.indexes }} {{- range $indices }} if ! data_view_exists "{{ . }}"; then create_data_view "{{ . }}" for t in 30 60 120 180; do if data_view_exists "{{ . }}"; then echo "Data view '{{ . }}-*' exists" break fi sleep $t echo "Retrying creation of data view '{{ . }}-*' ..." create_data_view "{{ . }}" done if ! data_view_exists "{{ . }}"; then echo "Giving up" return 1 fi else echo "Data view '{{ . }}-*' exists" fi {{- end }} {{- end }} # Lookup default view id. The new Kibana view API requires the id # instead of simply the name like the previous index API did. find_and_set_python default_index="{{ .Values.conf.create_kibana_indexes.default_index }}" default_index_id=$(get_view_id $default_index) set_default_data_view "$default_index_id" echo "Default data view set to '${default_index}'." ================================================ FILE: kibana/templates/bin/_flush_kibana_metadata.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex echo "Deleting index created for metadata" curl ${CACERT_OPTION} -K- <<< "--user ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD}" \ -XDELETE "${ELASTICSEARCH_ENDPOINT}/.kibana*" ================================================ FILE: kibana/templates/bin/_kibana.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e COMMAND="${@:-start}" function start () { exec /usr/share/kibana/bin/kibana \ --elasticsearch.hosts="${ELASTICSEARCH_HOSTS}" \ --elasticsearch.username="${ELASTICSEARCH_USERNAME}" \ --elasticsearch.password="${ELASTICSEARCH_PASSWORD}" } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: kibana/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: kibana-bin data: apache.sh: | {{ tuple "bin/_apache.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} kibana.sh: | {{ tuple "bin/_kibana.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} create_kibana_index_patterns.sh: | {{ tuple "bin/_create_kibana_index_patterns.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} flush_kibana_metadata.sh: | {{ tuple "bin/_flush_kibana_metadata.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: kibana/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: kibana-etc type: Opaque data: kibana.yml: {{ toYaml .Values.conf.kibana | b64enc }} # NOTE(portdirect): this must be last, to work round helm ~2.7 bug. {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.httpd "key" "httpd.conf" "format" "Secret") | indent 2 }} {{- end }} ================================================ FILE: kibana/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "kibanaProbeTemplate" }} {{- $kibanaPort := tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $esUser := .Values.endpoints.elasticsearch.auth.admin.username }} {{- $esPass := .Values.endpoints.elasticsearch.auth.admin.password }} {{- $authHeader := printf "%s:%s" $esUser $esPass | b64enc }} httpGet: path: /status port: {{ $kibanaPort }} httpHeaders: - name: Authorization value: Basic {{ $authHeader }} {{- end }} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $esUser := .Values.endpoints.elasticsearch.auth.admin.username }} {{- $esPass := .Values.endpoints.elasticsearch.auth.admin.password }} {{- $authHeader := printf "%s:%s" $esUser $esPass | b64enc }} {{- $esScheme := tuple "elasticsearch" "internal" "http" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $esSvc := tuple "elasticsearch" "default" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- $esHosts := printf "%s://%s" $esScheme $esSvc }} {{- $serviceAccountName := "kibana" }} {{ tuple $envAll "kibana" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $kibanaPort := tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: kibana annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "kibana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.kibana }} selector: matchLabels: {{ tuple $envAll "kibana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "kibana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "kibana" "containerNames" (list "apache-proxy" "kibana" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "dashboard" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "kibana" "dashboard" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.kibana.node_selector_key }}: {{ .Values.labels.kibana.node_selector_value | quote }} initContainers: {{ tuple $envAll "kibana" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: apache-proxy {{ tuple $envAll "apache_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.apache_proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "dashboard" "container" "apache_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/apache.sh - start ports: - name: http containerPort: {{ $kibanaPort }} readinessProbe: tcpSocket: port: {{ $kibanaPort }} initialDelaySeconds: 20 periodSeconds: 30 env: - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: kibana-bin mountPath: /tmp/apache.sh subPath: apache.sh readOnly: true - name: kibana-etc mountPath: /usr/local/apache2/conf/httpd.conf subPath: httpd.conf readOnly: true - name: kibana {{ tuple $envAll "kibana" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.kibana | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "dashboard" "container" "kibana" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/kibana.sh - start ports: - name: kibana containerPort: {{ tuple "kibana" "internal" "kibana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" . "component" "kibana" "container" "kibana" "type" "liveness" "probeTemplate" (include "kibanaProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "kibana" "container" "kibana" "type" "readiness" "probeTemplate" (include "kibanaProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: ELASTICSEARCH_HOSTS value: {{ $esHosts }} - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: kibana-bin mountPath: /tmp/kibana.sh subPath: kibana.sh readOnly: true - name: pod-etc-kibana mountPath: /usr/share/kibana/config - name: pod-optimize-kibana mountPath: /usr/share/kibana/optimize - name: kibana-etc mountPath: /usr/share/kibana/config/kibana.yml subPath: kibana.yml readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.elasticsearch.auth.admin.secret.tls.internal "path" "/etc/elasticsearch/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: pod-etc-kibana emptyDir: {} - name: pod-optimize-kibana emptyDir: {} - name: kibana-bin configMap: name: kibana-bin defaultMode: 0555 - name: kibana-etc secret: secretName: kibana-etc defaultMode: 0444 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.elasticsearch.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: kibana/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: kibana/templates/ingress-kibana.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.kibana.ingress.public }} {{- $envAll := . -}} {{- $ingressOpts := dict "envAll" $envAll "backendService" "kibana" "backendServiceType" "kibana" "backendPort" "http" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.kibana.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: kibana/templates/job-flush-kibana-metadata.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* This hook is enabled for post-delete and pre-upgrade triggers. The indices deleted by this hook are Kibana's meta indices - .kibana - .kibana_1 - .kibana_2 etc This is done to get around https://github.com/elastic/kibana/issues/58388 which sometimes prevents Kibana deployments from upgrading successfully. */}} {{- if .Values.manifests.job_flush_kibana_metadata }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $serviceAccountName := "flush-kibana-metadata" }} {{ tuple $envAll "flush_kibana_metadata" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: flush-kibana-metadata labels: {{ tuple $envAll "kibana" "flush_kibana_metadata" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: backoffLimit: {{ .Values.jobs.flush_kibana_metadata.backoffLimit }} template: metadata: labels: {{ tuple $envAll "kibana" "flush_kibana_metadata" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: "helm.sh/hook": pre-install, post-delete, pre-upgrade "helm.sh/hook-delete-policy": hook-succeeded {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "flush-kibana-metadata" "containerNames" (list "flush-kibana-metadata" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "flush_kibana_metadata" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} activeDeadlineSeconds: {{ .Values.jobs.flush_kibana_metadata.activeDeadlineSeconds }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "flush_kibana_metadata" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: flush-kibana-metadata {{ tuple $envAll "flush_kibana_metadata" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.flush_kibana_metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "flush_kibana_metadata" "container" "flush_kibana_metadata" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: KIBANA_ENDPOINT value: {{ tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} - name: ELASTICSEARCH_ENDPOINT value: {{ printf "%s://%s" (tuple "elasticsearch" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") (tuple "elasticsearch" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") }} {{- if .Values.manifests.certificates }} - name: CACERT_OPTION value: "--cacert /etc/elasticsearch/certs/ca.crt" {{- end }} command: - /tmp/flush_kibana_metadata.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: kibana-bin mountPath: /tmp/flush_kibana_metadata.sh subPath: flush_kibana_metadata.sh readOnly: false {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.elasticsearch.auth.admin.secret.tls.internal "path" "/etc/elasticsearch/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: kibana-bin configMap: name: kibana-bin defaultMode: 0755 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.elasticsearch.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: kibana/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "kibana" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: kibana/templates/job-register-kibana-indexes.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_register_kibana_indexes }} {{- $envAll := . }} {{- $esUserSecret := .Values.secrets.elasticsearch.user }} {{- $serviceAccountName := "register-kibana-indexes" }} {{ tuple $envAll "register_kibana_indexes" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: register-kibana-indexes labels: {{ tuple $envAll "kibana" "register_kibana_indexes" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "kibana" "register_kibana_indexes" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "register-kibana-indexes" "containerNames" (list "register-kibana-indexes" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "register_kibana_indexes" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "register_kibana_indexes" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: register-kibana-indexes {{ tuple $envAll "register_kibana_indexes" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.register_kibana_indexes | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "register_kibana_indexes" "container" "register_kibana_indexes" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: ELASTICSEARCH_USERNAME valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_USERNAME - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: {{ $esUserSecret }} key: ELASTICSEARCH_PASSWORD - name: KIBANA_ENDPOINT value: {{ tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} - name: ELASTICSEARCH_ENDPOINT value: {{ tuple "elasticsearch" "internal" "client" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} command: - /tmp/create_kibana_index_patterns.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-run mountPath: /run - name: kibana-bin mountPath: /tmp/create_kibana_index_patterns.sh subPath: create_kibana_index_patterns.sh readOnly: false volumes: - name: pod-tmp emptyDir: {} - name: pod-run emptyDir: medium: "Memory" - name: kibana-bin configMap: name: kibana-bin defaultMode: 0755 {{- end }} ================================================ FILE: kibana/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "kibana" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: kibana/templates/secret-elasticsearch-creds.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_elasticsearch }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.elasticsearch.user }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: ELASTICSEARCH_USERNAME: {{ .Values.endpoints.elasticsearch.auth.admin.username | b64enc }} ELASTICSEARCH_PASSWORD: {{ .Values.endpoints.elasticsearch.auth.admin.password | b64enc }} BIND_DN: {{ .Values.endpoints.ldap.auth.admin.bind | b64enc }} BIND_PASSWORD: {{ .Values.endpoints.ldap.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: kibana/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "kibana" "backendService" "kibana" ) }} {{- end }} ================================================ FILE: kibana/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: kibana/templates/service-ingress-kibana.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.kibana.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "kibana" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: kibana/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "kibana" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: http port: {{ tuple "kibana" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.kibana.node_port.enabled }} nodePort: {{ .Values.network.kibana.node_port.port }} {{ end }} selector: {{ tuple $envAll "kibana" "dashboard" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.kibana.node_port.enabled }} type: NodePort {{ end }} ================================================ FILE: kibana/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- labels: kibana: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: apache_proxy: docker.io/library/httpd:2.4 kibana: docker.elastic.co/kibana/kibana:8.19.9 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 register_kibana_indexes: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble flush_kibana_metadata: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync pod: security_context: dashboard: pod: runAsUser: 1000 container: apache_proxy: runAsUser: 0 readOnlyRootFilesystem: false kibana: runAsNonRoot: true allowPrivilegeEscalation: false readOnlyRootFilesystem: false register_kibana_indexes: pod: runAsUser: 1000 container: register_kibana_indexes: allowPrivilegeEscalation: false readOnlyRootFilesystem: true flush_kibana_metadata: pod: runAsUser: 1000 container: flush_kibana_metadata: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 lifecycle: upgrades: deployments: pod_replacement_strategy: RollingUpdate revision_history: 3 rolling_update: max_surge: 3 max_unavailable: 1 replicas: kibana: 1 resources: enabled: false apache_proxy: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" kibana: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" register_kibana_indexes: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" flush_kibana_metadata: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" probes: kibana: kibana: liveness: enabled: true params: initialDelaySeconds: 180 periodSeconds: 60 readiness: enabled: true params: initialDelaySeconds: 20 periodSeconds: 30 network_policy: kibana: ingress: - {} egress: - {} secrets: elasticsearch: user: kibana-elasticsearch-user oci_image_registry: kibana: kibana-oci-image-registry-key tls: kibana: kibana: public: kibana-tls-public dependencies: dynamic: common: local_image_registry: jobs: - kibana-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry kibana: jobs: - flush-kibana-metadata services: - endpoint: internal service: elasticsearch register_kibana_indexes: jobs: - flush-kibana-metadata services: - endpoint: internal service: kibana flush_kibana_metadata: services: - endpoint: internal service: elasticsearch jobs: flush_kibana_metadata: backoffLimit: 6 activeDeadlineSeconds: 600 conf: httpd: | ServerRoot "/usr/local/apache2" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule remoteip_module modules/mod_remoteip.so LoadModule slotmem_shm_module modules/mod_slotmem_shm.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so User daemon Group daemon AllowOverride none Require all denied Require all denied ErrorLog /dev/stderr LogLevel warn LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout common CustomLog /dev/stdout combined CustomLog /dev/stdout proxy env=forwarded AllowOverride None Options None Require all granted RequestHeader unset Proxy early Include conf/extra/proxy-html.conf RemoteIPHeader X-Original-Forwarded-For ProxyPass http://localhost:{{ tuple "kibana" "internal" "kibana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ ProxyPassReverse http://localhost:{{ tuple "kibana" "internal" "kibana" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ AuthName "Kibana" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user kibana: elasticsearch: pingTimeout: 1500 requestTimeout: 30000 shardTimeout: 0 ops: interval: 5000 server: rewriteBasePath: false host: localhost name: kibana maxPayload: 1048576 port: 5601 ssl: enabled: false create_kibana_indexes: indexes: base: - logstash - journal - kernel application: - openstack default_index: logstash endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false kibana: username: kibana password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null elasticsearch: name: elasticsearch namespace: null auth: admin: username: admin password: changeme secret: tls: internal: elasticsearch-tls-api hosts: default: elasticsearch-logging public: elasticsearch host_fqdn_override: default: null path: default: null scheme: default: http port: client: default: 80 kibana: name: kibana namespace: null hosts: default: kibana-dash public: kibana host_fqdn_override: default: null # NOTE(srwilkers): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: http port: kibana: default: 5601 http: default: 80 ldap: hosts: default: ldap auth: admin: bind: "cn=admin,dc=cluster,dc=local" password: password host_fqdn_override: default: null path: default: "/ou=People,dc=cluster,dc=local" scheme: default: ldap port: ldap: default: 389 network: kibana: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/affinity: cookie nginx.ingress.kubernetes.io/session-cookie-name: kube-ingress-session-kibana nginx.ingress.kubernetes.io/session-cookie-hash: sha1 nginx.ingress.kubernetes.io/session-cookie-expires: "600" nginx.ingress.kubernetes.io/session-cookie-max-age: "600" haproxy.org/path-rewrite: / haproxy.org/cookie-persistence: "kube-ingress-session-kibana" node_port: enabled: false port: 30905 port: 5601 manifests: configmap_bin: true configmap_etc: true deployment: true ingress: true job_image_repo_sync: true network_policy: false secret_elasticsearch: true secret_ingress_tls: true secret_registry: true service: true service_ingress: true job_register_kibana_indexes: true job_flush_kibana_metadata: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: kube-dns/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.14.5 description: OpenStack-Helm Kube-DNS name: kube-dns version: 2025.2.0 home: https://github.com/coreos/flannel icon: https://raw.githubusercontent.com/coreos/flannel/master/logos/flannel-horizontal-color.png sources: - https://github.com/coreos/flannel - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: kube-dns/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: kube-dns-bin data: image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: kube-dns/templates/configmap-kube-dns.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_kube_dns }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: kube-dns labels: addonmanager.kubernetes.io/mode: EnsureExists {{- end }} ================================================ FILE: kube-dns/templates/deployment-kube-dns.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_kube_dns }} {{- $envAll := . }} --- apiVersion: apps/v1 kind: Deployment metadata: annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: k8s-app: kube-dns {{ tuple $envAll "kubernetes" "dns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} name: kube-dns spec: replicas: 1 selector: matchLabels: k8s-app: kube-dns {{ tuple $envAll "kubernetes" "dns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} strategy: rollingUpdate: maxSurge: 10% maxUnavailable: 0 type: RollingUpdate template: metadata: labels: k8s-app: kube-dns {{ tuple $envAll "kubernetes" "dns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/arch operator: In values: - amd64 containers: - name: kubedns {{ tuple $envAll "kube_dns" | include "helm-toolkit.snippets.image" | indent 10 }} args: - --domain={{ .Values.networking.dnsDomain }}. - --dns-port=10053 - --config-dir=/kube-dns-config - --v=2 env: - name: PROMETHEUS_PORT value: "10055" livenessProbe: failureThreshold: 5 httpGet: path: /healthcheck/kubedns port: 10054 scheme: HTTP initialDelaySeconds: 60 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 ports: - containerPort: 10053 name: dns-local protocol: UDP - containerPort: 10053 name: dns-tcp-local protocol: TCP - containerPort: 10055 name: metrics protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /readiness port: 8081 scheme: HTTP initialDelaySeconds: 3 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 resources: limits: memory: 170Mi requests: cpu: 100m memory: 70Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - name: pod-tmp mountPath: /tmp - mountPath: /kube-dns-config name: kube-dns-config - name: dnsmasq {{ tuple $envAll "kube_dns_nanny" | include "helm-toolkit.snippets.image" | indent 10 }} args: - -v=2 - -logtostderr - -configDir=/etc/k8s/dns/dnsmasq-nanny - -restartDnsmasq=true - -- - -k - --cache-size=1000 - --log-facility=- - --server=/{{ .Values.networking.dnsDomain }}/127.0.0.1#10053 - --server=/in-addr.arpa/127.0.0.1#10053 - --server=/ip6.arpa/127.0.0.1#10053 livenessProbe: failureThreshold: 5 httpGet: path: /healthcheck/dnsmasq port: 10054 scheme: HTTP initialDelaySeconds: 60 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP resources: requests: cpu: 150m memory: 20Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - name: pod-tmp mountPath: /tmp - mountPath: /etc/k8s/dns/dnsmasq-nanny name: kube-dns-config - name: sidecar {{ tuple $envAll "kube_dns_sidecar" | include "helm-toolkit.snippets.image" | indent 10 }} args: - --v=2 - --logtostderr - --probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.{{ .Values.networking.dnsDomain }},5,A - --probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.{{ .Values.networking.dnsDomain }},5,A livenessProbe: failureThreshold: 5 httpGet: path: /metrics port: 10054 scheme: HTTP initialDelaySeconds: 60 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 ports: - containerPort: 10054 name: metrics protocol: TCP resources: requests: cpu: 10m memory: 20Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: {{ .Values.pod.dns_policy }} restartPolicy: Always schedulerName: default-scheduler securityContext: {} serviceAccount: kube-dns serviceAccountName: kube-dns terminationGracePeriodSeconds: 30 tolerations: - key: CriticalAddonsOnly operator: Exists - effect: NoSchedule key: node-role.kubernetes.io/master - effect: NoSchedule key: node-role.kubernetes.io/control-plane volumes: - name: pod-tmp emptyDir: {} - configMap: defaultMode: 420 name: kube-dns optional: true name: kube-dns-config {{- end }} ================================================ FILE: kube-dns/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: kube-dns/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "kube-dns" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: kube-dns/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: kube-dns/templates/service-kube-dns.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_kube_dns }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" kubernetes.io/name: KubeDNS {{ tuple $envAll "kubernetes" "dns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} name: kube-dns spec: type: ClusterIP clusterIP: {{ .Values.networking.dnsIP }} sessionAffinity: None ports: - name: dns port: 53 protocol: UDP targetPort: 53 - name: dns-tcp port: 53 protocol: TCP targetPort: 53 selector: k8s-app: kube-dns {{ tuple $envAll "kubernetes" "dns" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: kube-dns/templates/serviceaccount-kube-dns.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.serviceaccount_kube_dns }} {{- $envAll := . }} --- apiVersion: v1 kind: ServiceAccount metadata: name: kube-dns labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile {{- if $envAll.Values.manifests.secret_registry }} {{- if $envAll.Values.endpoints.oci_image_registry.auth.enabled }} imagePullSecrets: - name: {{ index $envAll.Values.secrets.oci_image_registry $envAll.Chart.Name }} {{- end -}} {{- end -}} {{- end }} ================================================ FILE: kube-dns/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # https://raw.githubusercontent.com/coreos/flannel/v0.8.0/Documentation/kube-flannel.yml --- labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: kube_dns: registry.k8s.io/k8s-dns-kube-dns-amd64:1.14.5 kube_dns_nanny: registry.k8s.io/k8s-dns-dnsmasq-nanny-amd64:1.14.5 kube_dns_sidecar: registry.k8s.io/k8s-dns-sidecar-amd64:1.14.5 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync pod: dns_policy: "Default" resources: enabled: false jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" networking: dnsDomain: cluster.local dnsIP: 10.96.0.10 dependencies: dynamic: common: local_image_registry: jobs: - kube-dns-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry kube_dns: services: null secrets: oci_image_registry: kube-dns: kube-dns-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false kube-dns: username: kube-dns password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null manifests: configmap_bin: true configmap_kube_dns: true deployment_kube_dns: true job_image_repo_sync: true secret_registry: true service_kube_dns: true serviceaccount_kube_dns: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: kubernetes-keystone-webhook/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v0.2.0 description: OpenStack-Helm Kubernetes keystone webhook name: kubernetes-keystone-webhook version: 2025.2.0 home: https://github.com/kubernetes/cloud-provider-openstack sources: - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: kubernetes-keystone-webhook/templates/bin/_kubernetes-keystone-webhook-test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex TOKEN="$(openstack token issue -f value -c id)" cat << EOF | curl -kvs -XPOST -d @- "${WEBHOOK_URL}" | python -mjson.tool { "apiVersion": "authentication.k8s.io/v1beta1", "kind": "TokenReview", "metadata": { "creationTimestamp": null }, "spec": { "token": "$TOKEN" } } EOF ================================================ FILE: kubernetes-keystone-webhook/templates/bin/_start.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -xe exec /bin/k8s-keystone-auth \ --tls-cert-file /opt/kubernetes-keystone-webhook/pki/tls.crt \ --tls-private-key-file /opt/kubernetes-keystone-webhook/pki/tls.key \ --keystone-policy-file /etc/kubernetes-keystone-webhook/policy.json \ --keystone-url {{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} ================================================ FILE: kubernetes-keystone-webhook/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . -}} --- apiVersion: v1 kind: ConfigMap metadata: name: kubernetes-keystone-webhook-bin data: start.sh: | {{ tuple "bin/_start.sh.tpl" $envAll | include "helm-toolkit.utils.template" | indent 4 }} kubernetes-keystone-webhook-test.sh: | {{ tuple "bin/_kubernetes-keystone-webhook-test.sh.tpl" $envAll | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . -}} --- apiVersion: v1 kind: ConfigMap metadata: name: kubernetes-keystone-webhook-etc data: policy.json: | {{ toPrettyJson $envAll.Values.conf.policy | indent 4 }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} --- apiVersion: apps/v1 kind: Deployment metadata: name: kubernetes-keystone-webhook annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "kubernetes-keystone-webhook" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ $envAll.Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "kubernetes-keystone-webhook" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "kubernetes-keystone-webhook" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "kubernetes-keystone-webhook" "containerNames" (list "kubernetes-keystone-webhook") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "kubernetes_keystone_webhook" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} containers: - name: kubernetes-keystone-webhook {{ tuple $envAll "kubernetes_keystone_webhook" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "kubernetes_keystone_webhook" "container" "kubernetes_keystone_webhook" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/start.sh readinessProbe: tcpSocket: port: {{ tuple "kubernetes_keystone_webhook" "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 15 periodSeconds: 10 ports: - name: k8sksauth-pub containerPort: {{ tuple "kubernetes_keystone_webhook" "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: etc-kubernetes-keystone-webhook mountPath: /etc/kubernetes-keystone-webhook - name: key-kubernetes-keystone-webhook mountPath: /opt/kubernetes-keystone-webhook/pki/tls.crt subPath: tls.crt readOnly: true - name: key-kubernetes-keystone-webhook mountPath: /opt/kubernetes-keystone-webhook/pki/tls.key subPath: tls.key readOnly: true - name: kubernetes-keystone-webhook-etc mountPath: /etc/kubernetes-keystone-webhook/policy.json subPath: policy.json readOnly: true - name: kubernetes-keystone-webhook-bin mountPath: /tmp/start.sh subPath: start.sh readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: etc-kubernetes-keystone-webhook emptyDir: {} - name: key-kubernetes-keystone-webhook secret: secretName: {{ $envAll.Values.secrets.certificates.api }} defaultMode: 0444 - name: kubernetes-keystone-webhook-etc configMap: name: kubernetes-keystone-webhook-etc defaultMode: 0444 - name: kubernetes-keystone-webhook-bin configMap: name: kubernetes-keystone-webhook-bin defaultMode: 0555 {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: kubernetes-keystone-webhook/templates/ingress.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_webhook .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendService" "api" "backendServiceType" "kubernetes_keystone_webhook" "backendPort" "k8sksauth-pub" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $mounts_kubernetes_keystone_webhook_tests := $envAll.Values.pod.mounts.kubernetes_keystone_webhook_tests.kubernetes_keystone_webhook_tests }} {{- $mounts_kubernetes_keystone_webhook_tests_init := $envAll.Values.pod.mounts.kubernetes_keystone_webhook_tests.init_container }} {{- $serviceAccountName := print $envAll.Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{ $envAll.Release.Name }}-test" annotations: "helm.sh/hook": test-success spec: serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ $envAll.Values.labels.test.node_selector_key }}: {{ $envAll.Values.labels.test.node_selector_value | quote }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" $mounts_kubernetes_keystone_webhook_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: {{ $envAll.Release.Name }}-kubernetes-keystone-webhook-test {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: - name: WEBHOOK_URL value: {{ tuple "kubernetes_keystone_webhook" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} command: - /tmp/kubernetes-keystone-webhook-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: kubernetes-keystone-webhook-bin mountPath: /tmp/kubernetes-keystone-webhook-test.sh subPath: kubernetes-keystone-webhook-test.sh readOnly: true {{ if $mounts_kubernetes_keystone_webhook_tests.volumeMounts }}{{ toYaml $mounts_kubernetes_keystone_webhook_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: kubernetes-keystone-webhook-bin configMap: name: kubernetes-keystone-webhook-bin defaultMode: 0555 {{ if $mounts_kubernetes_keystone_webhook_tests.volumes }}{{ toYaml $mounts_kubernetes_keystone_webhook_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/secret-certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_certificates }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ $envAll.Values.secrets.certificates.api }} type: kubernetes.io/tls data: tls.crt: {{ $envAll.Values.endpoints.kubernetes.auth.api.tls.crt | default "" | b64enc }} tls.key: {{ $envAll.Values.endpoints.kubernetes.auth.api.tls.key | default "" | b64enc }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendService" "api" "backendServiceType" "kubernetes_keystone_webhook" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "kubernetes_keystone_webhook" "internal" $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: k8sksauth-pub port: {{ tuple "kubernetes_keystone_webhook" "internal" "api" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "kubernetes-keystone-webhook" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: kubernetes-keystone-webhook/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: kubernetes_keystone_webhook: docker.io/k8scloudprovider/k8s-keystone-auth:v1.19.0 scripted_test: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / nginx.ingress.kubernetes.io/secure-backends: "true" external_policy_local: false node_port: enabled: false port: 30601 pod: security_context: kubernetes_keystone_webhook: pod: runAsUser: 65534 container: kubernetes_keystone_webhook: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: api: 1 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "200m" jobs: tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "200m" mounts: kubernetes_keystone_webhook_api: init_container: null kubernetes_keystone_webhook_api: null kubernetes_keystone_webhook_tests: init_container: null kubernetes_keystone_webhook_tests: null release_group: null conf: policy: - resource: verbs: - "*" resources: - "*" namespace: "*" version: "*" match: - type: role values: - admin - resource: verbs: - "*" resources: - "*" namespace: "kube-system" version: "*" match: - type: role values: - kube-system-admin - resource: verbs: - get - list - watch resources: - "*" namespace: "kube-system" version: "*" match: - type: role values: - kube-system-viewer - resource: verbs: - "*" resources: - "*" namespace: "openstack" version: "*" match: - type: project values: - openstack-system - resource: verbs: - "*" resources: - "*" namespace: "*" version: "*" match: - type: role values: - admin_k8cluster - nonresource: verbs: - "*" path: "*" match: - type: role values: - admin_k8cluster - resource: resources: - pods - pods/attach - pods/exec - pods/portforward - pods/proxy - configmaps - endpoints - persistentvolumeclaims - replicationcontrollers - replicationcontrollers/scale - secrets - serviceaccounts - services - services/proxy verbs: - create - delete - deletecollection - get - list - patch - update - watch namespace: "*" version: "" match: - type: role values: - admin_k8cluster_editor - resource: resources: - bindings - events - limitranges - namespaces/status - pods/log - pods/status - replicationcontrollers/status - resourcequotas - resourcequotas/status - namespaces verbs: - get - list - watch namespace: "*" version: "" match: - type: role values: - admin_k8cluster_editor - resource: resources: - serviceaccounts verbs: - impersonate namespace: "*" version: "" match: - type: role values: - admin_k8cluster_editor - resource: resources: - daemonsets - deployments - deployments/rollback - deployments/scale - replicasets - replicasets/scale - statefulsets verbs: - create - delete - deletecollection - get - list - patch - update - watch namespace: "*" version: "apps" match: - type: role values: - admin_k8cluster_editor - resource: resources: - horizontalpodautoscalers verbs: - create - delete - deletecollection - get - list - patch - update - watch namespace: "*" version: "autoscaling" match: - type: role values: - admin_k8cluster_editor - resource: resources: - cronjobs - jobs verbs: - create - delete - deletecollection - get - list - patch - update - watch namespace: "*" version: "batch" match: - type: role values: - admin_k8cluster_editor - resource: resources: - daemonsets - deployments - deployments/rollback - deployments/scale - ingresses - networkpolicies - replicasets - replicasets/scale - replicationcontrollers/scale verbs: - create - delete - deletecollection - get - list - patch - update - watch namespace: "*" version: "extensions" match: - type: role values: - admin_k8cluster_editor - resource: resources: - poddisruptionbudgets verbs: - create - delete - deletecollection - get - list - patch - update - watch namespace: "*" version: "policy" match: - type: role values: - admin_k8cluster_editor - resource: resources: - networkpolicies verbs: - create - delete - deletecollection - get - list - patch - update - watch namespace: "*" version: "networking.k8s.io" match: - type: role values: - admin_k8cluster_editor - resource: resources: - configmaps - endpoints - persistentvolumeclaims - pods - replicationcontrollers - replicationcontrollers/scale - serviceaccounts - services - bindings - events - limitranges - namespaces/status - pods/log - pods/status - replicationcontrollers/status - resourcequotas - resourcequotas/status - namespaces verbs: - get - list - watch namespace: "*" version: "" match: - type: role values: - admin_k8cluster_viewer - resource: resources: - daemonsets - deployments - deployments/scale - replicasets - replicasets/scale - statefulsets verbs: - get - list - watch namespace: "*" version: "apps" match: - type: role values: - admin_k8cluster_viewer - resource: resources: - horizontalpodautoscalers verbs: - get - list - watch namespace: "*" version: "autoscaling" match: - type: role values: - admin_k8cluster_viewer - resource: resources: - cronjobs - jobs verbs: - get - list - watch namespace: "*" version: "batch" match: - type: role values: - admin_k8cluster_viewer - resource: resources: - daemonsets - deployments - deployments/scale - ingresses - networkpolicies - replicasets - replicasets/scale - replicationcontrollers/scale verbs: - get - list - watch namespace: "*" version: "extensions" match: - type: role values: - admin_k8cluster_viewer - resource: resources: - poddisruptionbudgets verbs: - get - list - watch namespace: "*" version: "policy" match: - type: role values: - admin_k8cluster_viewer - resource: resources: - networkpolicies verbs: - get - list - watch namespace: "*" version: "networking.k8s.io" match: - type: role values: - admin_k8cluster_viewer secrets: identity: admin: kubernetes-keystone-webhook-admin certificates: api: kubernetes-keystone-webhook-certs oci_image_registry: kubernetes-keystone-webhook: kubernetes-keystone-webhook-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false kubernetes-keystone-webhook: username: kubernetes-keystone-webhook password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null kubernetes: auth: api: tls: crt: null key: null identity: name: keystone namespace: null auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 kubernetes_keystone_webhook: namespace: null name: k8sksauth hosts: default: k8sksauth-api public: k8sksauth host_fqdn_override: default: null path: default: /webhook scheme: default: https port: api: default: 8443 public: 443 dependencies: dynamic: common: local_image_registry: jobs: - k8sksauth-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: null services: null manifests: api_secret: true configmap_etc: true configmap_bin: true deployment: true ingress_webhook: true pod_test: true secret_certificates: true secret_keystone: true secret_registry: true service_ingress_api: true service: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: kubernetes-node-problem-detector/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Kubernetes Node Problem Detector name: kubernetes-node-problem-detector version: 2025.2.0 home: https://github.com/kubernetes/node-problem-detector sources: - https://github.com/kubernetes/node-problem-detector - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: kubernetes-node-problem-detector/templates/bin/_node-problem-detector.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec /opt/node-problem-detector/bin/node-problem-detector \ {{- range $monitor, $monitorConfig := .Values.conf.monitors }} {{- if $monitorConfig.enabled }} --config.{{$monitor}}={{ include "helm-toolkit.utils.joinListWithComma" $monitorConfig.enabled }} \ {{- end }} {{- end }} --logtostderr \ --prometheus-address=0.0.0.0 ================================================ FILE: kubernetes-node-problem-detector/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: node-problem-detector-bin data: node-problem-detector.sh: | {{ tuple "bin/_node-problem-detector.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- range $monitor, $monitorConfig := $envAll.Values.conf.monitors }} {{- $scripts := $monitorConfig.scripts }} {{- range $script, $scriptSource := $scripts.source }} {{- if has $script $scripts.enabled }} {{$script}}: | {{$scriptSource | indent 4 -}} {{- end }} {{- end -}} {{- end -}} {{- end }} ================================================ FILE: kubernetes-node-problem-detector/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: node-problem-detector-etc type: Opaque data: {{- range $monitor, $monitorConfig := $envAll.Values.conf.monitors }} {{- $plugins := $monitorConfig.config }} {{- range $plugin, $config := $plugins }} {{$plugin}}.json: {{ toJson $config | b64enc }} {{- end }} {{ end }} {{- end }} ================================================ FILE: kubernetes-node-problem-detector/templates/daemonset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "node-problem-detector" }} {{ tuple $envAll "node_problem_detector" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: run-node-problem-detector subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: DaemonSet metadata: name: node-problem-detector annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "node_problem_detector" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "node_problem_detector" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "node_problem_detector" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "node_problem_detector" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{- if .Values.monitoring.prometheus.pod.enabled }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.node_problem_detector }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_pod_annotations" | indent 8 }} {{- end }} {{ dict "envAll" $envAll "podName" "node-problem-detector" "containerNames" (list "node-problem-detector") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: {{ dict "envAll" $envAll "application" "node_problem_detector" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if .Values.pod.tolerations.node_problem_detector.enabled }} {{ tuple $envAll "node_exporter" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ else }} nodeSelector: {{ .Values.labels.node_problem_detector.node_selector_key }}: {{ .Values.labels.node_problem_detector.node_selector_value | quote }} {{ end }} containers: - name: node-problem-detector {{ tuple $envAll "node_problem_detector" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.node_problem_detector | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "node_problem_detector" "container" "node_problem_detector" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/node-problem-detector.sh ports: - name: metrics containerPort: {{ tuple "node_problem_detector" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: log mountPath: /var/log readOnly: true - name: kmsg mountPath: /dev/kmsg readOnly: true - name: localtime mountPath: /etc/localtime readOnly: true - name: node-problem-detector-bin mountPath: /tmp/node-problem-detector.sh subPath: node-problem-detector.sh readOnly: true {{- range $monitor, $monitorConfig := $envAll.Values.conf.monitors }} {{- $scripts := $monitorConfig.scripts }} {{- range $script, $scriptSource := $scripts.source }} {{- if has $script $scripts.enabled }} - name: node-problem-detector-bin mountPath: /config/plugin/{{$script}} subPath: {{$script}} {{- end }} {{- end }} {{- end }} {{- range $monitor, $monitorConfig := $envAll.Values.conf.monitors }} {{- $plugins := $monitorConfig.config }} {{- range $plugin, $config := $plugins }} - name: node-problem-detector-etc mountPath: /config/{{$plugin}}.json subPath: {{$plugin}}.json {{- end }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: log hostPath: path: /var/log - name: kmsg hostPath: path: /dev/kmsg - name: localtime hostPath: path: /etc/localtime - name: node-problem-detector-etc secret: secretName: node-problem-detector-etc defaultMode: 292 - name: node-problem-detector-bin configMap: name: node-problem-detector-bin defaultMode: 365 {{- end }} ================================================ FILE: kubernetes-node-problem-detector/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: kubernetes-node-problem-detector/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "node-problem-detector" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: kubernetes-node-problem-detector/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: kubernetes-node-problem-detector/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.node_problem_detector }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "node_problem_detector" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "node_problem_detector" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.service.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: type: ClusterIP clusterIP: None ports: - name: metrics port: {{ tuple "node_problem_detector" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "node_problem_detector" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "node_problem_detector" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: kubernetes-node-problem-detector/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for node-exporter. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: node_problem_detector: quay.io/airshipit/node-problem-detector:latest-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync labels: node_problem_detector: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled secrets: oci_image_registry: kubernetes-node-problem-detector: kubernetes-node-problem-detector-oci-image-registry-key pod: security_context: node_problem_detector: pod: runAsUser: 0 container: node_problem_detector: readOnlyRootFilesystem: true privileged: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname mounts: node_problem_detector: node_problem_detector: init_container: null lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate node_problem_detector: enabled: true min_ready_seconds: 0 revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: node_problem_detector: timeout: 30 resources: enabled: false node_problem_detector: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tolerations: node_problem_detector: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/control-plane operator: Exists - key: node-role.kubernetes.io/node operator: Exists dependencies: dynamic: common: local_image_registry: jobs: - node-exporter-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry node_problem_detector: services: null monitoring: prometheus: pod: enabled: true service: enabled: false node_problem_detector: scrape: true port: 20257 endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false kubernetes-node-problem-detector: username: kubernetes-node-problem-detector password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null node_problem_detector: name: node-problem-detector namespace: null hosts: default: node-problem-detector host_fqdn_override: default: null path: default: null port: metrics: default: 20257 manifests: configmap_bin: true configmap_etc: true daemonset: true job_image_repo_sync: true secret_registry: true service: false conf: monitors: system-log-monitor: enabled: - /config/kernel-monitor.json - /config/docker-monitor.json - /config/systemd-monitor.json scripts: enabled: null source: null config: kernel-monitor: plugin: kmsg logPath: "/dev/kmsg" lookback: 5m bufferSize: 10 source: kernel-monitor conditions: - type: KernelDeadlock reason: KernelHasNoDeadlock message: kernel has no deadlock - type: ReadonlyFilesystem reason: FilesystemIsNotReadOnly message: Filesystem is not read-only rules: - type: temporary reason: OOMKilling pattern: Kill process \d+ (.+) score \d+ or sacrifice child\nKilled process \d+ (.+) total-vm:\d+kB, anon-rss:\d+kB, file-rss:\d+kB.* - type: temporary reason: TaskHung pattern: task \S+:\w+ blocked for more than \w+ seconds\. - type: temporary reason: UnregisterNetDevice pattern: 'unregister_netdevice: waiting for \w+ to become free. Usage count = \d+' - type: temporary reason: KernelOops pattern: 'BUG: unable to handle kernel NULL pointer dereference at .*' - type: temporary reason: KernelOops pattern: 'divide error: 0000 \[#\d+\] SMP' - type: permanent condition: KernelDeadlock reason: AUFSUmountHung pattern: task umount\.aufs:\w+ blocked for more than \w+ seconds\. - type: permanent condition: KernelDeadlock reason: DockerHung pattern: task docker:\w+ blocked for more than \w+ seconds\. - type: permanent condition: ReadonlyFilesystem reason: FilesystemIsReadOnly pattern: Remounting filesystem read-only kernel-monitor-filelog: plugin: filelog pluginConfig: timestamp: "^.{15}" message: 'kernel: \[.*\] (.*)' timestampFormat: Jan _2 15:04:05 logPath: "/var/log/kern.log" lookback: 5m bufferSize: 10 source: kernel-monitor conditions: - type: KernelDeadlock reason: KernelHasNoDeadlock message: kernel has no deadlock rules: - type: temporary reason: OOMKilling pattern: Kill process \d+ (.+) score \d+ or sacrifice child\nKilled process \d+ (.+) total-vm:\d+kB, anon-rss:\d+kB, file-rss:\d+kB.* - type: temporary reason: TaskHung pattern: task \S+:\w+ blocked for more than \w+ seconds\. - type: temporary reason: UnregisterNetDevice pattern: 'unregister_netdevice: waiting for \w+ to become free. Usage count = \d+' - type: temporary reason: KernelOops pattern: 'BUG: unable to handle kernel NULL pointer dereference at .*' - type: temporary reason: KernelOops pattern: 'divide error: 0000 \[#\d+\] SMP' - type: permanent condition: KernelDeadlock reason: AUFSUmountHung pattern: task umount\.aufs:\w+ blocked for more than \w+ seconds\. - type: permanent condition: KernelDeadlock reason: DockerHung pattern: task docker:\w+ blocked for more than \w+ seconds\. kernel-monitor-counter: plugin: custom pluginConfig: invoke_interval: 5m timeout: 1m max_output_length: 80 concurrency: 1 source: kernel-monitor conditions: - type: FrequentUnregisterNetDevice reason: NoFrequentUnregisterNetDevice message: node is functioning properly rules: - type: permanent condition: FrequentUnregisterNetDevice reason: UnregisterNetDevice path: "/home/kubernetes/bin/log-counter" args: - "--journald-source=kernel" - "--log-path=/var/log/journal" - "--lookback=20m" - "--count=3" - "--pattern=unregister_netdevice: waiting for \\w+ to become free. Usage count = \\d+" timeout: 1m docker-monitor: plugin: journald pluginConfig: source: dockerd logPath: "/var/log/journal" lookback: 5m bufferSize: 10 source: docker-monitor conditions: [] rules: - type: temporary reason: CorruptDockerImage pattern: 'Error trying v2 registry: failed to register layer: rename /var/lib/docker/image/(.+) /var/lib/docker/image/(.+): directory not empty.*' docker-monitor-filelog: plugin: filelog pluginConfig: timestamp: ^time="(\S*)" message: |- msg="([^ ]*)" timestampFormat: '2006-01-02T15:04:05.999999999-07:00' logPath: "/var/log/docker.log" lookback: 5m bufferSize: 10 source: docker-monitor conditions: [] rules: - type: temporary reason: CorruptDockerImage pattern: 'Error trying v2 registry: failed to register layer: rename /var/lib/docker/image/(.+) /var/lib/docker/image/(.+): directory not empty.*' docker-monitor-counter: plugin: custom pluginConfig: invoke_interval: 5m timeout: 1m max_output_length: 80 concurrency: 1 source: docker-monitor conditions: - type: CorruptDockerOverlay2 reason: NoCorruptDockerOverlay2 message: docker overlay2 is functioning properly rules: - type: permanent condition: CorruptDockerOverlay2 reason: CorruptDockerOverlay2 path: "/home/kubernetes/bin/log-counter" args: - "--journald-source=dockerd" - "--log-path=/var/log/journal" - "--lookback=5m" - "--count=10" - "--pattern=returned error: readlink /var/lib/docker/overlay2.*: invalid argument.*" timeout: 1m systemd-monitor: plugin: journald pluginConfig: source: systemd logPath: "/var/log/journal" lookback: 5m bufferSize: 10 source: systemd-monitor conditions: [] rules: - type: temporary reason: KubeletStart pattern: Started Kubernetes kubelet. - type: temporary reason: DockerStart pattern: Starting Docker Application Container Engine... - type: temporary reason: ContainerdStart pattern: Starting containerd container runtime... systemd-monitor-counter: plugin: custom pluginConfig: invoke_interval: 5m timeout: 1m max_output_length: 80 concurrency: 1 source: systemd-monitor conditions: - type: FrequentKubeletRestart reason: NoFrequentKubeletRestart message: kubelet is functioning properly - type: FrequentDockerRestart reason: NoFrequentDockerRestart message: docker is functioning properly - type: FrequentContainerdRestart reason: NoFrequentContainerdRestart message: containerd is functioning properly rules: - type: permanent condition: FrequentKubeletRestart reason: FrequentKubeletRestart path: "/home/kubernetes/bin/log-counter" args: - "--journald-source=systemd" - "--log-path=/var/log/journal" - "--lookback=20m" - "--delay=5m" - "--count=5" - "--pattern=Started Kubernetes kubelet." timeout: 1m - type: permanent condition: FrequentDockerRestart reason: FrequentDockerRestart path: "/home/kubernetes/bin/log-counter" args: - "--journald-source=systemd" - "--log-path=/var/log/journal" - "--lookback=20m" - "--count=5" - "--pattern=Starting Docker Application Container Engine..." timeout: 1m - type: permanent condition: FrequentContainerdRestart reason: FrequentContainerdRestart path: "/home/kubernetes/bin/log-counter" args: - "--journald-source=systemd" - "--log-path=/var/log/journal" - "--lookback=20m" - "--count=5" - "--pattern=Starting containerd container runtime..." timeout: 1m custom-plugin-monitor: enabled: - /config/network-problem-monitor.json scripts: enabled: - network_problem.sh source: network_problem.sh: | #!/bin/bash # This plugin checks for common network issues. Currently, it only checks # if the conntrack table is 50% full. set -eu set -o pipefail conntrack_threshold=$(($(cat /proc/sys/net/netfilter/nf_conntrack_max)/2 )) conntrack_count=$(cat /proc/sys/net/netfilter/nf_conntrack_count) if [ "$conntrack_count" -ge "$conntrack_threshold" ]; then echo "Conntrack table approaching full" exit 1 fi exit 0 config: network-problem-monitor: plugin: custom pluginConfig: invoke_interval: 30s timeout: 5s max_output_length: 80 concurrency: 3 source: network-custom-plugin-monitor conditions: [] rules: - type: temporary reason: ConntrackFull path: "./config/plugin/network_problem.sh" timeout: 3s system-stats-monitor: enabled: - /config/system-stats-monitor.json scripts: enabled: null source: null config: system-stats-monitor: disk: metricsConfigs: disk/io_time: displayName: disk/io_time disk/weighted_io: displayName: disk/weighted_io disk/avg_queue_len: displayName: disk/avg_queue_len includeRootBlk: true includeAllAttachedBlk: true lsblkTimeout: 5s invokeInterval: 60s # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ldap/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.pyc *.bak *.tmp *~ # Various IDEs .project .idea/ *.tmproj ================================================ FILE: ldap/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.2.0 description: OpenStack-Helm LDAP name: ldap version: 2025.2.0 home: https://www.openldap.org/ maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ldap/templates/_helpers.tpl ================================================ {{/* vim: set filetype=mustache: */}} {{/* Expand the name of the chart. */}} {{- define "name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). */}} {{- define "fullname" -}} {{- $name := default .Chart.Name .Values.nameOverride -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- end -}} {{- define "splitdomain" -}} {{- $name := index . 0 -}} {{- $local := dict "first" true }} {{- range $k, $v := splitList "." $name }}{{- if not $local.first -}},{{- end -}}dc={{- $v -}}{{- $_ := set $local "first" false -}}{{- end -}} {{- end -}} ================================================ FILE: ldap/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash set -xe {{- $url := tuple "ldap" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- $port := tuple "ldap" "internal" "ldap" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} LDAPHOST="{{ .Values.endpoints.ldap.scheme }}://{{ $url }}:{{ $port }}" ADMIN="cn={{ .Values.secrets.identity.admin }},{{ tuple .Values.openldap.domain . | include "splitdomain" }}" PASSWORD="{{ .Values.openldap.password }}" # Wait for LDAP server to be ready retries=0 max_retries=60 until ldapsearch -x -H $LDAPHOST -b "" -s base "(objectclass=*)" namingContexts 2>/dev/null | grep -q namingContexts; do retries=$((retries + 1)) if [ $retries -ge $max_retries ]; then echo "ERROR: LDAP server not reachable after $max_retries attempts" exit 1 fi echo "Waiting for LDAP server to be ready... ($retries/$max_retries)" sleep 5 done ldapadd -x -c -D $ADMIN -H $LDAPHOST -w $PASSWORD -f /etc/sample_data.ldif ================================================ FILE: ldap/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} --- apiVersion: v1 kind: ConfigMap metadata: name: ldap-bin data: {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- end }} ================================================ FILE: ldap/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} --- apiVersion: v1 kind: Secret metadata: name: ldap-etc type: Opaque data: {{- if .Values.bootstrap.enabled }} sample_data.ldif: {{ .Values.data.sample | b64enc }} {{- end }} {{- end }} ================================================ FILE: ldap/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ldap/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "ldap" "configFile" "/etc/sample_data.ldif" "keystoneUser" "admin" "openrc" "false" -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: ldap/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ldap" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: ldap/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "ldap" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: ldap/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: ldap/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "ldap" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: ldap port: {{ tuple "ldap" "internal" "ldap" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: ldap/templates/statefulset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset }} {{- $envAll := . }} {{- $serviceAccountName := "ldap" }} {{ tuple $envAll "ldap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: ldap annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: {{ tuple "ldap" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} replicas: {{ .Values.pod.replicas.server }} selector: matchLabels: {{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "ldap" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value | quote }} securityContext: fsGroup: 1001 initContainers: {{ tuple $envAll "ldap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 6 }} - name: ldap-perms {{ tuple $envAll "ldap" | include "helm-toolkit.snippets.image" | indent 8 }} securityContext: runAsUser: 0 command: - chown - -R - "1001:1001" - /openldap/data - /openldap/slapd.d volumeMounts: - name: ldap-data mountPath: /openldap/data - name: ldap-config mountPath: /openldap/slapd.d containers: - name: ldap {{ tuple $envAll "ldap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: LDAP_ROOT value: {{ tuple .Values.openldap.domain . | include "splitdomain" }} - name: LDAP_ADMIN_PASSWORD value: {{ .Values.openldap.password }} - name: LDAP_SKIP_DEFAULT_TREE value: "yes" ports: - containerPort: {{ tuple "ldap" "internal" "ldap" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "ldap" "internal" "ldap" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 5 periodSeconds: 10 volumeMounts: - name: pod-tmp mountPath: /tmp - name: ldap-data mountPath: /openldap/data - name: ldap-config mountPath: /openldap/slapd.d volumes: - name: pod-tmp emptyDir: {} {{- if not .Values.storage.pvc.enabled }} - name: ldap-data hostPath: path: {{ .Values.storage.host.data_path }} - name: ldap-config hostPath: path: {{ .Values.storage.host.config_path }} {{- else }} volumeClaimTemplates: - metadata: name: ldap-data spec: accessModes: ["ReadWriteOnce"] storageClassName: {{ .Values.storage.pvc.class_name }} resources: requests: storage: {{ .Values.storage.pvc.size }} - metadata: name: ldap-config spec: accessModes: ["ReadWriteOnce"] storageClassName: {{ .Values.storage.pvc.class_name }} resources: requests: storage: {{ .Values.storage.pvc.size }} {{- end }} {{- end }} ================================================ FILE: ldap/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for ldap. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: server: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 resources: enabled: false server: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" mounts: ldap_data_load: init_container: null ldap_data_load: images: tags: bootstrap: "symas/openldap:2.6.8-debian-12" ldap: "symas/openldap:2.6.8-debian-12" dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync dependencies: dynamic: common: local_image_registry: jobs: - ldap-image-repo-sync services: - endpoint: node service: local_image_registry static: ldap: jobs: null bootstrap: services: - endpoint: internal service: ldap server: jobs: - ldap-load-data services: - endpoint: internal service: ldap image_repo_sync: services: - endpoint: internal service: local_image_registry storage: pvc: enabled: true size: 2Gi class_name: general host: data_path: /data/openstack-helm/ldap config_path: /data/openstack-helm/config labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled bootstrap: enabled: false endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ldap: username: ldap password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null ldap: hosts: default: ldap host_fqdn_override: default: null path: null scheme: 'ldap' port: ldap: default: 1389 network_policy: ldap: ingress: - {} egress: - {} data: sample: | dn: dc=cluster,dc=local objectClass: top objectClass: dcObject objectClass: organization dc: cluster o: cluster dn: ou=People,dc=cluster,dc=local objectclass: organizationalunit ou: People description: We the People # NOTE: Password is "password" without quotes dn: uid=alice,ou=People,dc=cluster,dc=local objectClass: inetOrgPerson objectClass: top objectClass: posixAccount objectClass: shadowAccount objectClass: person sn: Alice cn: alice uid: alice userPassword: {SSHA}+i3t/DLCgLDGaIOAmfeFJ2kDeJWmPUDH description: SHA gidNumber: 1000 uidNumber: 1493 homeDirectory: /home/alice mail: alice@example.com # NOTE: Password is "password" without quotes dn: uid=bob,ou=People,dc=cluster,dc=local objectClass: inetOrgPerson objectClass: top objectClass: posixAccount objectClass: shadowAccount objectClass: person sn: Bob cn: bob uid: bob userPassword: {SSHA}fCJ5vuW1BQ4/OfOVkkx1qjwi7yHFuGNB description: MD5 gidNumber: 1000 uidNumber: 5689 homeDirectory: /home/bob mail: bob@example.com dn: ou=Groups,dc=cluster,dc=local objectclass: organizationalunit ou: Groups description: We the People dn: cn=cryptography,ou=Groups,dc=cluster,dc=local objectclass: top objectclass: posixGroup gidNumber: 418 cn: cryptography description: Cryptography Team memberUID: uid=alice,ou=People,dc=cluster,dc=local memberUID: uid=bob,ou=People,dc=cluster,dc=local dn: cn=blue,ou=Groups,dc=cluster,dc=local objectclass: top objectclass: posixGroup gidNumber: 419 cn: blue description: Blue Team memberUID: uid=bob,ou=People,dc=cluster,dc=local dn: cn=red,ou=Groups,dc=cluster,dc=local objectclass: top objectclass: posixGroup gidNumber: 420 cn: red description: Red Team memberUID: uid=alice,ou=People,dc=cluster,dc=local secrets: identity: admin: admin ldap: ldap oci_image_registry: ldap: ldap-oci-image-registry-key openldap: domain: cluster.local password: password manifests: configmap_bin: true configmap_etc: true job_bootstrap: true job_image_repo_sync: true network_policy: false secret_registry: true statefulset: true service: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: libvirt/.helmignore ================================================ values_overrides ================================================ FILE: libvirt/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm libvirt name: libvirt version: 2025.2.0 home: https://libvirt.org sources: - https://libvirt.org/git/?p=libvirt.git;a=summary - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: libvirt/releasenotes/notes/libvirt-339936ca478fbf50.yaml ================================================ --- features: - | Make exporter container args configurable in values to make it possible to use ghcr.io/inovex/prometheus-libvirt-exporter image which assumes having no additional args. ... ================================================ FILE: libvirt/templates/bin/_ceph-admin-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat > /etc/ceph/ceph.client.admin.keyring << EOF [client.admin] {{- if .Values.conf.ceph.admin_keyring }} key = {{ .Values.conf.ceph.admin_keyring }} {{- else }} key = $(cat /tmp/client-keyring) {{- end }} EOF exit 0 ================================================ FILE: libvirt/templates/bin/_ceph-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cp -fv /etc/ceph/ceph.conf.template /etc/ceph/ceph.conf KEYRING=/etc/ceph/ceph.client.${CEPH_CINDER_USER}.keyring {{- if .Values.conf.ceph.cinder.keyring }} cat > ${KEYRING} </dev/null | grep -w libvirtd)" ]; then set +x for proc in $(ls /proc/*/comm 2>/dev/null); do if [ "x$(cat $proc 2>/dev/null | grep -w libvirtd)" == "xlibvirtd" ]; then set -x libvirtpid=$(echo $proc | cut -f 3 -d '/') echo "WARNING: libvirtd daemon already running on host" 1>&2 echo "$(cat "/proc/${libvirtpid}/status" 2>/dev/null | grep State)" 1>&2 kill -9 "$libvirtpid" || true set +x fi done set -x fi rm -f /var/run/libvirtd.pid if [[ -c /dev/kvm ]]; then chmod 660 /dev/kvm chown root:kvm /dev/kvm fi #Setup Cgroups to use when breaking out of Kubernetes defined groups CGROUPS="" for CGROUP in {{ .Values.conf.kubernetes.cgroup_controllers | include "helm-toolkit.utils.joinListWithSpace" }}; do if [ -d /sys/fs/cgroup/${CGROUP} ] || grep -w $CGROUP /sys/fs/cgroup/cgroup.controllers; then CGROUPS+="${CGROUP}," fi done cgcreate -g ${CGROUPS%,}:/osh-libvirt # We assume that if hugepage count > 0, then hugepages should be exposed to libvirt/qemu hp_count="$(cat /proc/meminfo | grep HugePages_Total | tr -cd '[:digit:]')" if [ 0"$hp_count" -gt 0 ]; then echo "INFO: Detected hugepage count of '$hp_count'. Enabling hugepage settings for libvirt/qemu." # Enable KVM hugepages for QEMU if [ -n "$(grep KVM_HUGEPAGES=0 /etc/default/qemu-kvm)" ]; then sed -i 's/.*KVM_HUGEPAGES=0.*/KVM_HUGEPAGES=1/g' /etc/default/qemu-kvm else echo KVM_HUGEPAGES=1 >> /etc/default/qemu-kvm fi # Ensure that the hugepage mount location is available/mapped inside the # container. This assumes use of the default ubuntu dev-hugepages.mount # systemd unit which mounts hugepages at this location. if [ ! -d /dev/hugepages ]; then echo "ERROR: Hugepages configured in kernel, but libvirtd container cannot access /dev/hugepages" exit 1 fi fi if [ -n "${LIBVIRT_CEPH_CINDER_SECRET_UUID}" ] || [ -n "${LIBVIRT_EXTERNAL_CEPH_CINDER_SECRET_UUID}" ] ; then cgexec -g ${CGROUPS%,}:/osh-libvirt systemd-run --scope --slice=system libvirtd --listen & tmpsecret=$(mktemp --suffix .xml) if [ -n "${LIBVIRT_EXTERNAL_CEPH_CINDER_SECRET_UUID}" ] ; then tmpsecret2=$(mktemp --suffix .xml) fi function cleanup { rm -f "${tmpsecret}" if [ -n "${LIBVIRT_EXTERNAL_CEPH_CINDER_SECRET_UUID}" ] ; then rm -f "${tmpsecret2}" fi } trap cleanup EXIT # Wait for the libvirtd is up TIMEOUT=60 while [[ ! -f /var/run/libvirtd.pid ]]; do if [[ ${TIMEOUT} -gt 0 ]]; then let TIMEOUT-=1 sleep 1 else echo "ERROR: libvirt did not start in time (pid file missing)" exit 1 fi done # Even though we see the pid file the socket immediately (this is # needed for virsh) TIMEOUT=10 while [[ ! -e /var/run/libvirt/libvirt-sock ]]; do if [[ ${TIMEOUT} -gt 0 ]]; then let TIMEOUT-=1 sleep 1 else echo "ERROR: libvirt did not start in time (socket missing)" exit 1 fi done function create_virsh_libvirt_secret { sec_user=$1 sec_uuid=$2 sec_ceph_keyring=$3 cat > ${tmpsecret} < ${sec_uuid} client.${sec_user}. secret EOF virsh secret-define --file ${tmpsecret} virsh secret-set-value --secret "${sec_uuid}" --base64 "${sec_ceph_keyring}" } if [ -z "${CEPH_CINDER_KEYRING}" ] && [ -n "${CEPH_CINDER_USER}" ] ; then CEPH_CINDER_KEYRING=$(awk '/key/{print $3}' /etc/ceph/ceph.client.${CEPH_CINDER_USER}.keyring) fi if [ -n "${CEPH_CINDER_USER}" ] ; then create_virsh_libvirt_secret ${CEPH_CINDER_USER} ${LIBVIRT_CEPH_CINDER_SECRET_UUID} ${CEPH_CINDER_KEYRING} fi if [ -n "${LIBVIRT_EXTERNAL_CEPH_CINDER_SECRET_UUID}" ] ; then EXTERNAL_CEPH_CINDER_KEYRING=$(cat /tmp/external-ceph-client-keyring) create_virsh_libvirt_secret ${EXTERNAL_CEPH_CINDER_USER} ${LIBVIRT_EXTERNAL_CEPH_CINDER_SECRET_UUID} ${EXTERNAL_CEPH_CINDER_KEYRING} fi cleanup # stop libvirtd; we needed it up to create secrets LIBVIRTD_PID=$(cat /var/run/libvirtd.pid) kill $LIBVIRTD_PID tail --pid=$LIBVIRTD_PID -f /dev/null fi # NOTE(vsaienko): changing CGROUP is required as restart of the pod will cause domains restarts cgexec -g ${CGROUPS%,}:/osh-libvirt systemd-run --scope --slice=system libvirtd --listen ================================================ FILE: libvirt/templates/configmap-apparmor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- dict "envAll" . "component" "libvirt" | include "helm-toolkit.snippets.kubernetes_apparmor_configmap" }} ================================================ FILE: libvirt/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "libvirt.configmap.bin" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapName }} data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} libvirt.sh: | {{ tuple "bin/_libvirt.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- if eq .Values.conf.qemu.vnc_tls "1" }} cert-init.sh: | {{ tpl .Values.conf.vencrypt.cert_init_sh . | indent 4 }} {{- end }} {{- if .Values.conf.ceph.enabled }} ceph-keyring.sh: | {{ tuple "bin/_ceph-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ceph-admin-keyring.sh: | {{ tuple "bin/_ceph-admin-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.init_modules.script "key" "libvirt-init-modules.sh") | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.dynamic_options.script "key" "init-dynamic-options.sh") | indent 2 }} {{- if .Values.conf.hooks.enabled }} {{- range $k, $v := .Values.conf.hooks.scripts }} {{ $k }}: | {{ tpl $v . | indent 4 }} {{- end }} {{- end }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_bin }} {{- list "libvirt-bin" . | include "libvirt.configmap.bin" }} {{- end }} ================================================ FILE: libvirt/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "libvirt.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: qemu.conf: {{ include "libvirt.utils.to_libvirt_conf" .Values.conf.qemu | b64enc }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "libvirt-etc" . | include "libvirt.configmap.etc" }} {{- end }} ================================================ FILE: libvirt/templates/daemonset-libvirt.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "libvirtProbeTemplate" }} exec: command: - bash - -c - /usr/bin/virsh connect {{- end }} {{- define "libvirt.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- $ssl_enabled := false }} {{- if eq $envAll.Values.conf.libvirt.listen_tls "1" }} {{- $ssl_enabled = true }} {{- end }} {{- with $envAll }} {{- $mounts_libvirt := .Values.pod.mounts.libvirt.libvirt }} {{- $mounts_libvirt_init := .Values.pod.mounts.libvirt.init_container }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: libvirt annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{- dict "envAll" $envAll "podName" "libvirt-libvirt-default" "containerNames" (list "libvirt") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: {{ dict "envAll" $envAll "application" "libvirt" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.agent.libvirt.node_selector_key }}: {{ .Values.labels.agent.libvirt.node_selector_value }} {{ if $envAll.Values.pod.tolerations.libvirt.enabled }} {{ tuple $envAll "libvirt" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} hostNetwork: true hostPID: true hostIPC: true dnsPolicy: {{ .Values.pod.dns_policy }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_libvirt_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{ dict "envAll" $envAll | include "helm-toolkit.snippets.kubernetes_apparmor_loader_init_container" | indent 8 }} {{- if .Values.conf.init_modules.enabled }} - name: libvirt-init-modules {{ tuple $envAll "libvirt" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "libvirt" "container" "libvirt_init_modules" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} terminationMessagePath: /var/log/termination-log command: - /tmp/libvirt-init-modules.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etc-modprobe-d mountPath: /etc/modprobe.d_host - name: host-rootfs mountPath: /mnt/host-rootfs mountPropagation: HostToContainer readOnly: true - name: libvirt-bin mountPath: /tmp/libvirt-init-modules.sh subPath: libvirt-init-modules.sh readOnly: true {{- end }} - name: init-dynamic-options {{ tuple $envAll "libvirt" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "libvirt" "container" "init_dynamic_options" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} terminationMessagePath: /var/log/termination-log command: - /tmp/init-dynamic-options.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: libvirt-bin mountPath: /tmp/init-dynamic-options.sh subPath: init-dynamic-options.sh readOnly: true {{- if eq .Values.conf.qemu.vnc_tls "1" }} - name: cert-init-vnc {{ tuple $envAll "kubectl" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "libvirt" "container" "cert_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/cert-init.sh env: - name: TYPE value: vnc - name: ISSUER_KIND value: {{ .Values.conf.vencrypt.issuer.kind }} - name: ISSUER_NAME value: {{ .Values.conf.vencrypt.issuer.name }} - name: POD_UID valueFrom: fieldRef: fieldPath: metadata.uid - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP volumeMounts: - name: pod-tmp mountPath: /tmp - name: libvirt-bin mountPath: /tmp/cert-init.sh subPath: cert-init.sh readOnly: true {{- end }} {{- if .Values.conf.ceph.enabled }} {{- if empty .Values.conf.ceph.cinder.keyring }} - name: ceph-admin-keyring-placement {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "libvirt" "container" "ceph_admin_keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ceph-admin-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph - name: libvirt-bin mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true {{- if empty .Values.conf.ceph.admin_keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} {{ end }} - name: ceph-keyring-placement {{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "libvirt" "container" "ceph_keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CEPH_CINDER_USER value: "{{ .Values.conf.ceph.cinder.user }}" {{- if .Values.conf.ceph.cinder.keyring }} - name: CEPH_CINDER_KEYRING value: "{{ .Values.conf.ceph.cinder.keyring }}" {{ end }} - name: LIBVIRT_CEPH_CINDER_SECRET_UUID value: "{{ .Values.conf.ceph.cinder.secret_uuid }}" command: - /tmp/ceph-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph - name: libvirt-bin mountPath: /tmp/ceph-keyring.sh subPath: ceph-keyring.sh readOnly: true - name: ceph-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true {{- end }} containers: - name: libvirt {{ tuple $envAll "libvirt" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.libvirt | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "libvirt" "container" "libvirt" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- if .Values.conf.ceph.enabled }} - name: CEPH_CINDER_USER value: "{{ .Values.conf.ceph.cinder.user }}" {{- if .Values.conf.ceph.cinder.keyring }} - name: CEPH_CINDER_KEYRING value: "{{ .Values.conf.ceph.cinder.keyring }}" {{ end }} - name: LIBVIRT_CEPH_CINDER_SECRET_UUID value: "{{ .Values.conf.ceph.cinder.secret_uuid }}" {{ end }} {{- if .Values.conf.ceph.cinder.external_ceph.enabled }} - name: EXTERNAL_CEPH_CINDER_USER value: "{{ .Values.conf.ceph.cinder.external_ceph.user }}" - name: LIBVIRT_EXTERNAL_CEPH_CINDER_SECRET_UUID value: "{{ .Values.conf.ceph.cinder.external_ceph.secret_uuid }}" {{ end }} {{ dict "envAll" . "component" "libvirt" "container" "libvirt" "type" "readiness" "probeTemplate" (include "libvirtProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "libvirt" "container" "libvirt" "type" "liveness" "probeTemplate" (include "libvirtProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/libvirt.sh lifecycle: preStop: exec: command: - bash - -c - |- kill $(cat /var/run/libvirtd.pid) volumeMounts: {{ dict "enabled" $ssl_enabled "name" "ssl-client" "path" "/etc/pki/libvirt" "certs" (tuple "clientcert.pem" "clientkey.pem" ) | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ dict "enabled" $ssl_enabled "name" "ssl-server-cert" "path" "/etc/pki/libvirt" "certs" (tuple "servercert.pem" ) | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ dict "enabled" $ssl_enabled "name" "ssl-server-key" "path" "/etc/pki/libvirt/private" "certs" (tuple "serverkey.pem" ) | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ dict "enabled" $ssl_enabled "name" "ssl-ca-cert" "path" "/etc/pki/CA" "certs" (tuple "cacert.pem" ) | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} - name: pod-tmp mountPath: /tmp - name: libvirt-bin mountPath: /tmp/libvirt.sh subPath: libvirt.sh readOnly: true - name: pod-shared mountPath: /etc/libvirt/libvirtd.conf subPath: libvirtd.conf readOnly: true - name: libvirt-etc mountPath: /etc/libvirt/qemu.conf subPath: qemu.conf readOnly: true - name: etc-libvirt-qemu mountPath: /etc/libvirt/qemu - mountPath: /lib/modules name: libmodules readOnly: true - name: var-lib-libvirt mountPath: /var/lib/libvirt {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: Bidirectional {{- end }} - name: var-lib-nova mountPath: /var/lib/nova {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: Bidirectional {{- end }} - name: run mountPath: /run - name: dev mountPath: /dev - name: cgroup mountPath: /sys/fs/cgroup - name: logs mountPath: /var/log/libvirt - name: machine-id mountPath: /etc/machine-id readOnly: true {{- if .Values.conf.ceph.enabled }} - name: etcceph mountPath: /etc/ceph {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: Bidirectional {{- end }} {{- if empty .Values.conf.ceph.cinder.keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{- end }} {{- end }} {{- if .Values.conf.ceph.cinder.external_ceph.enabled }} - name: external-ceph-keyring mountPath: /tmp/external-ceph-client-keyring subPath: key readOnly: true {{- end }} {{- if .Values.conf.hooks.enabled }} {{- range $k, $v := .Values.conf.hooks.scripts }} - name: libvirt-bin mountPath: /etc/libvirt/hooks/{{ $k }} subPath: {{ $k }} readOnly: true {{- end }} {{- end }} {{ if $mounts_libvirt.volumeMounts }}{{ toYaml $mounts_libvirt.volumeMounts | indent 12 }}{{ end }} {{- with .Values.libvirt.extraContainers }} {{- tpl (toYaml .) $envAll | nindent 8 }} {{- end }} volumes: {{ dict "enabled" $ssl_enabled "secretName" $envAll.Values.secrets.tls.client "name" "ssl-client" "path" "/etc/pki/libvirt" "certs" (tuple "clientcert.pem" "clientkey.pem" ) | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ dict "enabled" $ssl_enabled "secretName" $envAll.Values.secrets.tls.server "name" "ssl-server-cert" "path" "/etc/pki/libvirt" "certs" (tuple "servercert.pem" ) | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ dict "enabled" $ssl_enabled "secretName" $envAll.Values.secrets.tls.server "name" "ssl-server-key" "path" "/etc/pki/libvirt/private" "certs" (tuple "serverkey.pem" ) | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ dict "enabled" $ssl_enabled "secretName" $envAll.Values.secrets.tls.server "name" "ssl-ca-cert" "path" "/etc/pki/CA" "certs" (tuple "cacert.pem" ) | include "helm-toolkit.snippets.tls_volume" | indent 8 }} - name: pod-tmp emptyDir: {} - name: libvirt-bin configMap: name: libvirt-bin defaultMode: 0555 - name: libvirt-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 {{- if .Values.conf.ceph.enabled }} - name: etcceph hostPath: path: /var/lib/openstack-helm/compute/libvirt - name: ceph-etc configMap: name: {{ .Values.ceph_client.configmap }} defaultMode: 0444 {{- if empty .Values.conf.ceph.cinder.keyring }} - name: ceph-keyring secret: secretName: {{ .Values.ceph_client.user_secret_name }} {{ end }} {{ end }} {{- if .Values.conf.ceph.cinder.external_ceph.enabled }} - name: external-ceph-keyring secret: secretName: {{ .Values.conf.ceph.cinder.external_ceph.user_secret_name }} {{ end }} - name: libmodules hostPath: path: /lib/modules - name: var-lib-libvirt hostPath: path: /var/lib/libvirt - name: var-lib-nova hostPath: path: /var/lib/nova - name: run hostPath: path: /run - name: dev hostPath: path: /dev - name: logs hostPath: path: /var/log/libvirt - name: cgroup hostPath: path: /sys/fs/cgroup - name: machine-id hostPath: path: /etc/machine-id - name: etc-libvirt-qemu hostPath: path: /etc/libvirt/qemu - name: etc-modprobe-d hostPath: path: /etc/modprobe.d - name: host-rootfs hostPath: path: / type: Directory - name: pod-shared emptyDir: {} {{ dict "envAll" $envAll "component" "libvirt" "requireSys" true | include "helm-toolkit.snippets.kubernetes_apparmor_volumes" | indent 8 }} {{ if $mounts_libvirt.volumes }}{{ toYaml $mounts_libvirt.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_libvirt }} {{- $envAll := . }} {{- $daemonset := "libvirt" }} {{- $configMapName := "libvirt-etc" }} {{- $serviceAccountName := "libvirt" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "libvirt" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $configmap_yaml := "libvirt.configmap.etc" }} {{/* Preffer using .Values.overrides rather than .Values.conf.overrides */}} {{- list $daemonset "libvirt.daemonset" $serviceAccountName $configmap_yaml $configMapName "libvirt.configmap.bin" "libvirt-bin" . | include "helm-toolkit.utils.daemonset_overrides_root" }} {{- end }} ================================================ FILE: libvirt/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: libvirt/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "libvirt" -}} {{- if .Values.pod.tolerations.libvirt.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: libvirt/templates/network-policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "libvirt" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: libvirt/templates/pod-monitor.yaml ================================================ {{- if .Values.manifests.podmonitor -}} apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: libvirt-exporter spec: namespaceSelector: matchNames: - {{ .Release.Namespace }} podMetricsEndpoints: - interval: 10s path: /metrics port: metrics scheme: http selector: matchLabels: app.kubernetes.io/name: libvirt {{- end -}} ================================================ FILE: libvirt/templates/role-cert-manager.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.role_cert_manager }} {{- $serviceAccountName := "libvirt" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ .Release.Name }}-cert-manager namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ .Release.Name }}-cert-manager subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ .Release.Name }}-cert-manager namespace: {{ .Release.Namespace }} rules: - apiGroups: - cert-manager.io verbs: - get - list - create - watch resources: - certificates - apiGroups: - "" verbs: - get - patch resources: - secrets {{- end -}} ================================================ FILE: libvirt/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: libvirt/templates/utils/_to_libvirt_conf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* abstract: | Builds a libvirt compatible config file. values: | conf: libvirt: log_level: 3 cgroup_controllers: - cpu - cpuacct usage: | {{ include "libvirt.utils.to_libvirt_conf" .Values.conf.libvirt }} return: | cgroup_controllers = [ "cpu", "cpuacct" ] log_level = 3 */}} {{- define "libvirt.utils._to_libvirt_conf.list_to_string" -}} {{- $local := dict "first" true -}} {{- range $k, $v := . -}}{{- if not $local.first -}}, {{ end -}}{{- $v | quote -}}{{- $_ := set $local "first" false -}}{{- end -}} {{- end -}} {{- define "libvirt.utils.to_libvirt_conf" -}} {{- range $key, $value := . -}} {{- if kindIs "slice" $value }} {{ $key }} = [ {{ include "libvirt.utils._to_libvirt_conf.list_to_string" $value }} ] {{- else if kindIs "string" $value }} {{- if regexMatch "^[0-9]+$" $value }} {{ $key }} = {{ $value }} {{- else }} {{ $key }} = {{ $value | quote }} {{- end }} {{- else }} {{ $key }} = {{ $value }} {{- end }} {{- end -}} {{- end -}} ================================================ FILE: libvirt/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for libvirt. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null labels: agent: libvirt: node_selector_key: openstack-compute-node node_selector_value: enabled images: tags: libvirt: quay.io/airshipit/libvirt:2025.1-ubuntu_noble ceph_config_helper: 'quay.io/airshipit/ceph-config-helper:ubuntu_jammy_20.2.1-1-20260407' dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 kubectl: docker.io/bitnami/kubectl:latest pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync network: # provide what type of network wiring will be used # possible options: openvswitch, linuxbridge, sriov backend: - openvswitch endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false libvirt: username: libvirt password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null network_policy: libvirt: ingress: - {} egress: - {} ceph_client: configmap: ceph-etc user_secret_name: pvc-ceph-client-key conf: ceph: enabled: true admin_keyring: null cinder: user: "cinder" keyring: null secret_uuid: 457eb676-33da-42ec-9a8c-9293d545c337 # Cinder Ceph backend that is not configured by the k8s cluter external_ceph: enabled: false user: null secret_uuid: null user_secret_name: null libvirt: listen_tcp: "1" listen_tls: "0" auth_tcp: "none" ca_file: "/etc/pki/CA/cacert.pem" cert_file: "/etc/pki/libvirt/servercert.pem" key_file: "/etc/pki/libvirt/private/serverkey.pem" auth_unix_rw: "none" listen_addr: "${LISTEN_IP_ADDRESS}" log_level: "3" log_outputs: "1:file:/var/log/libvirt/libvirtd.log" # Modifies the config in which value is specified as the name of a variable # that is computed in the script. dynamic_options: libvirt: listen_interface: null listen_address: 127.0.0.1 script: | #!/bin/bash set -ex LIBVIRT_CONF_PATH=/tmp/pod-shared/libvirtd.conf {{- if .Values.conf.dynamic_options.libvirt.listen_interface }} LISTEN_INTERFACE="{{ .Values.conf.dynamic_options.libvirt.listen_interface }}" LISTEN_IP_ADDRESS=$(ip address show $LISTEN_INTERFACE | grep 'inet ' | awk '{print $2}' | awk -F "/" '{print $1}') {{- else if .Values.conf.dynamic_options.libvirt.listen_address }} LISTEN_IP_ADDRESS={{ .Values.conf.dynamic_options.libvirt.listen_address }} {{- end }} if [[ -z $LISTEN_IP_ADDRESS ]]; then echo "LISTEN_IP_ADDRESS is not set." exit 1 fi tee > ${LIBVIRT_CONF_PATH} << EOF {{ include "libvirt.utils.to_libvirt_conf" .Values.conf.libvirt }} EOF qemu: vnc_tls: "0" vnc_tls_x509_verify: "0" stdio_handler: "file" user: "nova" group: "kvm" kubernetes: cgroup: "kubepods.slice" # List of cgroup controller we want to use when breaking out of # Kubernetes defined groups cgroup_controllers: - blkio - cpu - devices - freezer - hugetlb - memory - net_cls - perf_event - rdma - misc - pids init_modules: enabled: false script: | #!/bin/bash set -ex export HOME=/tmp KVM_QEMU_CONF_HOST="/etc/modprobe.d_host/qemu-system-x86.conf" if [[ ! -f "${KVM_QEMU_CONF_HOST}" ]]; then if grep vmx /proc/cpuinfo; then cat << EOF > ${KVM_QEMU_CONF_HOST} options kvm_intel nested=1 options kvm_intel enable_apicv=1 options kvm_intel ept=1 EOF modprobe -r kvm_intel || true modprobe kvm_intel nested=1 elif grep svm /proc/cpuinfo; then cat << EOF > ${KVM_QEMU_CONF_HOST} options kvm_amd nested=1 EOF modprobe -r kvm_amd || true modprobe kvm_amd nested=1 else echo "Nested virtualization is not supported" fi fi vencrypt: # Issuer to use for the vencrypt certs. issuer: kind: ClusterIssuer name: ca-clusterissuer # Script is included here (vs in bin/) to allow overriding, in the case that # communication happens over an IP other than the pod IP for some reason. cert_init_sh: | #!/bin/bash set -x HOSTNAME_FQDN=$(hostname --fqdn) # Script to create certs for each libvirt pod based on pod IP (by default). cat < /tmp/${TYPE}.crt kubectl -n ${POD_NAMESPACE} get secret ${POD_NAME}-${TYPE} -o jsonpath='{.data.tls\.key}' | base64 -d > /tmp/${TYPE}.key kubectl -n ${POD_NAMESPACE} get secret ${POD_NAME}-${TYPE} -o jsonpath='{.data.ca\.crt}' | base64 -d > /tmp/${TYPE}-ca.crt hooks: # Libvirt hook scripts, that are placed in /etc/libvirt/hooks enabled: false scripts: # daemon: # qemu: # lxc: # libxl: # bhyve: # network: pod: probes: libvirt: libvirt: liveness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 5 readiness: enabled: true params: initialDelaySeconds: 15 periodSeconds: 60 timeoutSeconds: 5 security_context: libvirt: pod: runAsUser: 0 container: ceph_admin_keyring_placement: readOnlyRootFilesystem: false ceph_keyring_placement: readOnlyRootFilesystem: false libvirt: privileged: true readOnlyRootFilesystem: false libvirt_init_modules: readOnlyRootFilesystem: true privileged: true capabilities: drop: - ALL init_dynamic_options: runAsUser: 65534 runAsNonRoot: true readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: - ALL affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: libvirt: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule dns_policy: "ClusterFirstWithHostNet" mounts: libvirt: init_container: null libvirt: lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate libvirt: enabled: true min_ready_seconds: 0 max_unavailable: 1 resources: enabled: false libvirt: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - libvirt-image-repo-sync services: - endpoint: node service: local_image_registry targeted: ovn: libvirt: pod: - requireSameNode: true labels: application: ovn component: ovn-controller openvswitch: libvirt: pod: - requireSameNode: true labels: application: neutron component: neutron-ovs-agent linuxbridge: libvirt: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent sriov: libvirt: pod: - requireSameNode: true labels: application: neutron component: neutron-sriov-agent static: libvirt: services: null image_repo_sync: services: - endpoint: internal service: local_image_registry libvirt: extraContainers: [] manifests: configmap_bin: true configmap_etc: true daemonset_libvirt: true job_image_repo_sync: true network_policy: false role_cert_manager: false secret_registry: true secrets: oci_image_registry: libvirt: libvirt-oci-image-registry-key tls: server: libvirt-tls-server client: libvirt-tls-client # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: local-storage/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Local Storage name: local-storage version: 2025.2.0 home: https://kubernetes.io/docs/concepts/storage/volumes/#local maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: local-storage/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: local-storage/templates/persistent-volumes.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.persistent_volumes }} {{- $envAll := . }} {{- range .Values.conf.persistent_volumes }} --- apiVersion: v1 kind: PersistentVolume metadata: name: {{ .name }} labels: {{ tuple $envAll "local-storage" $envAll.Release.Name | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: capacity: storage: {{ .storage_capacity }} accessModes: {{ .access_modes }} persistentVolumeReclaimPolicy: {{ .reclaim_policy }} storageClassName: {{ $envAll.Release.Name }} local: path: {{ .local_path }} nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: {{ $envAll.Values.labels.node_affinity.node_selector_key }} operator: In values: - {{ $envAll.Values.labels.node_affinity.node_selector_value }} {{- end }} {{- end }} ================================================ FILE: local-storage/templates/storage-class.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.storage_class }} {{- $envAll := . }} --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: {{ .Release.Name }} labels: {{ tuple $envAll "local-storage" $envAll.Release.Name | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer {{- end }} ================================================ FILE: local-storage/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- labels: node_affinity: node_selector_key: openstack-control-plane node_selector_value: enabled conf: persistent_volumes: # For each mount path, one PV should be created. # If there are two mount paths for local storage are available on two nodes, # then two PVs details should be defined. Example: # - name: local-pv-1 (name of the Persistent Volume 1) # reclaimpolicy: Retain (Reclaim Policy for the PV local-pv-1) # storage_capacity: "100Gi" (Storage capacity of the PV local-pv-1) # access_modes: [ "ReadWriteOnce" ] (Access mode for the PV local-pv-1) # local_path: /mnt/disk/vol1 (Mount path of the local disk, local-pv-1 will be created on) # - name: local-pv-2 (name of the Persistent Volume 2) # reclaimpolicy: Retain (Reclaim Policy for the PV local-pv-2) # storage_capacity: "100Gi" (Storage capacity of the PV local-pv-2) # access_modes: [ "ReadWriteOnce" ] (Access mode for the PV local-pv-2) # local_path: /mnt/disk/vol2 (Mount path of the local disk, local-pv-2 will be created on) # Similarly if three nodes each have disk mount path /var/lib/kubernetes # which will be acting as local storage for each node, then Persistentvolumes # should be updated with three entries. manifests: storage_class: true persistent_volumes: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: local-volume-provisioner/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm local-volume-provisioner name: local-volume-provisioner version: 2025.2.0 home: https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner sources: - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: local-volume-provisioner/templates/bin/_fakemount.py.tpl ================================================ #!/usr/bin/env python3 # # Copyright 2019 Mirantis, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """Fakemount python module The module is aimed to crate fake mountpoints (--bind). Example: python3 fakemount --config-file '/root/mymount.yml' Attributes: config-file - file path to config file that contains fake mounts. """ __version__ = "1.0" import argparse import logging import os import re import subprocess import sys from collections import defaultdict import yaml logging.basicConfig(stream=sys.stdout, level=logging.INFO) LOG = logging.getLogger(__name__) MOUNT_BIN = "/bin/mount" ###Fork https://github.com/b10011/pyfstab/ ##################################### # Latest commit 828540d class InvalidEntry(Exception): """ Raised when a string cannot be generated because of the Entry is invalid. """ class InvalidFstabLine(Exception): """ Raised when a line is invalid in fstab. This doesn't just mean that the Entry will be invalid but also that the system can not process the fstab file fully either. """ class Entry: """ Handles parsing and formatting fstab line entries. :var device: (str or None) - Fstab device (1st parameter in the fstab entry) :var dir: (str or None) - Fstab device (2nd parameter in the fstab entry) :var type: (str or None) - Fstab device (3rd parameter in the fstab entry) :var options: (str or None) - Fstab device (4th parameter in the fstab entry) :var dump: (int or None) - Fstab device (5th parameter in the fstab entry) :var fsck: (int or None) - Fstab device (6th parameter in the fstab entry) :var valid: (bool) - Whether the Entry is valid or not. Can be checked with "if entry:". """ def __init__( self, _device=None, _dir=None, _type=None, _options=None, _dump=None, _fsck=None, ): """ :param _device: Fstab device (1st parameter in the fstab entry) :type _device: str :param _dir: Fstab device (2nd parameter in the fstab entry) :type _dir: str :param _type: Fstab device (3rd parameter in the fstab entry) :type _type: str :param _options: Fstab device (4th parameter in the fstab entry) :type _options: str :param _dump: Fstab device (5th parameter in the fstab entry) :type _dump: int :param _fsck: Fstab device (6th parameter in the fstab entry) :type _fsck: int """ self.device = _device self.dir = _dir self.type = _type self.options = _options self.dump = _dump self.fsck = _fsck self.valid = True self.valid &= self.device is not None self.valid &= self.dir is not None self.valid &= self.type is not None self.valid &= self.options is not None self.valid &= self.dump is not None self.valid &= self.fsck is not None def read_string(self, line): """ Parses an entry from a string :param line: Fstab entry line. :type line: str :return: self :rtype: Entry :raises InvalidEntry: If the data in the string cannot be parsed. """ line = line.strip() if line and not line[0] == "#": parts = re.split(r"\s+", line) if len(parts) == 6: [_device, _dir, _type, _options, _dump, _fsck] = parts _dump = int(_dump) _fsck = int(_fsck) self.device = _device self.dir = _dir self.type = _type self.options = _options self.dump = _dump self.fsck = _fsck self.valid = True return self else: raise InvalidFstabLine() self.device = None self.dir = None self.type = None self.options = None self.dump = None self.fsck = None self.valid = False raise InvalidEntry("Entry cannot be parsed") def write_string(self): """ Formats the Entry into fstab entry line. :return: Fstab entry line. :rtype: str :raises InvalidEntry: A string cannot be generated because the entry is invalid. """ if self: return "{} {} {} {} {} {}".format( self.device, self.dir, self.type, self.options, self.dump, self.fsck, ) else: raise InvalidEntry("Entry cannot be formatted") def __bool__(self): return self.valid def __str__(self): return self.write_string() def __repr__(self): try: return "".format(str(self)) except InvalidEntry: return "" class Fstab: """ Handles reading, parsing, formatting and writing of fstab files. :var entries: (list[Entry]) - List of entries. When writing to a file, entries are listed from this list. :var entries_by_device: (dict[str, list[Entry]]) - Fstab entries by device. :var entry_by_dir: (dict[str, Entry]) - Fstab entry by directory. :var entries_by_type: (dict[str, list[Entry]]) - Fstab entries by type. """ def __init__(self): self.entries = [] # A single device can have multiple mountpoints self.entries_by_device = defaultdict(list) # If multiple devices have same mountpoint, only the last entry in the # fstab file is taken into consideration self.entry_by_dir = dict() # And the most obvious one, many entries can have mountpoints of same # type self.entries_by_type = defaultdict(list) def read_string(self, data, only_valid=False): """ Parses entries from a data string :param data: Contents of the fstab file :type data: str :param only_valid: Skip the entries that do not actually mount. For example, if device A is mounted to directory X and later device B is mounted to directory X, the A mount to X is undone by the system. :type only_valid: bool :return: self :rtype: Fstab """ for line in reversed(data.splitlines()): try: entry = Entry().read_string(line) if entry and ( not only_valid or entry.dir not in self.entry_by_dir ): self.entries.insert(0, entry) self.entries_by_device[entry.device].insert(0, entry) self.entry_by_dir[entry.dir] = entry self.entries_by_type[entry.type].insert(0, entry) except InvalidEntry: pass return self def write_string(self): """ Formats entries into a string. :return: Formatted fstab file. :rtype: str :raises InvalidEntry: A string cannot be generated because one of the entries is invalid. """ return "\n".join(str(entry) for entry in self.entries) def read_file(self, handle, only_valid=False): """ Parses entries from a file :param handle: File handle :type handle: file :param only_valid: Skip the entries that do not actually mount. For example, if device A is mounted to directory X and later device B is mounted to directory X, the A mount to X is undone by the system. :type only_valid: bool :return: self :rtype: Fstab """ self.read_string(handle.read(), only_valid) return self def write_file(self, handle): """ Parses entries in data string :param path: File handle :type path: file :return: self :rtype: Fstab """ handle.write(str(self)) return self def __bool__(self): return len(self.entries) > 0 def __str__(self): return self.write_string() def __repr__(self): res = "= 0.1.0" ... ================================================ FILE: magnum/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: magnum/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex magnum-db-manage upgrade ================================================ FILE: magnum/templates/bin/_magnum-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/magnum/magnum-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: magnum/templates/bin/_magnum-conductor-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex tee /tmp/pod-shared/magnum.conf <= 0.1.0" ... ================================================ FILE: manila/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cd $HOME {{ range .Values.bootstrap.structured.images }} openstack image show {{ .name | quote }} || \ (curl --fail -sSL -O {{ .source_url }}{{ .image_file }}; \ openstack image create {{ .name | quote }} \ {{ if .id -}} --id {{ .id }} {{ end -}} \ --disk-format {{ .image_type }} \ --file {{ .image_file }} \ {{ if .properties -}} {{ range $key, $value := .properties }}--property {{$key}}={{$value}} {{ end }}{{ end -}} \ --container-format {{ .container_format | quote }} \ {{ if .private -}} --private {{- else -}} --public {{- end -}};) {{ end }} {{ range .Values.bootstrap.structured.flavors }} openstack flavor show {{ .name | quote }} || \ openstack flavor create {{ .name | quote }} \ {{ if .id -}} --id {{ .id }} {{ end -}} \ --ram {{ .ram }} \ --vcpus {{ .vcpus }} \ --disk {{ .disk }} \ --ephemeral {{ .ephemeral }} \ {{ if .public -}} --public {{- else -}} --private {{- end -}}; {{ end }} openstack share type show default || \ openstack share type create default true \ --public true --description "default generic share type" openstack share group type show default || \ openstack share group type create default default --public true {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: manila/templates/bin/_ceph-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat > /etc/ceph/ceph.client.${CEPHFS_AUTH_ID}.keyring < /tmp/pod-shared/manila-share-fqdn.conf << EOF [generic] service_network_host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: manila/templates/bin/_manila-share.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec manila-share \ --config-file /etc/manila/manila.conf \ --config-dir /etc/manila/manila.conf.d \ {{- if and ( empty .Values.conf.manila.generic.service_network_host ) ( .Values.pod.use_fqdn.share ) }} --config-file /tmp/pod-shared/manila-share-fqdn.conf {{- end }} ================================================ FILE: manila/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: manila-bin data: rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} manila-share-init.sh: | {{ tuple "bin/_manila-share-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} manila-api.sh: | {{ tuple "bin/_manila-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} manila-data.sh: | {{ tuple "bin/_manila-data.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} manila-scheduler.sh: | {{ tuple "bin/_manila-scheduler.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} manila-share.sh: | {{ tuple "bin/_manila-share.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ceph-keyring.sh: | {{ tuple "bin/_ceph-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: manila/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- $manila_auth_url := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} {{- $manila_region_name := .Values.endpoints.identity.auth.manila.region_name }} {{- $manila_project_name := .Values.endpoints.identity.auth.manila.project_name }} {{- $manila_project_domain_name := .Values.endpoints.identity.auth.manila.project_domain_name }} {{- $manila_user_domain_name := .Values.endpoints.identity.auth.manila.user_domain_name }} {{- $manila_username := .Values.endpoints.identity.auth.manila.username }} {{- $manila_password := .Values.endpoints.identity.auth.manila.password }} {{- $memcached_servers := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} {{- $memcache_secret_key := default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key }} {{- if empty .Values.conf.manila.keystone_authtoken.auth_uri -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "auth_uri" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.auth_url -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "auth_url" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "region_name" $manila_region_name -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "project_name" $manila_project_name -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "project_domain_name" $manila_project_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "user_domain_name" $manila_user_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.username -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "username" $manila_username -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.password -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "password" $manila_password -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.memcached_servers -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "memcached_servers" $memcached_servers -}} {{- end -}} {{- if empty .Values.conf.manila.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.manila.keystone_authtoken "memcache_secret_key" $memcache_secret_key -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.manila.database.connection)) (empty .Values.conf.manila.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "manila" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set .Values.conf.manila.database "connection" -}} {{- end -}} {{- if empty .Values.conf.manila.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "manila" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.manila.DEFAULT "transport_url" -}} {{- end -}} # neutron {{- if empty .Values.conf.manila.neutron.auth_uri -}} {{- $_ := set .Values.conf.manila.neutron "auth_uri" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.auth_url -}} {{- $_ := set .Values.conf.manila.neutron "auth_url" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.region_name -}} {{- $_ := set .Values.conf.manila.neutron "region_name" .Values.endpoints.identity.auth.manila.region_name -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.project_name -}} {{- $_ := set .Values.conf.manila.neutron "project_name" $manila_project_name -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.project_domain_name -}} {{- $_ := set .Values.conf.manila.neutron "project_domain_name" $manila_project_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.user_domain_name -}} {{- $_ := set .Values.conf.manila.neutron "user_domain_name" $manila_user_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.username -}} {{- $_ := set .Values.conf.manila.neutron "username" $manila_username -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.password -}} {{- $_ := set .Values.conf.manila.neutron "password" $manila_password -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.memcached_servers -}} {{- $_ := set .Values.conf.manila.neutron "memcached_servers" $memcached_servers -}} {{- end -}} {{- if empty .Values.conf.manila.neutron.memcache_secret_key -}} {{- $_ := set .Values.conf.manila.neutron "memcache_secret_key" $memcache_secret_key -}} {{- end -}} # nova {{- if empty .Values.conf.manila.nova.auth_uri -}} {{- $_ := set .Values.conf.manila.nova "auth_uri" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.nova.auth_url -}} {{- $_ := set .Values.conf.manila.nova "auth_url" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.nova.region_name -}} {{- $_ := set .Values.conf.manila.nova "region_name" .Values.endpoints.identity.auth.manila.region_name -}} {{- end -}} {{- if empty .Values.conf.manila.nova.project_name -}} {{- $_ := set .Values.conf.manila.nova "project_name" $manila_project_name -}} {{- end -}} {{- if empty .Values.conf.manila.nova.project_domain_name -}} {{- $_ := set .Values.conf.manila.nova "project_domain_name" $manila_project_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.nova.user_domain_name -}} {{- $_ := set .Values.conf.manila.nova "user_domain_name" $manila_user_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.nova.username -}} {{- $_ := set .Values.conf.manila.nova "username" $manila_username -}} {{- end -}} {{- if empty .Values.conf.manila.nova.password -}} {{- $_ := set .Values.conf.manila.nova "password" $manila_password -}} {{- end -}} {{- if empty .Values.conf.manila.nova.memcached_servers -}} {{- $_ := set .Values.conf.manila.nova "memcached_servers" $memcached_servers -}} {{- end -}} {{- if empty .Values.conf.manila.nova.memcache_secret_key -}} {{- $_ := set .Values.conf.manila.nova "memcache_secret_key" $memcache_secret_key -}} {{- end -}} # cinder {{- if empty .Values.conf.manila.cinder.auth_uri -}} {{- $_ := set .Values.conf.manila.cinder "auth_uri" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.auth_url -}} {{- $_ := set .Values.conf.manila.cinder "auth_url" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.region_name -}} {{- $_ := set .Values.conf.manila.cinder "region_name" .Values.endpoints.identity.auth.manila.region_name -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.project_name -}} {{- $_ := set .Values.conf.manila.cinder "project_name" $manila_project_name -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.project_domain_name -}} {{- $_ := set .Values.conf.manila.cinder "project_domain_name" $manila_project_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.user_domain_name -}} {{- $_ := set .Values.conf.manila.cinder "user_domain_name" $manila_user_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.username -}} {{- $_ := set .Values.conf.manila.cinder "username" $manila_username -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.password -}} {{- $_ := set .Values.conf.manila.cinder "password" $manila_password -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.memcached_servers -}} {{- $_ := set .Values.conf.manila.cinder "memcached_servers" $memcached_servers -}} {{- end -}} {{- if empty .Values.conf.manila.cinder.memcache_secret_key -}} {{- $_ := set .Values.conf.manila.cinder "memcache_secret_key" $memcache_secret_key -}} {{- end -}} # glance {{- if empty .Values.conf.manila.glance.auth_uri -}} {{- $_ := set .Values.conf.manila.glance "auth_uri" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.glance.auth_url -}} {{- $_ := set .Values.conf.manila.glance "auth_url" $manila_auth_url -}} {{- end -}} {{- if empty .Values.conf.manila.glance.region_name -}} {{- $_ := set .Values.conf.manila.glance "region_name" .Values.endpoints.identity.auth.manila.region_name -}} {{- end -}} {{- if empty .Values.conf.manila.glance.project_name -}} {{- $_ := set .Values.conf.manila.glance "project_name" $manila_project_name -}} {{- end -}} {{- if empty .Values.conf.manila.glance.project_domain_name -}} {{- $_ := set .Values.conf.manila.glance "project_domain_name" $manila_project_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.glance.user_domain_name -}} {{- $_ := set .Values.conf.manila.glance "user_domain_name" $manila_user_domain_name -}} {{- end -}} {{- if empty .Values.conf.manila.glance.username -}} {{- $_ := set .Values.conf.manila.glance "username" $manila_username -}} {{- end -}} {{- if empty .Values.conf.manila.glance.password -}} {{- $_ := set .Values.conf.manila.glance "password" $manila_password -}} {{- end -}} {{- if empty .Values.conf.manila.glance.memcached_servers -}} {{- $_ := set .Values.conf.manila.glance "memcached_servers" $memcached_servers -}} {{- end -}} {{- if empty .Values.conf.manila.glance.memcache_secret_key -}} {{- $_ := set .Values.conf.manila.glance "memcache_secret_key" $memcache_secret_key -}} {{- end -}} {{- if empty .Values.conf.manila_api_uwsgi.uwsgi.processes -}} {{- $_ := set .Values.conf.manila_api_uwsgi.uwsgi "processes" .Values.conf.manila.DEFAULT.osapi_share_workers -}} {{- end -}} {{- if empty (index .Values.conf.manila_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "sharev2" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.manila_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: manila-etc type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} manila.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.manila | b64enc }} manila-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.manila_api_uwsgi | b64enc }} {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- $filePrefix := replace "_" "-" $key }} {{ printf "%s.filters" $filePrefix }}: {{ $value.content | b64enc }} {{- end }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} manila_sudoers: {{ $envAll.Values.conf.manila_sudoers | b64enc }} rootwrap.conf: {{ $envAll.Values.conf.rootwrap | b64enc }} {{- end }} ================================================ FILE: manila/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_manila_api := .Values.pod.mounts.manila_api.manila_api }} {{- $mounts_manila_api_init := .Values.pod.mounts.manila_api.init_container }} {{- $etcSources := .Values.pod.etcSources.manila_api }} {{- $serviceAccountName := "manila-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: manila-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "manila" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "manila" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "manila" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "manila_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "manila-api" "containerNames" (list "init" "manila-api") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "manila" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "manila_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "manila_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "manila" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.manila.enabled }} {{ tuple $envAll "manila" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "api" $mounts_manila_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: manila-api {{ tuple $envAll "manila_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "manila" "container" "manila_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/manila-api.sh - start env: {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/manila/certs/ca.crt" {{- end }} lifecycle: preStop: exec: command: - /tmp/manila-api.sh - stop ports: - name: m-api containerPort: {{ tuple "sharev2" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: HTTP path: {{ tuple "sharev2" "healthcheck" "" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} port: {{ tuple "sharev2" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.manila.oslo_concurrency.lock_path }} - name: state-tmp mountPath: /var/lib/manila - name: etcmanila mountPath: /etc/manila - name: manila-etc mountPath: /etc/manila/manila.conf subPath: manila.conf readOnly: true - name: manila-etc-snippets mountPath: /etc/manila/manila.conf.d/ readOnly: true - name: manila-etc mountPath: /etc/manila/manila-api-uwsgi.ini subPath: manila-api-uwsgi.ini readOnly: true {{- if .Values.conf.manila.DEFAULT.log_config_append }} - name: manila-etc mountPath: {{ .Values.conf.manila.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.manila.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: manila-etc mountPath: /etc/manila/api-paste.ini subPath: api-paste.ini readOnly: true - name: manila-etc mountPath: /etc/manila/policy.yaml subPath: policy.yaml readOnly: true - name: manila-bin mountPath: /tmp/manila-api.sh subPath: manila-api.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal "path" "/etc/manila/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_manila_api.volumeMounts }}{{ toYaml $mounts_manila_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: state-tmp emptyDir: {} - name: etcmanila emptyDir: {} - name: manila-etc secret: secretName: manila-etc defaultMode: 0444 - name: manila-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: manila-bin configMap: name: manila-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_manila_api.volumes }}{{ toYaml $mounts_manila_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: manila/templates/deployment-data.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_data }} {{- $envAll := . }} {{- $mounts_manila_data := .Values.pod.mounts.manila_data.manila_data }} {{- $mounts_manila_data_init := .Values.pod.mounts.manila_data.init_container }} {{- $etcSources := .Values.pod.etcSources.manila_data }} {{- $serviceAccountName := "manila-data" }} {{ tuple $envAll "data" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: manila-data annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "manila" "data" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.data }} selector: matchLabels: {{ tuple $envAll "manila" "data" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "manila" "data" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "manila_data" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "manila-data" "containerNames" (list "init" "manila-data") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "manila" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "manila_data" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "manila_data" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "manila" "data" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.data.node_selector_key }}: {{ .Values.labels.data.node_selector_value }} {{ if $envAll.Values.pod.tolerations.manila.enabled }} {{ tuple $envAll "manila" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "data" $mounts_manila_data_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: manila-data {{ tuple $envAll "manila_data" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.data | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "manila" "container" "manila_data" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/manila-data.sh env: {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/manila/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.manila.oslo_concurrency.lock_path }} - name: etcmanila mountPath: /etc/manila - name: state-tmp mountPath: /var/lib/manila - name: manila-etc mountPath: /etc/manila/manila.conf subPath: manila.conf readOnly: true - name: manila-etc-snippets mountPath: /etc/manila/manila.conf.d/ readOnly: true {{- if .Values.conf.manila.DEFAULT.log_config_append }} - name: manila-etc mountPath: {{ .Values.conf.manila.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.manila.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: manila-etc mountPath: /etc/manila/policy.yaml subPath: policy.yaml readOnly: true - name: manila-bin mountPath: /tmp/manila-data.sh subPath: manila-data.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal "path" "/etc/manila/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_manila_data.volumeMounts }}{{ toYaml $mounts_manila_data.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: state-tmp emptyDir: {} - name: etcmanila emptyDir: {} - name: manila-etc secret: secretName: manila-etc defaultMode: 0444 - name: manila-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: manila-bin configMap: name: manila-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_manila_data.volumes }}{{ toYaml $mounts_manila_data.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: manila/templates/deployment-scheduler.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_scheduler }} {{- $envAll := . }} {{- $mounts_manila_scheduler := .Values.pod.mounts.manila_scheduler.manila_scheduler }} {{- $mounts_manila_scheduler_init := .Values.pod.mounts.manila_scheduler.init_container }} {{- $etcSources := .Values.pod.etcSources.manila_scheduler }} {{- $serviceAccountName := "manila-scheduler" }} {{ tuple $envAll "scheduler" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: manila-scheduler annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "manila" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.scheduler }} selector: matchLabels: {{ tuple $envAll "manila" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "manila" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "manila_scheduler" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "manila-scheduler" "containerNames" (list "init" "manila-scheduler") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "manila" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "manila_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "manila_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "manila" "scheduler" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.scheduler.node_selector_key }}: {{ .Values.labels.scheduler.node_selector_value }} {{ if $envAll.Values.pod.tolerations.manila.enabled }} {{ tuple $envAll "manila" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "scheduler" $mounts_manila_scheduler_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: manila-scheduler {{ tuple $envAll "manila_scheduler" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.scheduler | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "manila" "container" "manila_scheduler" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/manila-scheduler.sh env: {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/manila/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.manila.oslo_concurrency.lock_path }} - name: etcmanila mountPath: /etc/manila - name: state-tmp mountPath: /var/lib/manila - name: manila-etc mountPath: /etc/manila/manila.conf subPath: manila.conf readOnly: true - name: manila-etc-snippets mountPath: /etc/manila/manila.conf.d/ readOnly: true {{- if .Values.conf.manila.DEFAULT.log_config_append }} - name: manila-etc mountPath: {{ .Values.conf.manila.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.manila.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: manila-etc mountPath: /etc/manila/policy.yaml subPath: policy.yaml readOnly: true - name: manila-bin mountPath: /tmp/manila-scheduler.sh subPath: manila-scheduler.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal "path" "/etc/manila/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_manila_scheduler.volumeMounts }}{{ toYaml $mounts_manila_scheduler.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: state-tmp emptyDir: {} - name: etcmanila emptyDir: {} - name: manila-etc secret: secretName: manila-etc defaultMode: 0444 - name: manila-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: manila-bin configMap: name: manila-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_manila_scheduler.volumes }}{{ toYaml $mounts_manila_scheduler.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: manila/templates/deployment-share.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_share }} {{- $envAll := . }} {{- $mounts_manila_share := .Values.pod.mounts.manila_share.manila_share }} {{- $mounts_manila_share_init := .Values.pod.mounts.manila_share.init_container }} {{- $etcSources := .Values.pod.etcSources.manila_share }} {{- $serviceAccountName := "manila-share" }} {{ tuple $envAll "share" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $enabledBackends := default "" .Values.conf.manila.DEFAULT.enabled_share_backends }} {{- $isCephfsEnabled := (contains "cephfs" $enabledBackends) }} --- apiVersion: apps/v1 kind: Deployment metadata: name: manila-share annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "manila" "share" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.share }} selector: matchLabels: {{ tuple $envAll "manila" "share" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "manila" "share" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "manila_share" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "manila-share" "containerNames" (list "init" "manila-share" "manila-share-init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "manila" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "manila_share" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "manila_share" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "manila" "share" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.share.node_selector_key }}: {{ .Values.labels.share.node_selector_value }} {{ if $envAll.Values.pod.tolerations.manila.enabled }} {{ tuple $envAll "manila" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true initContainers: {{ tuple $envAll "share" $mounts_manila_share_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: manila-share-init {{ tuple $envAll "manila_share" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "manila" "container" "manila_share" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: [] command: - /tmp/manila-share-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: manila-bin mountPath: /tmp/manila-share-init.sh subPath: manila-share-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared {{ if $mounts_manila_share.volumeMounts }}{{ toYaml $mounts_manila_share.volumeMounts | indent 12 }}{{ end }} {{ if $isCephfsEnabled }} - name: ceph-keyring-placement {{ tuple $envAll "manila_share" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "manila" "container" "ceph_keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CEPHFS_AUTH_ID value: {{ .Values.conf.manila.DEFAULT.cephfs_auth_id | quote }} command: - /tmp/ceph-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph - name: manila-bin mountPath: /tmp/ceph-keyring.sh subPath: ceph-keyring.sh readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} containers: - name: manila-share {{ tuple $envAll "manila_share" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.share | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "manila" "container" "manila_share" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/manila-share.sh env: {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/manila/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.manila.oslo_concurrency.lock_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: etcmanila mountPath: /etc/manila - name: state-tmp mountPath: /var/lib/manila - name: manila-etc mountPath: /etc/manila/manila.conf subPath: manila.conf readOnly: true - name: manila-etc-snippets mountPath: /etc/manila/manila.conf.d/ readOnly: true - name: manila-etc mountPath: /etc/manila/rootwrap.conf subPath: rootwrap.conf - name: manila-etc mountPath: /etc/sudoers.d/kolla_manila_sudoers subPath: manila_sudoers readOnly: true - name: manila-etc mountPath: /etc/sudoers.d/kolla_manila_volume_sudoers subPath: manila_sudoers readOnly: true - mountPath: /run/openvswitch name: run-openvswitch readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "share" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/manila/rootwrap.d/%s.filters" $filePrefix }} - name: manila-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} {{- if .Values.conf.manila.DEFAULT.log_config_append }} - name: manila-etc mountPath: {{ .Values.conf.manila.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.manila.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: manila-etc mountPath: /etc/manila/policy.yaml subPath: policy.yaml readOnly: true - name: manila-bin mountPath: /tmp/manila-share.sh subPath: manila-share.sh readOnly: true {{- if $isCephfsEnabled }} - name: etcceph mountPath: /etc/ceph - name: ceph-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal "path" "/etc/manila/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_manila_share.volumeMounts }}{{ toYaml $mounts_manila_share.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-shared emptyDir: {} - name: state-tmp emptyDir: {} - name: etcmanila emptyDir: {} - name: run-openvswitch hostPath: path: /run/openvswitch type: Directory - name: manila-etc secret: secretName: manila-etc defaultMode: 0444 - name: manila-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: manila-bin configMap: name: manila-bin defaultMode: 0555 {{- if $isCephfsEnabled }} - name: etcceph emptyDir: {} - name: ceph-etc configMap: name: {{ .Values.ceph_client.configmap }} defaultMode: 0444 - name: ceph-keyring secret: secretName: {{ .Values.secrets.rbd | quote }} {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.share.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_manila_share.volumes }}{{ toYaml $mounts_manila_share.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: manila/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: manila/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "sharev2" "backendPort" "m-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: manila/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.bootstrap" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "5" {{- end }} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "manila" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.manila.DEFAULT.log_config_append "jobAnnotations" (include "metadata.annotations.job.bootstrap" . | fromYaml) -}} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.share.api.internal -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: manila/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "manila" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: manila/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "manila" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: manila/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "manila" "podVolMounts" .Values.pod.mounts.manila_db_sync.manila_db_sync.volumeMounts "podVols" .Values.pod.mounts.manila_db_sync.manila_db_sync.volumes -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: manila/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "manila" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: manila/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "manila" "serviceTypes" ( tuple "sharev2" ) "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) -}} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.share.api.internal -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: manila/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "manila" "serviceTypes" ( tuple "sharev2" ) "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) -}} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.share.api.internal -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: manila/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "manila" "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.share.api.internal -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: manila/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "manila" "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) -}} {{- if .Values.pod.tolerations.manila.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: manila/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "manila" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: manila/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: manila-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "manila" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: manila/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.manila_tests.manila_tests }} {{- $mounts_tests_init := .Values.pod.mounts.manila_tests.init_container }} {{- $serviceAccountName := print $envAll.deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.deployment_name "-test" }} labels: {{ tuple $envAll "manila" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "manila-test" "containerNames" (list "init" "manila-test" "manila-test-ks-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: restartPolicy: Never {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ tuple "manila_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "manila_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: manila-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "manila_test_ks_user" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: manila-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{- if and .Values.manifests.certificates .Values.secrets.tls.share.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.share.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{- end }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" (and .Values.manifests.certificates .Values.secrets.tls.share.api.internal) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: manila-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "manila_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6}} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" (and .Values.manifests.certificates .Values.secrets.tls.share.api.internal) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.deployment_name}} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: manila-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: manila-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally - name: rally-work mountPath: /home/rally/.rally {{- if and .Values.manifests.certificates .Values.secrets.tls.share.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.share.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{- end }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: manila-etc secret: secretName: manila-etc defaultMode: 0444 - name: manila-bin configMap: name: manila-bin defaultMode: 0555 - name: rally-db emptyDir: {} - name: rally-work emptyDir: {} {{- if and .Values.manifests.certificates .Values.secrets.tls.share.api.internal }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.share.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: manila/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "manila" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: manila/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "sharev2" ) }} {{- end }} ================================================ FILE: manila/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "manila" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: manila/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "manila" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: manila/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: manila/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "sharev2" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: m-api port: {{ tuple "sharev2" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "manila" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: manila/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "sharev2" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: manila/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for manila. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled data: node_selector_key: openstack-control-plane node_selector_value: enabled scheduler: node_selector_key: openstack-control-plane node_selector_value: enabled share: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble manila_db_sync: quay.io/airshipit/manila:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble manila_api: quay.io/airshipit/manila:2025.1-ubuntu_noble manila_data: quay.io/airshipit/manila:2025.1-ubuntu_noble manila_scheduler: quay.io/airshipit/manila:2025.1-ubuntu_noble manila_share: quay.io/airshipit/manila:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync pod: security_context: manila: pod: runAsUser: 42424 container: manila_api: allowPrivilegeEscalation: false readOnlyRootFilesystem: true manila_data: allowPrivilegeEscalation: false readOnlyRootFilesystem: true manila_scheduler: allowPrivilegeEscalation: false readOnlyRootFilesystem: true manila_share: readOnlyRootFilesystem: true privileged: true test: pod: runAsUser: 42424 container: manila_test: allowPrivilegeEscalation: false readOnlyRootFilesystem: true use_fqdn: # NOTE: Setting the option here to true will cause use $(hostname --fqdn) # as the host name by default. If the short name is desired # $(hostname --short), set the option to false. Specifying a host in the # manila.conf via the conf section will supersede the value of this option. share: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: manila: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule mounts: manila_api: init_container: null manila_api: volumeMounts: volumes: manila_scheduler: init_container: null manila_scheduler: volumeMounts: volumes: manila_data: init_container: null manila_data: volumeMounts: volumes: manila_share: init_container: null manila_share: volumeMounts: volumes: manila_bootstrap: init_container: null manila_bootstrap: volumeMounts: volumes: manila_tests: init_container: null manila_tests: volumeMounts: volumes: manila_db_sync: manila_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/manila/manila.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: manila_api: [] manila_scheduler: [] manila_data: [] manila_share: [] manila_db_sync: [] replicas: api: 1 data: 1 scheduler: 1 share: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 sheduler: min_available: 0 share: min_available: 0 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" data: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" scheduler: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" share: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30486 network_policy: manila: ingress: - {} egress: - {} bootstrap: enabled: true ks_user: admin script: null structured: flavors: manila-service-flavor: id: 100 name: "manila-service-flavor" ram: 512 vcpus: 1 disk: 5 ephemeral: 0 public: true images: manila-service-image: id: null name: "manila-service-image" source_url: "https://tarballs.opendev.org/openstack/manila-image-elements/images/" image_file: "manila-service-image-master.qcow2" image_type: qcow2 container_format: bare private: false ceph_client: configmap: ceph-etc dependencies: dynamic: common: local_image_registry: jobs: - manila-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - manila-db-sync - manila-ks-user - manila-ks-endpoints - manila-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging data: jobs: - manila-db-sync - manila-ks-user - manila-ks-endpoints - manila-rabbit-init scheduler: jobs: - manila-db-sync - manila-ks-user - manila-ks-endpoints - manila-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging share: # pod: # - requireSameNode: true # labels: # application: openvswitch # component: server jobs: - manila-db-sync - manila-ks-user - manila-ks-endpoints - manila-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - manila-db-init services: - endpoint: internal service: oslo_db image_repo_sync: services: - endpoint: internal service: local_image_registry ks_endpoints: jobs: - manila-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - endpoint: internal service: oslo_messaging conf: paste: composite:osapi_share: use: call:manila.api:root_app_factory /: apiversions /healthcheck: healthcheck /v1: openstack_share_api /v2: openstack_share_api_v2 composite:openstack_share_api: use: call:manila.api.middleware.auth:pipeline_factory noauth: cors faultwrap http_proxy_to_wsgi sizelimit osprofiler noauth api keystone: cors faultwrap http_proxy_to_wsgi sizelimit osprofiler authtoken keystonecontext api keystone_nolimit: cors faultwrap http_proxy_to_wsgi sizelimit osprofiler authtoken keystonecontext api composite:openstack_share_api_v2: use: call:manila.api.middleware.auth:pipeline_factory noauth: cors faultwrap http_proxy_to_wsgi sizelimit osprofiler noauth apiv2 noauthv2: cors faultwrap http_proxy_to_wsgi sizelimit osprofiler noauthv2 apiv2 keystone: cors faultwrap http_proxy_to_wsgi sizelimit osprofiler authtoken keystonecontext apiv2 keystone_nolimit: cors faultwrap http_proxy_to_wsgi sizelimit osprofiler authtoken keystonecontext apiv2 filter:faultwrap: paste.filter_factory: manila.api.middleware.fault:FaultWrapper.factory filter:noauth: paste.filter_factory: manila.api.middleware.auth:NoAuthMiddleware.factory filter:noauthv2: paste.filter_factory: manila.api.middleware.auth:NoAuthMiddlewarev2_60.factory filter:sizelimit: paste.filter_factory: oslo_middleware.sizelimit:RequestBodySizeLimiter.factory filter:osprofiler: paste.filter_factory: osprofiler.web:WsgiMiddleware.factory filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory app:api: paste.app_factory: manila.api.v1.router:APIRouter.factory app:apiv2: paste.app_factory: manila.api.v2.router:APIRouter.factory pipeline:apiversions: pipeline: cors faultwrap http_proxy_to_wsgi osshareversionapp app:osshareversionapp: paste.app_factory: manila.api.versions:VersionsRouter.factory filter:keystonecontext: paste.filter_factory: manila.api.middleware.auth:ManilaKeystoneContext.factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: manila app:healthcheck: paste.app_factory: oslo_middleware:Healthcheck.app_factory backends: disable_by_file disable_by_file_path: /etc/manila/healthcheck_disable policy: {} manila_sudoers: | # This sudoers file supports rootwrap for both Kolla and LOCI Images. Defaults !requiretty Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin:/var/lib/kolla/venv/bin" manila ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/manila-rootwrap /etc/manila/rootwrap.conf *, /var/lib/openstack/bin/manila-rootwrap /etc/manila/rootwrap.conf * rootwrap_filters: share: pods: - share content: | # manila-rootwrap command filters for share nodes # This file should be owned by (and only-writeable by) the root user [Filters] # manila/utils.py : 'chown', '%s', '%s' chown: CommandFilter, chown, root # manila/utils.py : 'cat', '%s' cat: CommandFilter, cat, root # manila/share/drivers/lvm.py: 'mkfs.ext4', '/dev/mapper/%s' mkfs.ext4: CommandFilter, mkfs.ext4, root # manila/share/drivers/lvm.py: 'mkfs.ext3', '/dev/mapper/%s' mkfs.ext3: CommandFilter, mkfs.ext3, root # manila/share/drivers/lvm.py: 'smbd', '-s', '%s', '-D' smbd: CommandFilter, smbd, root smb: CommandFilter, smb, root # manila/share/drivers/lvm.py: 'rmdir', '%s' rmdir: CommandFilter, rmdir, root # manila/share/drivers/lvm.py: 'dd' 'count=0', 'if=%s' % srcstr, 'of=%s' dd: CommandFilter, dd, root # manila/share/drivers/lvm.py: 'fsck', '-pf', %s fsck: CommandFilter, fsck, root # manila/share/drivers/lvm.py: 'resize2fs', %s resize2fs: CommandFilter, resize2fs, root # manila/share/drivers/helpers.py: 'smbcontrol', 'all', 'close-share', '%s' smbcontrol: CommandFilter, smbcontrol, root # manila/share/drivers/helpers.py: 'net', 'conf', 'addshare', '%s', '%s', 'writeable=y', 'guest_ok=y # manila/share/drivers/helpers.py: 'net', 'conf', 'delshare', '%s' # manila/share/drivers/helpers.py: 'net', 'conf', 'setparm', '%s', '%s', '%s' # manila/share/drivers/helpers.py: 'net', 'conf', 'getparm', '%s', 'hosts allow' net: CommandFilter, net, root # manila/share/drivers/helpers.py: 'cp', '%s', '%s' cp: CommandFilter, cp, root # manila/share/drivers/helpers.py: 'service', '%s', '%s' service: CommandFilter, service, root # manila/share/drivers/lvm.py: 'lvremove', '-f', "%s/%s lvremove: CommandFilter, lvremove, root # manila/share/drivers/lvm.py: 'lvextend', '-L', '%sG''-n', %s lvextend: CommandFilter, lvextend, root # manila/share/drivers/lvm.py: 'lvcreate', '-L', %s, '-n', %s lvcreate: CommandFilter, lvcreate, root # manila/share/drivers/lvm.py: 'vgs', '--noheadings', '-o', 'name' # manila/share/drivers/lvm.py: 'vgs', %s, '--rows', '--units', 'g' vgs: CommandFilter, vgs, root # manila/share/drivers/lvm.py: 'tune2fs', '-U', 'random', '%volume-snapshot%' tune2fs: CommandFilter, tune2fs, root # manila/share/drivers/generic.py: 'sed', '-i', '\'/%s/d\'', '%s' sed: CommandFilter, sed, root # manila/share/drivers/glusterfs.py: 'mkdir', '%s' # manila/share/drivers/ganesha/manager.py: 'mkdir', '-p', '%s' mkdir: CommandFilter, mkdir, root # manila/share/drivers/glusterfs.py: 'rm', '-rf', '%s' rm: CommandFilter, rm, root # manila/share/drivers/glusterfs.py: 'mount', '-t', 'glusterfs', '%s', '%s' # manila/share/drivers/glusterfs/glusterfs_native.py: 'mount', '-t', 'glusterfs', '%s', '%s' mount: CommandFilter, mount, root # manila/share/drivers/glusterfs.py: 'gluster', '--xml', 'volume', 'info', '%s' # manila/share/drivers/glusterfs.py: 'gluster', 'volume', 'set', '%s', 'nfs.export-dir', '%s' gluster: CommandFilter, gluster, root # manila/network/linux/ip_lib.py: 'ip', 'netns', 'exec', '%s', '%s' ip: CommandFilter, ip, root # manila/network/linux/interface.py: 'ovs-vsctl', 'add-port', '%s', '%s' ovs-vsctl: CommandFilter, ovs-vsctl, root # manila/share/drivers/glusterfs/glusterfs_native.py: 'find', '%s', '-mindepth', '1', '!', '-path', '%s', '!', '-path', '%s', '-delete' # manila/share/drivers/glusterfs/glusterfs_native.py: 'find', '%s', '-mindepth', '1', '-delete' find: CommandFilter, find, root # manila/share/drivers/glusterfs/glusterfs_native.py: 'umount', '%s' umount: CommandFilter, umount, root # GPFS commands # manila/share/drivers/ibm/gpfs.py: 'mmgetstate', '-Y' mmgetstate: CommandFilter, mmgetstate, root # manila/share/drivers/ibm/gpfs.py: 'mmlsattr', '%s' mmlsattr: CommandFilter, mmlsattr, root # manila/share/drivers/ibm/gpfs.py: 'mmcrfileset', '%s', '%s', '--inode-space', 'new' mmcrfileset: CommandFilter, mmcrfileset, root # manila/share/drivers/ibm/gpfs.py: 'mmlinkfileset', '%s', '%s', '-J', '%s' mmlinkfileset: CommandFilter, mmlinkfileset, root # manila/share/drivers/ibm/gpfs.py: 'mmsetquota', '-j', '%s', '-h', '%s', '%s' mmsetquota: CommandFilter, mmsetquota, root # manila/share/drivers/ibm/gpfs.py: 'mmunlinkfileset', '%s', '%s', '-f' mmunlinkfileset: CommandFilter, mmunlinkfileset, root # manila/share/drivers/ibm/gpfs.py: 'mmdelfileset', '%s', '%s', '-f' mmdelfileset: CommandFilter, mmdelfileset, root # manila/share/drivers/ibm/gpfs.py: 'mmcrsnapshot', '%s', '%s', '-j', '%s' mmcrsnapshot: CommandFilter, mmcrsnapshot, root # manila/share/drivers/ibm/gpfs.py: 'mmdelsnapshot', '%s', '%s', '-j', '%s' mmdelsnapshot: CommandFilter, mmdelsnapshot, root # manila/share/drivers/ibm/gpfs.py: 'rsync', '-rp', '%s', '%s' rsync: CommandFilter, rsync, root # manila/share/drivers/ibm/gpfs.py: 'exportfs' exportfs: CommandFilter, exportfs, root # manila/share/drivers/ibm/gpfs.py: 'stat', '--format=%F', '%s' stat: CommandFilter, stat, root # manila/share/drivers/ibm/gpfs.py: 'df', '-P', '-B', '1', '%s' df: CommandFilter, df, root # manila/share/drivers/ibm/gpfs.py: 'chmod', '777', '%s' chmod: CommandFilter, chmod, root # manila/share/drivers/ibm/gpfs.py: 'mmnfs', 'export', '%s', '%s' mmnfs: CommandFilter, mmnfs, root # manila/share/drivers/ibm/gpfs.py: 'mmlsfileset', '%s', '-J', '%s', '-L' mmlsfileset: CommandFilter, mmlsfileset, root # manila/share/drivers/ibm/gpfs.py: 'mmchfileset', '%s', '-J', '%s', '-j', '%s' mmchfileset: CommandFilter, mmchfileset, root # manila/share/drivers/ibm/gpfs.py: 'mmlsquota', '-j', '-J', '%s', '%s' mmlsquota: CommandFilter, mmlsquota, root # manila/share/drivers/ganesha/manager.py: 'mv', '%s', '%s' mv: CommandFilter, mv, root # manila/share/drivers/ganesha/manager.py: 'mktemp', '-p', '%s', '-t', '%s' mktemp: CommandFilter, mktemp, root # manila/share/drivers/ganesha/manager.py: shcat: RegExpFilter, sh, root, sh, -c, echo '((.|\n)*)' > /.* # manila/share/drivers/ganesha/manager.py: dbus-addexport: RegExpFilter, dbus-send, root, dbus-send, --print-reply, --system, --dest=org\.ganesha\.nfsd, /org/ganesha/nfsd/ExportMgr, org\.ganesha\.nfsd\.exportmgr\.(Add|Remove)Export, .*, .* # manila/share/drivers/ganesha/manager.py: dbus-removeexport: RegExpFilter, dbus-send, root, dbus-send, --print-reply, --system, --dest=org\.ganesha\.nfsd, /org/ganesha/nfsd/ExportMgr, org\.ganesha\.nfsd\.exportmgr\.(Add|Remove)Export, .* # manila/share/drivers/ganesha/manager.py: dbus-updateexport: RegExpFilter, dbus-send, root, dbus-send, --print-reply, --system, --dest=org\.ganesha\.nfsd, /org/ganesha/nfsd/ExportMgr, org\.ganesha\.nfsd\.exportmgr\.UpdateExport, .*, .* # manila/share/drivers/ganesha/manager.py: rmconf: RegExpFilter, sh, root, sh, -c, rm -f /.*/\*\.conf$ # ZFS commands # manila/share/drivers/zfsonlinux/driver.py # manila/share/drivers/zfsonlinux/utils.py zpool: CommandFilter, zpool, root # manila/share/drivers/zfsonlinux/driver.py # manila/share/drivers/zfsonlinux/utils.py zfs: CommandFilter, zfs, root # manila/share/drivers/zfsonlinux/driver.py kill: CommandFilter, kill, root # manila/data/utils.py: 'ls', '-pA1', '--group-directories-first', '%s' ls: CommandFilter, ls, root # manila/data/utils.py: 'touch', '--reference=%s', '%s' touch: CommandFilter, touch, root # manila/share/drivers/container/container.py: docker docker: CommandFilter, docker, root # manila/share/drivers/container/container.py: brctl brctl: CommandFilter, brctl, root # manila/share/drivers/container/storage_helper.py: e2fsck # manila/share/drivers/generic.py: e2fsck # manila/share/drivers/lvm.py: e2fsck e2fsck: CommandFilter, e2fsck, root # manila/share/drivers/lvm.py: lvconvert --merge %s lvconvert: CommandFilter, lvconvert, root # manila/data/utils.py: 'sha256sum', '%s' sha256sum: CommandFilter, sha256sum, root # manila/utils.py: 'tee', '%s' tee: CommandFilter, tee, root # manila/share/drivers/container/storage_helper.py: lvs -o lv_size --noheadings --nosuffix --units g lvs: CommandFilter, lvs, root # manila/share/drivers/container/storage_helper.py: lvrename --autobackup n lvrename: CommandFilter, lvrename, root rootwrap: | # Configuration for manila-rootwrap # This file should be owned by (and only-writeable by) the root user [DEFAULT] # List of directories to load filter definitions from (separated by ','). # These directories MUST all be only writeable by root ! filters_path=/etc/manila/rootwrap.d,/usr/share/manila/rootwrap # List of directories to search executables in, in case filters do not # explicitly specify a full path (separated by ',') # If not specified, defaults to system PATH environment variable. # These directories MUST all be only writeable by root ! exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/sbin,/usr/local/bin,/usr/lpp/mmfs/bin # Enable logging to syslog # Default value is False use_syslog=False # Which syslog facility to use. # Valid values include auth, authpriv, syslog, user0, user1... # Default value is 'syslog' syslog_log_facility=syslog # Which messages to log. # INFO means log all usage # ERROR means only log unsuccessful attempts syslog_log_level=ERROR manila: DEFAULT: default_share_type: default default_share_group_type: default share_name_template: share-%s rootwrap_config: /etc/manila/rootwrap.conf api_paste_config: /etc/manila/api-paste.ini enabled_share_backends: generic enabled_share_protocols: NFS cephfs_auth_id: manila keystone_authtoken: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT endpoint_type: internalURL service_type: sharev2 neutron: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT endpoint_type: internalURL nova: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT endpoint_type: internalURL cinder: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT endpoint_type: internalURL glance: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT endpoint_type: internalURL database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" generic: share_backend_name: GENERIC share_driver: manila.share.drivers.generic.GenericShareDriver driver_handles_share_servers: true # manila-service-flavor service_instance_flavor_id: 100 service_image_name: manila-service-image service_instance_user: manila service_instance_password: manila # # Module path to the Virtual Interface (VIF) driver class. This option # # is used only by drivers operating in # # `driver_handles_share_servers=True` mode that provision OpenStack # # compute instances as share servers. This option is only supported # # with Neutron networking. Drivers provided in tree work with Linux # # Bridge (manila.network.linux.interface.BridgeInterfaceDriver) and # # OVS (manila.network.linux.interface.OVSInterfaceDriver). If the # # manila-share service is running on a host that is connected to the # # administrator network, a no-op driver # # (manila.network.linux.interface.NoopInterfaceDriver) may be used. # # (string value) # interface_driver: manila.network.linux.interface.OVSInterfaceDriver oslo_policy: policy_file: /etc/manila/policy.yaml oslo_concurrency: lock_path: /var/lock oslo_messaging_notifications: driver: messagingv2 oslo_middleware: enable_proxy_headers_parsing: true oslo_messaging_rabbit: rabbit_ha_queues: true logging: loggers: keys: - root - manila handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_manila: level: INFO handlers: - stdout qualname: manila logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" rally_tests: tests: ManilaShares.create_and_delete_share: - args: share_proto: "nfs" size: 1 share_type: "dhss_false" min_sleep: 1 max_sleep: 2 context: quotas: manila: shares: 0 gigabytes: 0 share_networks: 0 users: tenants: 2 users_per_tenant: 1 user_choice_method: "round_robin" manila_share_networks: use_share_networks: true runner: concurrency: 4 times: 4 type: constant sla: failure_rate: max: 0 manila_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "manila-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 module: "manila.wsgi.api:application" stats: 0.0.0.0:1717 stats-http: true # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: manila-keystone-admin manila: manila-keystone-user test: manila-keystone-test oslo_db: admin: manila-db-admin manila: manila-db-user rbd: manila-keyring oslo_messaging: admin: manila-rabbitmq-admin manila: manila-rabbitmq-user tls: share: api: public: manila-tls-public internal: manila-tls-internal oci_image_registry: manila: manila-oci-image-registry endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false manila: username: manila password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default manila: role: admin region_name: RegionOne username: manila password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: manila-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 sharev2: name: manilav2 hosts: default: manila-api public: manila host_fqdn_override: default: null path: default: '/v2' healthcheck: /healthcheck scheme: default: http service: http port: api: default: 8786 public: 80 service: 8786 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct manila: username: manila password: password hosts: default: mariadb host_fqdn_override: default: null path: /manila scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct manila: username: manila password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /manila scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false configmap_bin: true configmap_etc: true deployment_api: true deployment_scheduler: true deployment_data: true deployment_share: true ingress_api: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_rabbit_init: true job_ks_endpoints: true job_ks_service: true job_ks_user: true pdb_api: true pod_rally_test: true secret_db: true network_policy: false secret_ingress_tls: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_ingress_api: true service_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: mariadb/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *~ # Various IDEs .project .idea/ *.tmproj ================================================ FILE: mariadb/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v10.6.7 description: OpenStack-Helm MariaDB name: mariadb version: 2025.2.0 home: https://mariadb.com/kb/en/ icon: http://badges.mariadb.org/mariadb-badge-180x60.png sources: - https://github.com/MariaDB/server - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: mariadb/README.rst ================================================ openstack-helm/mariadb ====================== By default, this chart creates a 3-member mariadb galera cluster. This chart leverages StatefulSets, with persistent storage. It creates a job that acts as a temporary standalone galera cluster. This host is bootstrapped with authentication and then the WSREP bindings are exposed publicly. The cluster members being StatefulSets are provisioned one at a time. The first host must be marked as ``Ready`` before the next host will be provisioned. This is determined by the readinessProbes which actually validate that MySQL is up and responsive. The configuration leverages xtrabackup-v2 for synchronization. This may later be augmented to leverage rsync which has some benefits. Once the seed job completes, which completes only when galera reports that it is Synced and all cluster members are reporting in thus matching the cluster count according to the job to the replica count in the helm values configuration, the job is terminated. When the job is no longer active, future StatefulSets provisioned will leverage the existing cluster members as gcomm endpoints. It is only when the job is running that the cluster members leverage the seed job as their gcomm endpoint. This ensures you can restart members and scale the cluster. The StatefulSets all leverage PVCs to provide stateful storage to ``/var/lib/mysql``. You must ensure that your control nodes that should receive mariadb instances are labeled with ``openstack-control-plane=enabled``, or whatever you have configured in values.yaml for the label configuration: :: kubectl label nodes openstack-control-plane=enabled --all ================================================ FILE: mariadb/templates/bin/_backup_mariadb.sh.tpl ================================================ #!/bin/bash SCOPE=${1:-"all"} # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. source /tmp/backup_main.sh # Export the variables required by the framework # Note: REMOTE_BACKUP_ENABLED, STORAGE_POLICY and CONTAINER_NAME are already # exported. export DB_NAMESPACE=${MARIADB_POD_NAMESPACE} export DB_NAME="mariadb" export LOCAL_DAYS_TO_KEEP=${MARIADB_LOCAL_BACKUP_DAYS_TO_KEEP} export REMOTE_DAYS_TO_KEEP=${MARIADB_REMOTE_BACKUP_DAYS_TO_KEEP} export REMOTE_BACKUP_RETRIES=${NUMBER_OF_RETRIES_SEND_BACKUP_TO_REMOTE} export MIN_DELAY_SEND_REMOTE=${MIN_DELAY_SEND_BACKUP_TO_REMOTE} export MAX_DELAY_SEND_REMOTE=${MAX_DELAY_SEND_BACKUP_TO_REMOTE} export ARCHIVE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${DB_NAMESPACE}/${DB_NAME}/archive # Dump all the database files to existing $TMP_DIR and save logs to $LOG_FILE dump_databases_to_directory() { TMP_DIR=$1 LOG_FILE=$2 SCOPE=${3:-"all"} MYSQL="mariadb \ --defaults-file=/etc/mysql/admin_user.cnf \ --connect-timeout 10" MYSQLDUMP="mariadb-dump \ --defaults-file=/etc/mysql/admin_user.cnf" if [[ "${SCOPE}" == "all" ]]; then MYSQL_DBNAMES=( $($MYSQL --silent --skip-column-names -e \ "show databases;" | \ grep -ivE 'information_schema|performance_schema|mysql|sys') ) else if [[ "${SCOPE}" != "information_schema" && "${SCOPE}" != "performance_schema" && "${SCOPE}" != "mysql" && "${SCOPE}" != "sys" ]]; then MYSQL_DBNAMES=( ${SCOPE} ) else log ERROR "It is not allowed to backup database ${SCOPE}." return 1 fi fi #check if there is a database to backup, otherwise exit if [[ -z "${MYSQL_DBNAMES// }" ]] then log INFO "There is no database to backup" return 0 fi #Create a list of Databases printf "%s\n" "${MYSQL_DBNAMES[@]}" > $TMP_DIR/db.list if [[ "${SCOPE}" == "all" ]]; then #Retrieve and create the GRANT file for all the users {{- if .Values.manifests.certificates }} SSL_DSN=";mysql_ssl=1" SSL_DSN="$SSL_DSN;mysql_ssl_client_key=/etc/mysql/certs/tls.key" SSL_DSN="$SSL_DSN;mysql_ssl_client_cert=/etc/mysql/certs/tls.crt" SSL_DSN="$SSL_DSN;mysql_ssl_ca_file=/etc/mysql/certs/ca.crt" if ! pt-show-grants --defaults-file=/etc/mysql/admin_user.cnf $SSL_DSN \ {{- else }} if ! pt-show-grants --defaults-file=/etc/mysql/admin_user.cnf \ {{- end }} 2>>"$LOG_FILE" > "$TMP_DIR"/grants.sql; then log ERROR "Failed to create GRANT for all the users" return 1 fi fi #Retrieve and create the GRANT files per DB for db in "${MYSQL_DBNAMES[@]}" do echo $($MYSQL --skip-column-names -e "select concat('show grants for ',user,';') \ from mysql.db where ucase(db)=ucase('$db');") | \ sed -r "s/show grants for ([a-zA-Z0-9_-]*)/show grants for '\1'/g" | \ $MYSQL --silent --skip-column-names 2>>$LOG_FILE > $TMP_DIR/${db}_grant.sql if [ "$?" -eq 0 ] then sed -i 's/$/;/' $TMP_DIR/${db}_grant.sql else log ERROR "Failed to create GRANT files for ${db}" return 1 fi done #Dumping the database SQL_FILE=mariadb.$MARIADB_POD_NAMESPACE.${SCOPE} $MYSQLDUMP $MYSQL_BACKUP_MYSQLDUMP_OPTIONS "${MYSQL_DBNAMES[@]}" \ > $TMP_DIR/${SQL_FILE}.sql 2>>$LOG_FILE if [[ $? -eq 0 && -s $TMP_DIR/${SQL_FILE}.sql ]] then log INFO "Database(s) dumped successfully. (SCOPE = ${SCOPE})" return 0 else log ERROR "Backup failed and need attention. (SCOPE = ${SCOPE})" return 1 fi } # functions from mariadb-verifier chart get_time_delta_secs () { second_delta=0 input_date_second=$( date --date="$1" +%s ) if [ -n "$input_date_second" ]; then current_date=$( date +"%Y-%m-%dT%H:%M:%SZ" ) current_date_second=$( date --date="$current_date" +%s ) ((second_delta=current_date_second-input_date_second)) if [ "$second_delta" -lt 0 ]; then second_delta=0 fi fi echo $second_delta } check_data_freshness () { archive_file=$(basename "$1") archive_date=$(echo "$archive_file" | cut -d'.' -f 4) SCOPE=$2 if [[ "${SCOPE}" != "all" ]]; then log "Data freshness check is skipped for individual database." return 0 fi log "Checking for data freshness in the backups..." # Get some idea of which database.table has changed in the last 30m # Excluding the system DBs and aqua_test_database # changed_tables=$(${MYSQL_LIVE} -e "select TABLE_SCHEMA,TABLE_NAME from \ information_schema.tables where UPDATE_TIME >= SUBTIME(now(),'00:30:00') AND TABLE_SCHEMA \ NOT IN('information_schema', 'mysql', 'performance_schema', 'sys', 'aqua_test_database');" | \ awk '{print $1 "." $2}') if [ -n "${changed_tables}" ]; then delta_secs=$(get_time_delta_secs "$archive_date") age_offset={{ .Values.conf.backup.validateData.ageOffset }} ((age_threshold=delta_secs+age_offset)) data_freshness=false skipped_freshness=false for table in ${changed_tables}; do tab_schema=$(echo "$table" | awk -F. '{print $1}') tab_name=$(echo "$table" | awk -F. '{print $2}') local_table_existed=$(${MYSQL_LOCAL_SHORT_SILENT} -e "select TABLE_SCHEMA,TABLE_NAME from \ INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=\"${tab_schema}\" AND TABLE_NAME=\"${tab_name}\";") if [ -n "$local_table_existed" ]; then # TODO: If last updated field of a table structure has different # patterns (updated/timstamp), it may be worth to parameterize the patterns. datetime=$(${MYSQL_LOCAL_SHORT_SILENT} -e "describe ${table};" | \ awk '(/updated/ || /timestamp/) && /datetime/ {print $1}') if [ -n "${datetime}" ]; then data_ages=$(${MYSQL_LOCAL_SHORT_SILENT} -e "select \ time_to_sec(timediff(now(),${datetime})) from ${table} where ${datetime} is not null order by 1 limit 10;") for age in $data_ages; do if [ "$age" -le $age_threshold ]; then data_freshness=true break fi done # As long as there is an indication of data freshness, no need to check further if [ "$data_freshness" = true ] ; then break fi else skipped_freshness=true log "No indicator to determine data freshness for table $table. Skipped data freshness check." # Dumping out table structure to determine if enhancement is needed to include this table debug_info=$(${MYSQL_LOCAL} --skip-column-names -e "describe ${table};" | awk '{print $2 " " $1}') log "$debug_info" "DEBUG" fi else log "Table $table doesn't exist in local database" skipped_freshness=true fi done if [ "$data_freshness" = true ] ; then log "Database passed integrity (data freshness) check." else if [ "$skipped_freshness" = false ] ; then log "Local backup database restore failed integrity check." "ERROR" log "The backup may not have captured the up-to-date data." "INFO" return 1 fi fi else log "No tables changed in this backup. Skipped data freshness check as the" log "check should have been performed by previous validation runs." fi return 0 } cleanup_local_databases () { old_local_dbs=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|sys' || true) for db in $old_local_dbs; do ${MYSQL_LOCAL_SHORT_SILENT} -e "drop database $db;" done } list_archive_dir () { archive_dir_content=$(ls -1R "$ARCHIVE_DIR") if [ -n "$archive_dir_content" ]; then log "Content of $ARCHIVE_DIR" log "${archive_dir_content}" fi } remove_remote_archive_file () { archive_file=$(basename "$1") token_req_file=$(mktemp --suffix ".json") header_file=$(mktemp) resp_file=$(mktemp --suffix ".json") http_resp="404" HEADER_CONTENT_TYPE="Content-Type: application/json" HEADER_ACCEPT="Accept: application/json" cat << JSON_EOF > "$token_req_file" { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "domain": { "name": "${OS_USER_DOMAIN_NAME}" }, "name": "${OS_USERNAME}", "password": "${OS_PASSWORD}" } } }, "scope": { "project": { "domain": { "name": "${OS_PROJECT_DOMAIN_NAME}" }, "name": "${OS_PROJECT_NAME}" } } } } JSON_EOF http_resp=$(curl -s -X POST "$OS_AUTH_URL/auth/tokens" -H "${HEADER_CONTENT_TYPE}" \ -H "${HEADER_ACCEPT}" -d @"${token_req_file}" -D "$header_file" -o "$resp_file" -w "%{http_code}") if [ "$http_resp" = "201" ]; then OS_TOKEN=$(grep -i "x-subject-token" "$header_file" | cut -d' ' -f2 | tr -d "\r") if [ -n "$OS_TOKEN" ]; then OS_OBJ_URL=$(python3 -c "import json,sys;print([[ep['url'] for ep in obj['endpoints'] if ep['interface']=='public'] for obj in json.load(sys.stdin)['token']['catalog'] if obj['type']=='object-store'][0][0])" < "$resp_file") if [ -n "$OS_OBJ_URL" ]; then http_resp=$(curl -s -X DELETE "$OS_OBJ_URL/$CONTAINER_NAME/$archive_file" \ -H "${HEADER_CONTENT_TYPE}" -H "${HEADER_ACCEPT}" \ -H "X-Auth-Token: ${OS_TOKEN}" -D "$header_file" -o "$resp_file" -w "%{http_code}") fi fi fi if [ "$http_resp" == "404" ] ; then log "Failed to cleanup remote backup. Container object $archive_file is not on RGW." return 1 fi if [ "$http_resp" != "204" ] ; then log "Failed to cleanup remote backup. Cannot delete container object $archive_file" "ERROR" cat "$header_file" cat "$resp_file" fi return 0 } handle_bad_archive_file () { archive_file=$1 if [ ! -d "$BAD_ARCHIVE_DIR" ]; then mkdir -p "$BAD_ARCHIVE_DIR" fi # Move the file to quarantine directory such that # file won't be used for restore in case of recovery # log "Moving $i to $BAD_ARCHIVE_DIR..." mv "$i" "$BAD_ARCHIVE_DIR" log "Removing $i from remote RGW..." if remove_remote_archive_file "$i"; then log "File $i has been successfully removed from RGW." else log "FIle $i cannot be removed form RGW." "ERROR" return 1 fi # Atmost only three bad files are kept. Deleting the oldest if # number of files exceeded the threshold. # bad_files=$(find "$BAD_ARCHIVE_DIR" -name "*.tar.gz" 2>/dev/null | wc -l) if [ "$bad_files" -gt 3 ]; then ((bad_files=bad_files-3)) delete_files=$(find "$BAD_ARCHIVE_DIR" -name "*.tar.gz" 2>/dev/null | sort | head --lines=$bad_files) for b in $delete_files; do log "Deleting $b..." rm -f "${b}" done fi return 0 } cleanup_old_validation_result_file () { clean_files=$(find "$ARCHIVE_DIR" -maxdepth 1 -name "*.passed" 2>/dev/null) for d in $clean_files; do archive_file=${d/.passed} if [ ! -f "$archive_file" ]; then log "Deleting $d as its associated archive file $archive_file nolonger existed." rm -f "${d}" fi done } validate_databases_backup () { archive_file=$1 SCOPE=${2:-"all"} restore_log='/tmp/restore_error.log' tmp_dir=$(mktemp -d) rm -f $restore_log cd "$tmp_dir" log "Decompressing archive $archive_file..." if ! tar zxvf - < "$archive_file" 1>/dev/null; then log "Database restore from local backup failed. Archive decompression failed." "ERROR" return 1 fi db_list_file="$tmp_dir/db.list" if [[ -e "$db_list_file" ]]; then dbs=$(sort < "$db_list_file" | grep -ivE sys | tr '\n' ' ') else dbs=" " fi sql_file="${tmp_dir}/mariadb.${MARIADB_POD_NAMESPACE}.${SCOPE}.sql" if [[ "${SCOPE}" == "all" ]]; then grant_file="${tmp_dir}/grants.sql" else grant_file="${tmp_dir}/${SCOPE}_grant.sql" fi if [[ -f $sql_file ]]; then if $MYSQL_LOCAL < "$sql_file" 2>$restore_log; then local_dbs=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|sys' | sort | tr '\n' ' ') if [ "$dbs" = "$local_dbs" ]; then log "Databases restored successful." else log "Database restore from local backup failed. Database mismatched between local backup and local server" "ERROR" log "Databases restored on local server: $local_dbs" "DEBUG" log "Databases in the local backup: $dbs" "DEBUG" return 1 fi else log "Database restore from local backup failed. $dbs" "ERROR" cat $restore_log return 1 fi if [[ -f $grant_file ]]; then if $MYSQL_LOCAL < "$grant_file" 2>$restore_log; then if ! $MYSQL_LOCAL -e 'flush privileges;'; then log "Database restore from local backup failed. Failed to flush privileges." "ERROR" return 1 fi log "Databases permission restored successful." else log "Database restore from local backup failed. Databases permission failed to restore." "ERROR" cat "$restore_log" cat "$grant_file" log "Local DBs: $local_dbs" "DEBUG" return 1 fi else log "Database restore from local backup failed. There is no permission file available" "ERROR" return 1 fi if ! check_data_freshness "$archive_file" ${SCOPE}; then # Log has already generated during check data freshness return 1 fi else log "Database restore from local backup failed. There is no database file available to restore from" "ERROR" return 1 fi return 0 } # end of functions form mariadb verifier chart # Verify all the databases backup archives verify_databases_backup_archives() { SCOPE=${1:-"all"} # verification code export DB_NAME="mariadb" export ARCHIVE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${MARIADB_POD_NAMESPACE}/${DB_NAME}/archive export BAD_ARCHIVE_DIR=${ARCHIVE_DIR}/quarantine export MYSQL_OPTS="--silent --skip-column-names" export MYSQL_LIVE="mariadb ${MYSQL_OPTS}" export MYSQL_LOCAL_OPTS="" export MYSQL_LOCAL_SHORT="mariadb ${MYSQL_LOCAL_OPTS} --connect-timeout 2" export MYSQL_LOCAL_SHORT_SILENT="${MYSQL_LOCAL_SHORT} ${MYSQL_OPTS}" export MYSQL_LOCAL="mariadb ${MYSQL_LOCAL_OPTS} --connect-timeout 10" max_wait={{ .Values.conf.mariadb_server.setup_wait.iteration }} duration={{ .Values.conf.mariadb_server.setup_wait.duration }} counter=0 dbisup=false log "Waiting for Mariadb backup verification server to start..." # During Mariadb init/startup process, a temporary server is startup # and shutdown prior to starting up the normal server. # To avoid prematurely determine server availability, lets snooze # a bit to give time for the process to complete prior to issue # mysql commands. # while [ $counter -lt $max_wait ]; do if ! $MYSQL_LOCAL_SHORT -e 'select 1' > /dev/null 2>&1 ; then sleep $duration ((counter=counter+1)) else # Lets sleep for an additional duration just in case async # init takes a bit more time to complete. # sleep $duration dbisup=true counter=$max_wait fi done if ! $dbisup; then log "Mariadb backup verification server is not running" "ERROR" return 1 fi # During Mariadb init process, a test database will be briefly # created and deleted. Adding to the exclusion list for some # edge cases # clean_db=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|test|sys' || true) if [[ -z "${clean_db// }" ]]; then log "Clean Server is up and running" else cleanup_local_databases log "Old databases found on the Mariadb backup verification server were cleaned." clean_db=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|test|sys' || true) if [[ -z "${clean_db// }" ]]; then log "Clean Server is up and running" else log "Cannot clean old databases on verification server." "ERROR" return 1 fi log "The server is ready for verification." fi # Starting with 10.4.13, new definer mariadb.sys was added. However, mariadb.sys was deleted # during init mariadb as it was not on the exclusion list. This corrupted the view of mysql.user. # Insert the tuple back to avoid other similar issues with error i.e # The user specified as a definer ('mariadb.sys'@'localhost') does not exist # # Before insert the tuple mentioned above, we should make sure that the MariaDB version is 10.4.+ mariadb_version=$($MYSQL_LOCAL_SHORT -e "status" | grep -E '^Server\s+version:') log "Current database ${mariadb_version}" if [[ ! -z ${mariadb_version} && -z $(grep '10.2' <<< ${mariadb_version}) ]]; then if [[ -z $(grep 'mariadb.sys' <<< $($MYSQL_LOCAL_SHORT mysql -e "select * from global_priv where user='mariadb.sys'")) ]]; then $MYSQL_LOCAL_SHORT -e "insert into mysql.global_priv values ('localhost','mariadb.sys',\ '{\"access\":0,\"plugin\":\"mysql_native_password\",\"authentication_string\":\"\",\"account_locked\":true,\"password_last_changed\":0}');" $MYSQL_LOCAL_SHORT -e 'flush privileges;' fi fi # Ensure archive dir existed if [ -d "$ARCHIVE_DIR" ]; then # List archive dir before list_archive_dir # Ensure the local databases are clean for each restore validation # cleanup_local_databases if [[ "${SCOPE}" == "all" ]]; then archive_files=$(find "$ARCHIVE_DIR" -maxdepth 1 -name "*.tar.gz" 2>/dev/null | sort) for i in $archive_files; do archive_file_passed=$i.passed if [ ! -f "$archive_file_passed" ]; then log "Validating archive file $i..." if validate_databases_backup "$i"; then touch "$archive_file_passed" else if handle_bad_archive_file "$i"; then log "File $i has been removed from RGW." else log "File $i cannot be removed from RGW." "ERROR" return 1 fi fi fi done else archive_files=$(find "$ARCHIVE_DIR" -maxdepth 1 -name "*.tar.gz" 2>/dev/null | grep "${SCOPE}" | sort) for i in $archive_files; do archive_file_passed=$i.passed if [ ! -f "$archive_file_passed" ]; then log "Validating archive file $i..." if validate_databases_backup "${i}" "${SCOPE}"; then touch "$archive_file_passed" else if handle_bad_archive_file "$i"; then log "File $i has been removed from RGW." else log "File $i cannot be removed from RGW." "ERROR" return 1 fi fi fi done fi # Cleanup passed files if its archive file nolonger existed cleanup_old_validation_result_file # List archive dir after list_archive_dir fi return 0 } # Call main program to start the database backup backup_databases ${SCOPE} ================================================ FILE: mariadb/templates/bin/_health.sh.tpl ================================================ #!/usr/bin/env bash ########################################################################### # Copyright 2017 The Openstack-Helm Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ######################################################################### set -e MYSQL="mariadb \ --defaults-file=/etc/mysql/admin_user.cnf \ --host=localhost \ {{- if .Values.manifests.certificates }} --ssl-verify-server-cert=false \ --ssl-ca=/etc/mysql/certs/ca.crt \ --ssl-key=/etc/mysql/certs/tls.key \ --ssl-cert=/etc/mysql/certs/tls.crt \ {{- end }} --connect-timeout 2" mysql_query () { TABLE=$1 KEY=$2 $MYSQL -e "show ${TABLE} like \"${KEY}\"" | \ awk "/${KEY}/ { print \$NF; exit }" } function usage { echo "Usage: $0 [-t ] [-d ]" 1>&2 exit 1 } PROBE_TYPE='' while getopts ":t:d:" opt; do case $opt in t) PROBE_TYPE=$OPTARG ;; d) DISK_ALARM_LIMIT=$OPTARG ;; *) usage ;; esac done shift $((OPTIND-1)) check_readiness () { if ! $MYSQL -e 'select 1' > /dev/null 2>&1 ; then echo "Select from mysql failed" exit 1 fi DATADIR=$(mysql_query variables datadir) TMPDIR=$(mysql_query variables tmpdir) for partition in ${DATADIR} ${TMPDIR}; do if [ "$(df --output=pcent ${partition} | grep -Po '\d+')" -ge "${DISK_ALARM_LIMIT:-100}" ]; then echo "[ALARM] Critical high disk space utilization of ${partition}" exit 1 fi done if [ "x$(mysql_query status wsrep_ready)" != "xON" ]; then echo "WSREP says the node can not receive queries" exit 1 fi if [ "x$(mysql_query status wsrep_connected)" != "xON" ]; then echo "WSREP not connected" exit 1 fi if [ "x$(mysql_query status wsrep_cluster_status)" != "xPrimary" ]; then echo "Not in primary cluster" exit 1 fi if [ "x$(mysql_query status wsrep_local_state_comment)" != "xSynced" ]; then echo "WSREP not synced" exit 1 fi } check_liveness () { if pidof mariadb-upgrade > /dev/null 2>&1 ; then echo "The process mariadb-upgrade is active. Skip rest checks" exit 0 fi if ! pidof mariadbd > /dev/null 2>&1 ; then echo "The mariadbd pid not found" exit 1 fi # NOTE(mkarpin): SST process may take significant time in case of large databases, # killing mysqld during SST may destroy all data on the node. local datadir="/var/lib/mysql" if [ -f ${datadir}/sst_in_progress ]; then echo "SST is still in progress, skip further checks as mysql won't respond" else # NOTE(vsaienko): in some cases maria might stuck during IST, or when neighbours # IPs are changed. Here we check that we can connect to mysql socket to ensure # process is alive. if ! $MYSQL -e "show status like 'wsrep_cluster_status'" > /dev/null 2>&1 ; then echo "Can't connect to mysql socket" exit 1 fi # Detect node that is not connected to wsrep provider if [ "x$(mysql_query status wsrep_ready)" != "xON" ]; then echo "WSREP says the node can not receive queries" exit 1 fi if [ "x$(mysql_query status wsrep_connected)" != "xON" ]; then echo "WSREP not connected" exit 1 fi fi } case $PROBE_TYPE in liveness) check_liveness ;; readiness) check_readiness ;; *) echo "Unknown probe type: ${PROBE_TYPE}" usage ;; esac ================================================ FILE: mariadb/templates/bin/_mariadb-wait-for-cluster.py.tpl ================================================ #!/usr/bin/env python3 import datetime from enum import Enum import logging import os import sys import time import pymysql import pykube MARIADB_HOST = os.getenv("MARIADB_HOST") MARIADB_PASSWORD = os.getenv("MARIADB_PASSWORD") MARIADB_REPLICAS = os.getenv("MARIADB_REPLICAS") MARIADB_CLUSTER_STATE_LOG_LEVEL = os.getenv("MARIADB_CLUSTER_STATE_LOG_LEVEL", "INFO") MARIADB_CLUSTER_STABILITY_COUNT = int( os.getenv("MARIADB_CLUSTER_STABILITY_COUNT", "30") ) MARIADB_CLUSTER_STABILITY_WAIT = int(os.getenv("MARIADB_CLUSTER_STABILITY_WAIT", "4")) MARIADB_CLUSTER_CHECK_WAIT = int(os.getenv("MARIADB_CLUSTER_CHECK_WAIT", "30")) MARIADB_CLUSTER_STATE_CONFIGMAP = os.getenv("MARIADB_CLUSTER_STATE_CONFIGMAP") MARIADB_CLUSTER_STATE_CONFIGMAP_NAMESPACE = os.getenv( "MARIADB_CLUSTER_STATE_CONFIGMAP_NAMESPACE", "openstack" ) MARIADB_CLUSTER_STATE_PYKUBE_REQUEST_TIMEOUT = int( os.getenv("MARIADB_CLUSTER_STATE_PYKUBE_REQUEST_TIMEOUT", 60) ) log_level = MARIADB_CLUSTER_STATE_LOG_LEVEL logging.basicConfig( stream=sys.stdout, format="%(asctime)s %(levelname)s %(name)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) LOG = logging.getLogger("mariadb-cluster-wait") LOG.setLevel(log_level) def login(): config = pykube.KubeConfig.from_env() client = pykube.HTTPClient( config=config, timeout=MARIADB_CLUSTER_STATE_PYKUBE_REQUEST_TIMEOUT ) LOG.info(f"Created k8s api client from context {config.current_context}") return client api = login() cluster_state_map = ( pykube.ConfigMap.objects(api) .filter(namespace=MARIADB_CLUSTER_STATE_CONFIGMAP_NAMESPACE) .get_by_name(MARIADB_CLUSTER_STATE_CONFIGMAP) ) def get_current_state(cluster_state_map): cluster_state_map.get( MARIADB_CLUSTER_STATE_INITIAL_BOOTSTRAP_COMPLETED_KEY, "False" ) def retry(times, exceptions): def decorator(func): def newfn(*args, **kwargs): attempt = 0 while attempt < times: try: return func(*args, **kwargs) except exceptions: attempt += 1 LOG.exception( f"Exception thrown when attempting to run {func}, attempt {attempt} of {times}" ) return func(*args, **kwargs) return newfn return decorator class initalClusterState: initial_state_key = "initial-bootstrap-completed.cluster" @retry(times=100, exceptions=(Exception)) def __init__(self, api, namespace, name): self.namespace = namespace self.name = name self.cm = ( pykube.ConfigMap.objects(api) .filter(namespace=self.namespace) .get_by_name(self.name) ) def get_default(self): """We have deployments with completed job, but it is not reflected in the configmap state. Assume when configmap is created more than 1h and we doing update/restart, and key not in map this is existed environment. So we assume the cluster was initialy bootstrapped. This is needed to avoid manual actions. """ now = datetime.datetime.utcnow() created_at = datetime.datetime.strptime( self.cm.obj["metadata"]["creationTimestamp"], "%Y-%m-%dT%H:%M:%SZ" ) delta = datetime.timedelta(seconds=3600) if now - created_at > delta: self.complete() return "COMPLETED" return "NOT_COMPLETED" @property @retry(times=10, exceptions=(Exception)) def is_completed(self): self.cm.reload() if self.initial_state_key in self.cm.obj["data"]: return self.cm.obj["data"][self.initial_state_key] return self.get_default() == "COMPLETED" @retry(times=100, exceptions=(Exception)) def complete(self): patch = {"data": {self.initial_state_key: "COMPLETED"}} self.cm.patch(patch) ics = initalClusterState( api, MARIADB_CLUSTER_STATE_CONFIGMAP_NAMESPACE, MARIADB_CLUSTER_STATE_CONFIGMAP ) if ics.is_completed: LOG.info("The initial bootstrap was completed, skipping wait...") sys.exit(0) LOG.info("Checking for mariadb cluster state.") def is_mariadb_stabe(): try: wsrep_OK = { "wsrep_ready": "ON", "wsrep_connected": "ON", "wsrep_cluster_status": "Primary", "wsrep_local_state_comment": "Synced", "wsrep_cluster_size": str(MARIADB_REPLICAS), } wsrep_vars = ",".join(["'" + var + "'" for var in wsrep_OK.keys()]) db_cursor = pymysql.connect( host=MARIADB_HOST, password=MARIADB_PASSWORD, read_default_file="/etc/mysql/admin_user.cnf" ).cursor() db_cursor.execute(f"SHOW GLOBAL STATUS WHERE Variable_name IN ({wsrep_vars})") wsrep_vars = db_cursor.fetchall() diff = set(wsrep_vars).difference(set(wsrep_OK.items())) if diff: LOG.error(f"The wsrep is not OK: {diff}") else: LOG.info("The wspep is ready") return True except Exception as e: LOG.exception(f"Got exception while checking state. {e}") return False count = 0 ready = False stable_for = 1 while True: if is_mariadb_stabe(): stable_for += 1 LOG.info( f"The cluster is stable for {stable_for} out of {MARIADB_CLUSTER_STABILITY_COUNT}" ) if stable_for == MARIADB_CLUSTER_STABILITY_COUNT: ics.complete() sys.exit(0) else: LOG.info(f"Sleeping for {MARIADB_CLUSTER_STABILITY_WAIT}") time.sleep(MARIADB_CLUSTER_STABILITY_WAIT) continue else: LOG.info("Resetting stable_for count.") stable_for = 0 LOG.info(f"Sleeping for {MARIADB_CLUSTER_CHECK_WAIT}") time.sleep(MARIADB_CLUSTER_CHECK_WAIT) ================================================ FILE: mariadb/templates/bin/_mariadb_controller.py.tpl ================================================ #!/usr/bin/env python3 """ Mariadb controller The script is responsible for set mariadb_role: primary to first active pod in mariadb deployment. Env variables: MARIADB_CONTROLLER_DEBUG: Flag to enable debug when set to 1. MARIADB_CONTROLLER_CHECK_PODS_DELAY: The delay between check pod attempts. MARIADB_CONTROLLER_PYKUBE_REQUEST_TIMEOUT: The timeout for kubernetes http session MARIADB_CONTROLLER_PODS_NAMESPACE: The namespace to look for mariadb pods. MARIADB_MASTER_SERVICE_NAME: The name of master service for mariadb. Changelog: 0.1.0: Initial varsion """ import logging import os import sys import time import pykube MARIADB_CONTROLLER_DEBUG = os.getenv("MARIADB_CONTROLLER_DEBUG") MARIADB_CONTROLLER_CHECK_PODS_DELAY = int( os.getenv("MARIADB_CONTROLLER_CHECK_PODS_DELAY", 10) ) MARIADB_CONTROLLER_PYKUBE_REQUEST_TIMEOUT = int( os.getenv("MARIADB_CONTROLLER_PYKUBE_REQUEST_TIMEOUT", 60) ) MARIADB_CONTROLLER_PODS_NAMESPACE = os.getenv( "MARIADB_CONTROLLER_PODS_NAMESPACE", "openstack" ) MARIADB_MASTER_SERVICE_NAME = os.getenv( "MARIADB_MASTER_SERVICE_NAME", "mariadb" ) log_level = "DEBUG" if MARIADB_CONTROLLER_DEBUG else "INFO" logging.basicConfig( stream=sys.stdout, format="%(asctime)s %(levelname)s %(name)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) LOG = logging.getLogger("mariadb-controller") LOG.setLevel(log_level) def login(): config = pykube.KubeConfig.from_env() client = pykube.HTTPClient( config=config, timeout=MARIADB_CONTROLLER_PYKUBE_REQUEST_TIMEOUT ) LOG.info(f"Created k8s api client from context {config.current_context}") return client api = login() def resource_list(klass, selector, namespace=None): return klass.objects(api).filter(namespace=namespace, selector=selector) def get_mariadb_pods(): sorted_pods = sorted( resource_list( pykube.Pod, {"application": "mariadb", "component": "server"}, MARIADB_CONTROLLER_PODS_NAMESPACE, ).iterator(), key=lambda i: i.name, ) return sorted_pods def get_mariadb_master_service(namespace): return pykube.Service.objects(api).filter(namespace=namespace).get(name=MARIADB_MASTER_SERVICE_NAME) def link_master_service(pod): svc = get_mariadb_master_service(MARIADB_CONTROLLER_PODS_NAMESPACE) svc.reload() if svc.obj['spec']['selector'].get('statefulset.kubernetes.io/pod-name') == pod.name: LOG.debug(f"Nothing to do, master service points to {pod.name}") else: svc.obj['spec']['selector']['statefulset.kubernetes.io/pod-name'] = pod.name svc.update() LOG.info(f"Link master service with {pod.name}") def is_ready(pod): if pod.ready and "deletionTimestamp" not in pod.metadata: return True def main(): while True: for pod in get_mariadb_pods(): pod.reload() if is_ready(pod): link_master_service(pod) break LOG.debug(f"Sleeping for {MARIADB_CONTROLLER_CHECK_PODS_DELAY}") time.sleep(MARIADB_CONTROLLER_CHECK_PODS_DELAY) main() ================================================ FILE: mariadb/templates/bin/_prometheus-create-mysql-user.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e # SLAVE MONITOR # Grants ability to SHOW SLAVE STATUS, SHOW REPLICA STATUS, # SHOW ALL SLAVES STATUS, SHOW ALL REPLICAS STATUS, SHOW RELAYLOG EVENTS. # New privilege added in MariaDB Enterprise Server 10.5.8-5. Alias for REPLICA MONITOR. # # REPLICATION CLIENT # Grants ability to SHOW MASTER STATUS, SHOW SLAVE STATUS, SHOW BINARY LOGS. In ES10.5, # is an alias for BINLOG MONITOR and the capabilities have changed. BINLOG MONITOR grants # ability to SHOW MASTER STATUS, SHOW BINARY LOGS, SHOW BINLOG EVENTS, and SHOW BINLOG STATUS. mariadb_version=$(mariadb --defaults-file=/etc/mysql/admin_user.cnf -e "status" | grep -E '^Server\s+version:') echo "Current database ${mariadb_version}" if [[ ! -z ${mariadb_version} && -z $(grep -E '10.2|10.3|10.4' <<< ${mariadb_version}) ]]; then # In case MariaDB version is 10.2.x-10.4.x - we use old privileges definitions if ! mariadb --defaults-file=/etc/mysql/admin_user.cnf -e \ "CREATE OR REPLACE USER '${EXPORTER_USER}'@'127.0.0.1' IDENTIFIED BY '${EXPORTER_PASSWORD}'; \ GRANT SLAVE MONITOR, PROCESS, BINLOG MONITOR, SLAVE MONITOR, SELECT ON *.* TO '${EXPORTER_USER}'@'127.0.0.1'; \ FLUSH PRIVILEGES;" ; then echo "ERROR: Could not create user: ${EXPORTER_USER}" exit 1 fi else # here we use new MariaDB privileges definitions defines since version 10.5 if ! mariadb --defaults-file=/etc/mysql/admin_user.cnf -e \ "CREATE OR REPLACE USER '${EXPORTER_USER}'@'127.0.0.1' IDENTIFIED BY '${EXPORTER_PASSWORD}'; \ GRANT SLAVE MONITOR, PROCESS, REPLICATION CLIENT, SELECT ON *.* TO '${EXPORTER_USER}'@'127.0.0.1' ${MARIADB_X509}; \ FLUSH PRIVILEGES;" ; then echo "ERROR: Could not create user: ${EXPORTER_USER}" exit 1 fi fi ================================================ FILE: mariadb/templates/bin/_prometheus-mysqld-exporter.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex compareVersions() { echo $1 $2 | \ awk '{ split($1, a, "."); split($2, b, "."); res = -1; for (i = 1; i <= 3; i++){ if (a[i] < b[i]) { res =-1; break; } else if (a[i] > b[i]) { res = 1; break; } else if (a[i] == b[i]) { if (i == 3) { res = 0; break; } else { continue; } } } print res; }' } MYSQL_EXPORTER_VER=`/bin/mysqld_exporter --version 2>&1 | grep "mysqld_exporter" | awk '{print $3}'` #in versions greater than 0.10.0 different configuration flags are used: #https://github.com/prometheus/mysqld_exporter/commit/66c41ac7eb90a74518a6ecf6c6bb06464eb68db8 compverResult=`compareVersions "${MYSQL_EXPORTER_VER}" "0.10.0"` CONFIG_FLAG_PREFIX='-' if [ ${compverResult} -gt 0 ]; then CONFIG_FLAG_PREFIX='--' fi exec /bin/mysqld_exporter \ ${CONFIG_FLAG_PREFIX}config.my-cnf=/etc/mysql/mysql_user.cnf \ ${CONFIG_FLAG_PREFIX}web.listen-address="${POD_IP}:${LISTEN_PORT}" \ ${CONFIG_FLAG_PREFIX}web.telemetry-path="$TELEMETRY_PATH" ================================================ FILE: mariadb/templates/bin/_restore_mariadb.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. {{- $envAll := . }} # Capture the user's command line arguments ARGS=("$@") if [[ -s /tmp/restore_main.sh ]]; then source /tmp/restore_main.sh else echo "File /tmp/restore_main.sh does not exist." exit 1 fi # Export the variables needed by the framework export DB_NAME="mariadb" export DB_NAMESPACE=${MARIADB_POD_NAMESPACE} export ARCHIVE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${DB_NAMESPACE}/${DB_NAME}/archive RESTORE_USER='restoreuser' RESTORE_PW=$(pwgen 16 1) RESTORE_LOG='/tmp/restore_error.log' rm -f $RESTORE_LOG # This is for commands which require admin access MYSQL="mariadb \ --defaults-file=/etc/mysql/admin_user.cnf \ --connect-timeout 10" # This is for commands which we want the temporary "restore" user # to execute RESTORE_CMD="mariadb \ --user=${RESTORE_USER} \ --password=${RESTORE_PW} \ --host={{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} \ --port={{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} \ {{- if .Values.manifests.certificates }} --ssl-ca=/etc/mysql/certs/ca.crt \ --ssl-key=/etc/mysql/certs/tls.key \ --ssl-cert=/etc/mysql/certs/tls.crt \ {{- end }} --connect-timeout 10" # Get a single database data from the SQL file. # $1 - database name # $2 - sql file path current_db_desc() { PATTERN="-- Current Database:" sed -n "/${PATTERN} \`$1\`/,/${PATTERN}/p" $2 } #Return all database from an archive get_databases() { TMP_DIR=$1 DB_FILE=$2 if [[ -e ${TMP_DIR}/db.list ]] then DBS=$(cat ${TMP_DIR}/db.list | \ grep -ivE 'information_schema|performance_schema|mysql|sys' ) else DBS=" " fi echo $DBS > $DB_FILE } # Determine sql file from 2 options - current and legacy one # if current is not found check that there is no other namespaced dump file # before falling back to legacy one _get_sql_file() { TMP_DIR=$1 SQL_FILE="${TMP_DIR}/mariadb.${MARIADB_POD_NAMESPACE}.*.sql" LEGACY_SQL_FILE="${TMP_DIR}/mariadb.*.sql" INVALID_SQL_FILE="${TMP_DIR}/mariadb.*.*.sql" if [ -f ${SQL_FILE} ] then echo "Found $(ls ${SQL_FILE})" > /dev/stderr printf ${SQL_FILE} elif [ -f ${INVALID_SQL_FILE} ] then echo "Expected to find ${SQL_FILE} or ${LEGACY_SQL_FILE}, but found $(ls ${INVALID_SQL_FILE})" > /dev/stderr elif [ -f ${LEGACY_SQL_FILE} ] then echo "Falling back to legacy naming ${LEGACY_SQL_FILE}. Found $(ls ${LEGACY_SQL_FILE})" > /dev/stderr printf ${LEGACY_SQL_FILE} fi } # Extract all tables of a database from an archive and put them in the requested # file. get_tables() { DATABASE=$1 TMP_DIR=$2 TABLE_FILE=$3 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then current_db_desc ${DATABASE} ${SQL_FILE} \ | grep "^CREATE TABLE" | awk -F '`' '{print $2}' \ > $TABLE_FILE else # Error, cannot report the tables echo "No SQL file found - cannot extract the tables" return 1 fi } # Extract all rows in the given table of a database from an archive and put # them in the requested file. get_rows() { DATABASE=$1 TABLE=$2 TMP_DIR=$3 ROW_FILE=$4 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then current_db_desc ${DATABASE} ${SQL_FILE} \ | grep "INSERT INTO \`${TABLE}\` VALUES" > $ROW_FILE return 0 else # Error, cannot report the rows echo "No SQL file found - cannot extract the rows" return 1 fi } # Extract the schema for the given table in the given database belonging to # the archive file found in the TMP_DIR. get_schema() { DATABASE=$1 TABLE=$2 TMP_DIR=$3 SCHEMA_FILE=$4 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then DB_FILE=$(mktemp -p /tmp) current_db_desc ${DATABASE} ${SQL_FILE} > ${DB_FILE} sed -n /'CREATE TABLE `'$TABLE'`'/,/'--'/p ${DB_FILE} > ${SCHEMA_FILE} if [[ ! (-s ${SCHEMA_FILE}) ]]; then sed -n /'CREATE TABLE IF NOT EXISTS `'$TABLE'`'/,/'--'/p ${DB_FILE} \ > ${SCHEMA_FILE} fi rm -f ${DB_FILE} else # Error, cannot report the rows echo "No SQL file found - cannot extract the schema" return 1 fi } # Create temporary user for restoring specific databases. create_restore_user() { restore_db=$1 # Ensure any old restore user is removed first, if it exists. # If it doesn't exist it may return error, so do not exit the # script if that's the case. delete_restore_user "dont_exit_on_error" $MYSQL --execute="GRANT SELECT ON *.* TO ${RESTORE_USER}@'%' IDENTIFIED BY '${RESTORE_PW}';" 2>>$RESTORE_LOG if [[ "$?" -eq 0 ]] then $MYSQL --execute="GRANT ALL ON ${restore_db}.* TO ${RESTORE_USER}@'%' IDENTIFIED BY '${RESTORE_PW}';" 2>>$RESTORE_LOG if [[ "$?" -ne 0 ]] then cat $RESTORE_LOG echo "Failed to grant restore user ALL permissions on database ${restore_db}" return 1 fi else cat $RESTORE_LOG echo "Failed to grant restore user select permissions on all databases" return 1 fi } # Delete temporary restore user delete_restore_user() { error_handling=$1 $MYSQL --execute="DROP USER ${RESTORE_USER}@'%';" 2>>$RESTORE_LOG if [[ "$?" -ne 0 ]] then if [ "$error_handling" == "exit_on_error" ] then cat $RESTORE_LOG echo "Failed to delete temporary restore user - needs attention to avoid a security hole" return 1 fi fi } #Restore a single database restore_single_db() { SINGLE_DB_NAME=$1 TMP_DIR=$2 if [[ -z "$SINGLE_DB_NAME" ]] then echo "Restore single DB called but with wrong parameter." return 1 fi SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then # Restoring a single database requires us to create a temporary user # which has capability to only restore that ONE database. One gotcha # is that the mysql command to restore the database is going to throw # errors because of all the other databases that it cannot access. So # because of this reason, the --force option is used to prevent the # command from stopping on an error. create_restore_user $SINGLE_DB_NAME if [[ $? -ne 0 ]] then echo "Restore $SINGLE_DB_NAME failed create restore user." return 1 fi $RESTORE_CMD --force < $SQL_FILE 2>>$RESTORE_LOG if [[ "$?" -eq 0 ]] then echo "Database $SINGLE_DB_NAME Restore successful." else cat $RESTORE_LOG delete_restore_user "exit_on_error" echo "Database $SINGLE_DB_NAME Restore failed." return 1 fi delete_restore_user "exit_on_error" if [[ $? -ne 0 ]] then echo "Restore $SINGLE_DB_NAME failed delete restore user." return 1 fi if [ -f ${TMP_DIR}/${SINGLE_DB_NAME}_grant.sql ] then $MYSQL < ${TMP_DIR}/${SINGLE_DB_NAME}_grant.sql 2>>$RESTORE_LOG if [[ "$?" -eq 0 ]] then if ! $MYSQL --execute="FLUSH PRIVILEGES;"; then echo "Failed to flush privileges for $SINGLE_DB_NAME." return 1 fi echo "Database $SINGLE_DB_NAME Permission Restore successful." else cat $RESTORE_LOG echo "Database $SINGLE_DB_NAME Permission Restore failed." return 1 fi else echo "There is no permission file available for $SINGLE_DB_NAME" return 1 fi else echo "There is no database file available to restore from" return 1 fi return 0 } #Restore all the databases restore_all_dbs() { TMP_DIR=$1 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then # Check the scope of the archive. SCOPE=$(echo ${SQL_FILE} | awk -F'.' '{print $(NF-1)}') if [[ "${SCOPE}" != "all" ]]; then # This is just a single database backup. The user should # instead use the single database restore option. echo "Cannot use the restore all option for an archive containing only a single database." echo "Please use the single database restore option." return 1 fi $MYSQL < $SQL_FILE 2>$RESTORE_LOG if [[ "$?" -eq 0 ]] then echo "Databases $( echo $DBS | tr -d '\n') Restore successful." else cat $RESTORE_LOG echo "Databases $( echo $DBS | tr -d '\n') Restore failed." return 1 fi if [[ -f ${TMP_DIR}/grants.sql ]] then $MYSQL < ${TMP_DIR}/grants.sql 2>$RESTORE_LOG if [[ "$?" -eq 0 ]] then if ! $MYSQL --execute="FLUSH PRIVILEGES;"; then echo "Failed to flush privileges." return 1 fi echo "Databases Permission Restore successful." else cat $RESTORE_LOG echo "Databases Permission Restore failed." return 1 fi else echo "There is no permission file available" return 1 fi else echo "There is no database file available to restore from" return 1 fi return 0 } # Call the CLI interpreter, providing the archive directory path and the # user arguments passed in cli_main ${ARGS[@]} ================================================ FILE: mariadb/templates/bin/_start.py.tpl ================================================ #!/usr/bin/python3 {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} import errno import logging import os import secrets import select import signal import subprocess # nosec import socket import sys import tempfile import time import threading from datetime import datetime, timedelta import configparser import iso8601 import kubernetes.client import kubernetes.config # Create logger, console handler and formatter logger = logging.getLogger('OpenStack-Helm Mariadb') logger.setLevel(logging.INFO) ch = logging.StreamHandler() ch.setLevel(logging.INFO) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) # Get the local hostname local_hostname = socket.gethostname() logger.info("This instance hostname: {0}".format(local_hostname)) # Get local node IP address local_ip = socket.gethostbyname(local_hostname) logger.info("This instance IP address: {0}".format(local_ip)) # Get the instance number instance_number = local_hostname.split("-")[-1] logger.info("This instance number: {0}".format(instance_number)) # Setup k8s client credentials and check api version kubernetes.config.load_incluster_config() kubernetes_version = kubernetes.client.VersionApi().get_code().git_version logger.info("Kubernetes API Version: {0}".format(kubernetes_version)) k8s_api_instance = kubernetes.client.CoreV1Api() # Setup secrets generator secretsGen = secrets.SystemRandom() def check_env_var(env_var): """Check if an env var exists. Keyword arguments: env_var -- the env var to check for the existance of """ if env_var in os.environ: return True else: logger.critical("environment variable \"{0}\" not set".format(env_var)) sys.exit(1) # Set some variables from env vars injected into the container if check_env_var("STATE_CONFIGMAP"): state_configmap_name = os.environ['STATE_CONFIGMAP'] logger.info("Will use \"{0}\" configmap for cluster state info".format( state_configmap_name)) if check_env_var("POD_NAMESPACE"): pod_namespace = os.environ['POD_NAMESPACE'] if check_env_var("DIRECT_SVC_NAME"): direct_svc_name = os.environ['DIRECT_SVC_NAME'] if check_env_var("MARIADB_REPLICAS"): mariadb_replicas = os.environ['MARIADB_REPLICAS'] if check_env_var("POD_NAME_PREFIX"): pod_name_prefix = os.environ['POD_NAME_PREFIX'] if check_env_var("DISCOVERY_DOMAIN"): discovery_domain = os.environ['DISCOVERY_DOMAIN'] if check_env_var("WSREP_PORT"): wsrep_port = os.environ['WSREP_PORT'] if check_env_var("MYSQL_DBADMIN_USERNAME"): mysql_dbadmin_username = os.environ['MYSQL_DBADMIN_USERNAME'] if check_env_var("MYSQL_DBADMIN_PASSWORD"): mysql_dbadmin_password = os.environ['MYSQL_DBADMIN_PASSWORD'] if check_env_var("MYSQL_DBSST_USERNAME"): mysql_dbsst_username = os.environ['MYSQL_DBSST_USERNAME'] if check_env_var("MYSQL_DBSST_PASSWORD"): mysql_dbsst_password = os.environ['MYSQL_DBSST_PASSWORD'] if check_env_var("MYSQL_DBAUDIT_USERNAME"): mysql_dbaudit_username = os.environ['MYSQL_DBAUDIT_USERNAME'] else: mysql_dbaudit_username = '' if check_env_var("MYSQL_DBAUDIT_PASSWORD"): mysql_dbaudit_password = os.environ['MYSQL_DBAUDIT_PASSWORD'] mysql_x509 = os.getenv('MARIADB_X509', "") MYSQL_SSL_CMD_OPTS=["--ssl-verify-server-cert=false", "--ssl-ca=/etc/mysql/certs/ca.crt", "--ssl-key=/etc/mysql/certs/tls.key", "--ssl-cert=/etc/mysql/certs/tls.crt"] if mysql_dbadmin_username == mysql_dbsst_username: logger.critical( "The dbadmin username should not match the sst user username") sys.exit(1) # Set some variables for tuneables cluster_leader_ttl = int(os.environ['CLUSTER_LEADER_TTL']) state_configmap_update_period = 10 default_sleep = 20 # set one name for all commands, avoid "magic names" MYSQL_BINARY_NAME='mariadbd' def ensure_state_configmap(pod_namespace, configmap_name, configmap_body): """Ensure the state configmap exists. Keyword arguments: pod_namespace -- the namespace to house the configmap configmap_name -- the configmap name configmap_body -- the configmap body """ try: k8s_api_instance.read_namespaced_config_map( name=configmap_name, namespace=pod_namespace) return True except: k8s_api_instance.create_namespaced_config_map( namespace=pod_namespace, body=configmap_body) return False def run_cmd_with_logging(popenargs, logger, stdout_log_level=logging.INFO, stderr_log_level=logging.INFO, **kwargs): """Run subprocesses and stream output to logger.""" child = subprocess.Popen( # nosec popenargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) log_level = { child.stdout: stdout_log_level, child.stderr: stderr_log_level } def check_io(): ready_to_read = select.select([child.stdout, child.stderr], [], [], 1000)[0] for io in ready_to_read: line = io.readline().decode() logger.log(log_level[io], line[:-1]) while child.poll( ) is None: # keep checking stdout/stderr until the child exits check_io() check_io() # check again to catch anything after the process exits return child.wait() def wait_mysql_status(delay=30): logger.info("Start checking mariadb status") i = 0 res = 1 while True: logger.info("Checking mysql status {0}".format(i)) cmd = ['mariadb', "--defaults-file=/etc/mysql/admin_user.cnf", "--host=localhost"] if mysql_x509: cmd.extend(MYSQL_SSL_CMD_OPTS) cmd.extend(["--execute=status"]) res = run_cmd_with_logging(cmd, logger) if res == 0: logger.info("mariadb status check passed") break else: logger.info("mariadb status check failed") i += 1 time.sleep(delay) def stop_mysqld(): """Stop mysqld, assuming pid file in default location.""" logger.info("Shutting down any mysqld instance if required") mysqld_pidfile_path = "/var/lib/mysql/{0}.pid".format(local_hostname) def is_pid_running(pid): if os.path.isdir('/proc/{0}'.format(pid)): return True return False def is_pid_mysqld(pid): with open('/proc/{0}/comm'.format(pid), "r") as mysqld_pidfile: comm = mysqld_pidfile.readlines()[0].rstrip('\n') if comm.startswith(MYSQL_BINARY_NAME): return True else: return False if not os.path.isfile(mysqld_pidfile_path): logger.debug("No previous pid file found for mysqld") return if os.stat(mysqld_pidfile_path).st_size == 0: logger.info( "{0} file is empty, removing it".format(mysqld_pidfile_path)) os.remove(mysqld_pidfile_path) return logger.info( "Previous pid file found for mysqld, attempting to shut it down") with open(mysqld_pidfile_path, "r") as mysqld_pidfile: mysqld_pid = int(mysqld_pidfile.readlines()[0].rstrip('\n')) if not is_pid_running(mysqld_pid): logger.info( "Mysqld was not running with pid {0}, going to remove stale " "file".format(mysqld_pid)) os.remove(mysqld_pidfile_path) return if not is_pid_mysqld(mysqld_pid): logger.error( "pidfile process is not mysqld, removing pidfile and panic") os.remove(mysqld_pidfile_path) sys.exit(1) logger.info("pid from pidfile is mysqld") os.kill(mysqld_pid, 15) try: pid, status = os.waitpid(mysqld_pid, 0) except OSError as err: # The process has already exited if err.errno == errno.ECHILD: return else: raise logger.info("Mysqld stopped: pid = {0}, " "exit status = {1}".format(pid, status)) def mysqld_write_cluster_conf(mode='run'): """Write out dynamic cluster config. Keyword arguments: mode -- whether we are writing the cluster config for the cluster to 'run' or 'bootstrap' (default 'run') """ logger.info("Setting up cluster config") cluster_config = configparser.ConfigParser() cluster_config['mysqld'] = {} cluster_config_params = cluster_config['mysqld'] wsrep_cluster_members = [] for node in range(int(mariadb_replicas)): node_hostname = "{0}-{1}".format(pod_name_prefix, node) if local_hostname == node_hostname: cluster_config_params['wsrep_node_address'] = local_ip wsrep_node_name = "{0}.{1}".format(node_hostname, discovery_domain) cluster_config_params['wsrep_node_name'] = wsrep_node_name if mode == 'run': cluster_config_params['wsrep_cluster_address'] = "gcomm://{0}:{1}".format( discovery_domain, wsrep_port) else: cluster_config_params['wsrep_cluster_address'] = "gcomm://" cluster_config_file = '/etc/mysql/conf.d/10-cluster-config.cnf' logger.info( "Writing out cluster config to: {0}".format(cluster_config_file)) with open(cluster_config_file, 'w') as configfile: cluster_config.write(configfile) # Function to setup mysqld def mysqld_bootstrap(): """Bootstrap the db if no data found in the 'bootstrap_test_dir'""" logger.info("Boostrapping Mariadb") mysql_data_dir = '/var/lib/mysql' bootstrap_test_dir = "{0}/mysql".format(mysql_data_dir) if not os.path.isdir(bootstrap_test_dir): stop_mysqld() mysqld_write_cluster_conf(mode='bootstrap') run_cmd_with_logging([ 'mariadb-install-db', '--user=mysql', "--datadir={0}".format(mysql_data_dir) ], logger) if not mysql_dbaudit_username: template = ( # NOTE: since mariadb 10.4.13 definer of view # mysql.user is not root but mariadb.sys user # it is safe not to remove it because the account by default # is locked and cannot login "DELETE FROM mysql.user WHERE user != 'mariadb.sys' ;\n" # nosec "CREATE OR REPLACE USER '{0}'@'%' IDENTIFIED BY \'{1}\' ;\n" "GRANT ALL ON *.* TO '{0}'@'%' {4} WITH GRANT OPTION; \n" "DROP DATABASE IF EXISTS test ;\n" "CREATE OR REPLACE USER '{2}'@'127.0.0.1' IDENTIFIED BY '{3}';\n" "GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO '{2}'@'127.0.0.1';\n" "FLUSH PRIVILEGES ;\n" "SHUTDOWN ;".format(mysql_dbadmin_username, mysql_dbadmin_password, mysql_dbsst_username, mysql_dbsst_password, mysql_x509)) else: template = ( "DELETE FROM mysql.user WHERE user != 'mariadb.sys' ;\n" # nosec "CREATE OR REPLACE USER '{0}'@'%' IDENTIFIED BY \'{1}\' ;\n" "GRANT ALL ON *.* TO '{0}'@'%' {6} WITH GRANT OPTION;\n" "DROP DATABASE IF EXISTS test ;\n" "CREATE OR REPLACE USER '{2}'@'127.0.0.1' IDENTIFIED BY '{3}';\n" "GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO '{2}'@'127.0.0.1' ;\n" "CREATE OR REPLACE USER '{4}'@'%' IDENTIFIED BY '{5}';\n" "GRANT SELECT ON *.* TO '{4}'@'%' {6};\n" "FLUSH PRIVILEGES ;\n" "SHUTDOWN ;".format(mysql_dbadmin_username, mysql_dbadmin_password, mysql_dbsst_username, mysql_dbsst_password, mysql_dbaudit_username, mysql_dbaudit_password, mysql_x509)) bootstrap_sql_file = tempfile.NamedTemporaryFile(suffix='.sql').name with open(bootstrap_sql_file, 'w') as f: f.write(template) f.close() run_cmd_with_logging([ MYSQL_BINARY_NAME, '--user=mysql', '--bind-address=127.0.0.1', '--wsrep_cluster_address=gcomm://', "--init-file={0}".format(bootstrap_sql_file) ], logger) os.remove(bootstrap_sql_file) else: logger.info("Skipping bootstrap as {0} directory is present".format( bootstrap_test_dir)) def safe_update_configmap(configmap_dict, configmap_patch): """Update a configmap with locking. Keyword arguments: configmap_dict -- a dict representing the configmap to be patched configmap_patch -- a dict containign the patch """ logger.debug("Safe Patching configmap") # NOTE(portdirect): Explictly set the resource version we are patching to # ensure nothing else has modified the confimap since we read it. configmap_patch['metadata']['resourceVersion'] = configmap_dict[ 'metadata']['resource_version'] try: api_response = k8s_api_instance.patch_namespaced_config_map( name=state_configmap_name, namespace=pod_namespace, body=configmap_patch) return True except kubernetes.client.rest.ApiException as error: if error.status == 409: # This status code indicates a collision trying to write to the # config map while another instance is also trying the same. logger.warning("Collision writing configmap: {0}".format(error)) # This often happens when the replicas were started at the same # time, and tends to be persistent. Sleep with some random # jitter value briefly to break the synchronization. naptime = secretsGen.uniform(0.8,1.2) time.sleep(naptime) else: logger.error("Failed to set configmap: {0}".format(error)) return error def set_configmap_annotation(key, value): """Update a configmap's annotations via patching. Keyword arguments: key -- the key to be patched value -- the value to give the key """ logger.debug("Setting configmap annotation key={0} value={1}".format( key, value)) configmap_dict = k8s_api_instance.read_namespaced_config_map( name=state_configmap_name, namespace=pod_namespace).to_dict() configmap_patch = {'metadata': {'annotations': {}}} configmap_patch['metadata']['annotations'][key] = value return safe_update_configmap( configmap_dict=configmap_dict, configmap_patch=configmap_patch) def set_configmap_data(key, value): """Update a configmap's data via patching. Keyword arguments: key -- the key to be patched value -- the value to give the key """ logger.debug("Setting configmap data key={0} value={1}".format(key, value)) configmap_dict = k8s_api_instance.read_namespaced_config_map( name=state_configmap_name, namespace=pod_namespace).to_dict() configmap_patch = {'data': {}, 'metadata': {}} configmap_patch['data'][key] = value return safe_update_configmap( configmap_dict=configmap_dict, configmap_patch=configmap_patch) def get_configmap_value(key, type='data'): """Get a configmap's key's value. Keyword arguments: key -- the key to retrive the data from type -- the type of data to retrive from the configmap, can either be 'data' or an 'annotation'. (default data) """ state_configmap = k8s_api_instance.read_namespaced_config_map( name=state_configmap_name, namespace=pod_namespace) state_configmap_dict = state_configmap.to_dict() if type == 'data': state_configmap_data = state_configmap_dict['data'] elif type == 'annotation': state_configmap_data = state_configmap_dict['metadata']['annotations'] else: logger.error( "Unknown data type \"{0}\" reqested for retrival".format(type)) return False if state_configmap_data and key in state_configmap_data: return state_configmap_data[key] else: return None def get_cluster_state(): """Get the current cluster state from a configmap, creating the configmap if it does not already exist. """ logger.info("Getting cluster state") state = None while state is None: try: state = get_configmap_value( type='annotation', key='openstackhelm.openstack.org/cluster.state') logger.info( "The cluster is currently in \"{0}\" state.".format(state)) except: logger.info("The cluster configmap \"{0}\" does not exist.".format( state_configmap_name)) time.sleep(default_sleep) leader_expiry_raw = datetime.utcnow() + timedelta( seconds=cluster_leader_ttl) leader_expiry = "{0}Z".format(leader_expiry_raw.isoformat("T")) if check_for_active_nodes(): # NOTE(portdirect): here we make the assumption that the 1st pod # in an existing statefulset is the one to adopt as leader. leader = "{0}-0".format("-".join( local_hostname.split("-")[:-1])) state = "live" logger.info( "The cluster is running already though unmanaged \"{0}\" will be declared leader in a \"{1}\" state". format(leader, state)) else: leader = local_hostname state = "new" logger.info( "The cluster is new \"{0}\" will be declared leader in a \"{1}\" state". format(leader, state)) initial_configmap_body = { "apiVersion": "v1", "kind": "ConfigMap", "metadata": { "name": state_configmap_name, "annotations": { "openstackhelm.openstack.org/cluster.state": state, "openstackhelm.openstack.org/leader.node": leader, "openstackhelm.openstack.org/leader.expiry": leader_expiry, "openstackhelm.openstack.org/reboot.node": "" } }, "data": {} } ensure_state_configmap( pod_namespace=pod_namespace, configmap_name=state_configmap_name, configmap_body=initial_configmap_body) return state def declare_myself_cluster_leader(): """Declare the current pod as the cluster leader.""" logger.info("Declaring myself current cluster leader") leader_expiry_raw = datetime.utcnow() + timedelta( seconds=cluster_leader_ttl) leader_expiry = "{0}Z".format(leader_expiry_raw.isoformat("T")) set_configmap_annotation( key='openstackhelm.openstack.org/leader.node', value=local_hostname) set_configmap_annotation( key='openstackhelm.openstack.org/leader.expiry', value=leader_expiry) def deadmans_leader_election(): """Run a simplisic deadmans leader election.""" leader_node = get_configmap_value( type='annotation', key='openstackhelm.openstack.org/leader.node') leader_expiry = get_configmap_value( type='annotation', key='openstackhelm.openstack.org/leader.expiry') if iso8601.parse_date(leader_expiry).replace( tzinfo=None) < datetime.utcnow().replace(tzinfo=None): logger.info("Current cluster leader has expired") declare_myself_cluster_leader() elif local_hostname == leader_node: logger.info("Renewing cluster leader lease") declare_myself_cluster_leader() def get_grastate_val(key): """Extract data from grastate.dat. Keyword arguments: key -- the key to extract the value of """ logger.debug("Reading grastate.dat key={0}".format(key)) try: # This attempts to address a potential race condition with the initial # creation of the grastate.date file where the file would exist # however, it is not immediately populated. Testing indicated it could # take 15-20 seconds for the file to be populated. So loop and keep # checking up to 60 seconds. If it still isn't populated afterwards, # the IndexError will still occur as we are seeing now without the loop. time_end = time.time() + 60 while time.time() < time_end: with open("/var/lib/mysql/grastate.dat", "r") as myfile: grastate_raw = [s.strip() for s in myfile.readlines()] if grastate_raw: break time.sleep(1) return [i for i in grastate_raw if i.startswith("{0}:".format(key))][0].split(':')[1].strip() except IndexError: logger.error( "IndexError: Unable to find %s with ':' in grastate.dat", key) raise def set_grastate_val(key, value): """Set values in grastate.dat. Keyword arguments: key -- the key to set the value of value -- the value to set the key to """ logger.debug("Updating grastate.dat key={0} value={1}".format(key, value)) with open("/var/lib/mysql/grastate.dat", "r") as sources: lines = sources.readlines() for line_num, line_content in enumerate(lines): if line_content.startswith("{0}:".format(key)): line_content = "{0}: {1}\n".format(key, value) lines[line_num] = line_content with open("/var/lib/mysql/grastate.dat", "w") as sources: for line in lines: sources.write(line) def update_grastate_configmap(): """Update state configmap with grastate.dat info.""" while not os.path.exists('/var/lib/mysql/grastate.dat'): time.sleep(1) logger.info("Updating grastate configmap") grastate = dict() grastate['version'] = get_grastate_val(key='version') grastate['uuid'] = get_grastate_val(key='uuid') grastate['seqno'] = get_grastate_val(key='seqno') grastate['safe_to_bootstrap'] = get_grastate_val(key='safe_to_bootstrap') grastate['sample_time'] = "{0}Z".format(datetime.utcnow().isoformat("T")) for grastate_key, grastate_value in list(grastate.items()): configmap_key = "{0}.{1}".format(grastate_key, local_hostname) if get_configmap_value(type='data', key=configmap_key) != grastate_value: set_configmap_data(key=configmap_key, value=grastate_value) def update_grastate_on_restart(): """Update the grastate.dat on node restart.""" logger.info("Updating grastate info for node") if os.path.exists('/var/lib/mysql/grastate.dat'): if get_grastate_val(key='seqno') == '-1': logger.info( "Node shutdown was not clean, getting position via wsrep-recover" ) def recover_wsrep_position(): """Extract recovered wsrep position from uncleanly exited node.""" wsrep_recover = subprocess.Popen( # nosec [ MYSQL_BINARY_NAME, '--bind-address=127.0.0.1', '--wsrep_cluster_address=gcomm://', '--wsrep-recover' ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8") out, err = wsrep_recover.communicate() wsrep_rec_pos = None # NOTE: communicate() returns a tuple (stdout_data, stderr_data). # The data will be strings if streams were opened in text mode; # otherwise, bytes. If it is bytes, we should decode and get a # str for the err.split() to not error below. if isinstance(err, bytes): err = err.decode('utf-8') for item in err.split("\n"): logger.info("Recovering wsrep position: {0}".format(item)) if "WSREP: Recovered position:" in item: line = item.strip().split() wsrep_rec_pos = line[-1].split(':')[-1] if wsrep_rec_pos is None: logger.error("WSREP_REC_POS position could not be found.") raise Exception("WSREP_REC_POS position could not be found.") return wsrep_rec_pos set_grastate_val(key='seqno', value=recover_wsrep_position()) else: logger.info("Node shutdown was clean, using grastate.dat") update_grastate_configmap() else: logger.info("No grastate.dat exists I am a new node") def get_active_endpoints(endpoints_name=direct_svc_name, namespace=pod_namespace): """Returns a list of active endpoints. Keyword arguments: endpoints_name -- endpoints to check for active backends (default direct_svc_name) namespace -- namespace to check for endpoints (default pod_namespace) """ try: endpoints = k8s_api_instance.read_namespaced_endpoints( name=endpoints_name, namespace=pod_namespace) except kubernetes.client.rest.ApiException as error: logger.error("Failed to get mariadb service with error: {0}".format(error)) raise error endpoints_dict = endpoints.to_dict() active_endpoints = [] if endpoints_dict['subsets']: active_endpoints = [s['addresses'] for s in endpoints_dict['subsets'] if 'addresses' in s ][0] return active_endpoints def check_for_active_nodes(endpoints_name=direct_svc_name, namespace=pod_namespace): """Check K8s endpoints to see if there are active Mariadb Instances. Keyword arguments: endpoints_name -- endpoints to check for active backends (default direct_svc_name) namespace -- namespace to check for endpoints (default pod_namespace) """ logger.info("Checking for active nodes") active_endpoints = get_active_endpoints() if active_endpoints and len(active_endpoints) >= 1: logger.info("Amount of active endpoints: {0}".format(len(active_endpoints))) return True else: logger.info("Amount of active endpoints: 0") return False def check_if_cluster_data_is_fresh(): """Check if the state_configmap is both current and reasonably stable.""" logger.info("Checking to see if cluster data is fresh") state_configmap = k8s_api_instance.read_namespaced_config_map( name=state_configmap_name, namespace=pod_namespace) state_configmap_dict = state_configmap.to_dict() sample_times = dict() for key, value in list(state_configmap_dict['data'].items()): keyitems = key.split('.') key = keyitems[0] node = keyitems[1] if key == 'sample_time': sample_times[node] = value sample_time_ok = True for key, value in list(sample_times.items()): sample_time = iso8601.parse_date(value).replace(tzinfo=None) # NOTE(vsaienko): give some time on resolving configmap update conflicts sample_cutoff_time = datetime.utcnow().replace( tzinfo=None) - timedelta(seconds=5*state_configmap_update_period) if not sample_time >= sample_cutoff_time: logger.info( "The data we have from the cluster is too old to make a " "decision for node {0}".format(key)) sample_time_ok = False else: logger.info( "The data we have from the cluster is ok for node {0}".format( key)) return sample_time_ok def get_nodes_with_highest_seqno(): """Find out which node(s) has the highest sequence number and return them in an array.""" logger.info("Getting the node(s) with highest seqno from configmap.") # We can proceed only when we get seqno from all nodes, and if seqno is # -1 it means we didn't get it correctly, the shutdown was not clean and we need # to wait for a value taken by wsrep recover. while True: state_configmap = k8s_api_instance.read_namespaced_config_map( name=state_configmap_name, namespace=pod_namespace) state_configmap_dict = state_configmap.to_dict() seqnos = dict() for key, value in list(state_configmap_dict['data'].items()): keyitems = key.split('.') key = keyitems[0] node = keyitems[1] if key == 'seqno': #Explicit casting to integer to have resulting list of integers for correct comparison seqnos[node] = int(value) max_seqno = max(seqnos.values()) max_seqno_nodes = sorted([k for k, v in list(seqnos.items()) if v == max_seqno]) if [x for x in seqnos.values() if x < 0 ]: logger.info("Thq seqno for some nodes is < 0, can't make a decision about leader. Node seqnums: %s", seqnos) time.sleep(state_configmap_update_period) continue return max_seqno_nodes def resolve_leader_node(nodename_array): """From the given nodename array, determine which node is the leader by choosing the node which has a hostname with the lowest number at the end of it. If by chance there are two nodes with the same number then the first one encountered will be chosen.""" logger.info("Returning the node with the lowest hostname") lowest = sys.maxsize leader = nodename_array[0] for nodename in nodename_array: nodenum = int(nodename[nodename.rindex('-') + 1:]) logger.info("Nodename %s has nodenum %d", nodename, nodenum) if nodenum < lowest: lowest = nodenum leader = nodename logger.info("Resolved leader is %s", leader) return leader def check_if_i_lead(): """Check on full restart of cluster if this node should lead the cluster reformation.""" logger.info("Checking to see if I lead the cluster for reboot") # as we sample on the update period - we sample for a full cluster # leader election period as a simplistic way of ensureing nodes are # reliably checking in following full restart of cluster. count = cluster_leader_ttl / state_configmap_update_period counter = 0 while counter < count: if check_if_cluster_data_is_fresh(): counter += 1 else: counter = 0 time.sleep(state_configmap_update_period) logger.info( "Cluster info has been uptodate {0} times out of the required " "{1}".format(counter, count)) max_seqno_nodes = get_nodes_with_highest_seqno() leader_node = resolve_leader_node(max_seqno_nodes) if (local_hostname == leader_node and not check_for_active_nodes() and get_cluster_state() == 'live'): logger.info("I lead the cluster. Setting cluster state to reboot.") set_configmap_annotation( key='openstackhelm.openstack.org/cluster.state', value='reboot') set_configmap_annotation( key='openstackhelm.openstack.org/reboot.node', value=local_hostname) return True elif local_hostname == leader_node: logger.info("The cluster is already rebooting") return False else: logger.info("{0} leads the cluster".format(leader_node)) return False def monitor_cluster(stop_event): """Function to kick off grastate configmap updating thread""" while True: if stop_event.is_set(): logger.info("Stopped monitor_cluster thread") break try: update_grastate_configmap() except Exception as error: logger.error("Error updating grastate configmap: {0}".format(error)) time.sleep(state_configmap_update_period) # Stop event stop_event = threading.Event() # Setup the thread for the cluster monitor monitor_cluster_thread = threading.Thread(target=monitor_cluster, args=(stop_event,)) monitor_cluster_thread.daemon = True def launch_cluster_monitor(): """Launch grastate configmap updating thread""" if not monitor_cluster_thread.is_alive(): monitor_cluster_thread.start() def leader_election(stop_event): """Function to kick off leader election thread""" while True: if stop_event.is_set(): logger.info("Stopped leader_election thread") break try: deadmans_leader_election() except Exception as error: logger.error("Error electing leader: {0}".format(error)) time.sleep(cluster_leader_ttl / 2) # Setup the thread for the leader election leader_election_thread = threading.Thread(target=leader_election, args=(stop_event,)) leader_election_thread.daemon = True def launch_leader_election(): """Launch leader election thread""" if not leader_election_thread.is_alive(): leader_election_thread.start() def run_mysqld(cluster='existing'): """Launch the mysqld instance for the pod. This will also run mysql upgrade if we are the 1st replica, and the rest of the cluster is already running. This senario will be triggerd either following a rolling update, as this works in reverse order for statefulset. Or restart of the 1st instance, in which case the comand should be a no-op. Keyword arguments: cluster -- whether we going to form a cluster 'new' or joining an existing cluster 'existing' (default 'existing') """ stop_mysqld() mysqld_write_cluster_conf(mode='run') launch_leader_election() launch_cluster_monitor() mysqld_cmd = [MYSQL_BINARY_NAME, '--user=mysql'] if cluster == 'new': mysqld_cmd.append('--wsrep-new-cluster') mysql_data_dir = '/var/lib/mysql' db_test_dir = "{0}/mysql".format(mysql_data_dir) if os.path.isdir(db_test_dir): logger.info("Setting the admin passwords to the current value and upgrade mysql if needed") if not mysql_dbaudit_username: template = ( "CREATE OR REPLACE USER '{0}'@'%' IDENTIFIED BY \'{1}\' ;\n" "GRANT ALL ON *.* TO '{0}'@'%' {4} WITH GRANT OPTION ;\n" "CREATE OR REPLACE USER '{2}'@'127.0.0.1' IDENTIFIED BY '{3}' ;\n" "GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO '{2}'@'127.0.0.1' ;\n" "FLUSH PRIVILEGES ;".format(mysql_dbadmin_username, mysql_dbadmin_password, mysql_dbsst_username, mysql_dbsst_password, mysql_x509)) else: template = ( "CREATE OR REPLACE USER '{0}'@'%' IDENTIFIED BY \'{1}\' ;\n" "GRANT ALL ON *.* TO '{0}'@'%' {6} WITH GRANT OPTION ;\n" "CREATE OR REPLACE USER '{2}'@'127.0.0.1' IDENTIFIED BY '{3}' ;\n" "GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO '{2}'@'127.0.0.1' ;\n" "CREATE OR REPLACE USER '{4}'@'%' IDENTIFIED BY '{5}' ;\n" "GRANT SELECT ON *.* TO '{4}'@'%' {6};\n" "FLUSH PRIVILEGES ;".format(mysql_dbadmin_username, mysql_dbadmin_password, mysql_dbsst_username, mysql_dbsst_password, mysql_dbaudit_username, mysql_dbaudit_password, mysql_x509)) bootstrap_sql_file = tempfile.NamedTemporaryFile(suffix='.sql').name with open(bootstrap_sql_file, 'w') as f: f.write(template) f.close() run_cmd_with_logging_thread = threading.Thread(target=run_cmd_with_logging, args=([ MYSQL_BINARY_NAME, '--bind-address=127.0.0.1', '--wsrep-on=false', "--init-file={0}".format(bootstrap_sql_file) ], logger)) run_cmd_with_logging_thread.start() wait_mysql_status() logger.info("Upgrading local mysql instance") upgrade_cmd=['mariadb-upgrade', '--skip-write-binlog', "--user={0}".format(mysql_dbadmin_username), "--password={0}".format(mysql_dbadmin_password)] if mysql_x509: upgrade_cmd.extend(MYSQL_SSL_CMD_OPTS) upgrade_res = run_cmd_with_logging(upgrade_cmd, logger) if upgrade_res != 0: raise Exception('Mysql upgrade failed, cannot proceed') stop_mysqld() os.remove(bootstrap_sql_file) else: logger.info( "This is a fresh node joining the cluster for the 1st time, not attempting to set admin passwords or upgrading" ) logger.info("Launching MariaDB") run_cmd_with_logging(mysqld_cmd, logger) def mysqld_reboot(): """Reboot a mysqld cluster.""" declare_myself_cluster_leader() set_grastate_val(key='safe_to_bootstrap', value='1') run_mysqld(cluster='new') def sigterm_shutdown(x, y): """Shutdown the instance of mysqld on shutdown signal.""" logger.info("Got a sigterm from the container runtime, time to go.") stop_event.set() stop_mysqld() monitor_cluster_thread.join() leader_election_thread.join() sys.exit(0) # Register the signal to the handler signal.signal(signal.SIGTERM, sigterm_shutdown) # Main logic loop if get_cluster_state() == 'new': leader_node = get_configmap_value( type='annotation', key='openstackhelm.openstack.org/leader.node') if leader_node == local_hostname: set_configmap_annotation( key='openstackhelm.openstack.org/cluster.state', value='init') declare_myself_cluster_leader() launch_leader_election() mysqld_bootstrap() update_grastate_configmap() set_configmap_annotation( key='openstackhelm.openstack.org/cluster.state', value='live') run_mysqld(cluster='new') else: logger.info("Waiting for cluster to start running") while not get_cluster_state() == 'live': time.sleep(default_sleep) while not check_for_active_nodes(): time.sleep(default_sleep) launch_leader_election() run_mysqld() elif get_cluster_state() == 'init': logger.info("Waiting for cluster to start running") while not get_cluster_state() == 'live': time.sleep(default_sleep) while not check_for_active_nodes(): time.sleep(default_sleep) launch_leader_election() run_mysqld() elif get_cluster_state() == 'live': logger.info("Cluster has been running starting restore/rejoin") if not int(mariadb_replicas) > 1: logger.info( "There is only a single node in this cluster, we are good to go") update_grastate_on_restart() mysqld_reboot() else: if check_for_active_nodes(): logger.info( "There are currently running nodes in the cluster, we can " "join them") run_mysqld() else: logger.info("This cluster has lost all running nodes, we need to " "determine the new lead node") update_grastate_on_restart() launch_leader_election() launch_cluster_monitor() if check_if_i_lead(): logger.info("I won the ability to reboot the cluster") mysqld_reboot() else: logger.info( "Waiting for the lead node to come online before joining " "it") while not check_for_active_nodes(): time.sleep(default_sleep) set_configmap_annotation( key='openstackhelm.openstack.org/cluster.state', value='live') set_configmap_annotation( key='openstackhelm.openstack.org/reboot.node', value='') run_mysqld() elif get_cluster_state() == 'reboot': reboot_node = get_configmap_value( type='annotation', key='openstackhelm.openstack.org/reboot.node') if reboot_node == local_hostname: logger.info( "Cluster reboot procedure wasn`t finished. Trying again.") update_grastate_on_restart() launch_leader_election() launch_cluster_monitor() mysqld_reboot() else: logger.info( "Waiting for the lead node to come online before joining " "it") update_grastate_on_restart() launch_leader_election() launch_cluster_monitor() while not check_for_active_nodes(): time.sleep(default_sleep) set_configmap_annotation( key='openstackhelm.openstack.org/cluster.state', value='live') run_mysqld() else: logger.critical("Dont understand cluster state, exiting with error status") sys.exit(1) ================================================ FILE: mariadb/templates/bin/_start_mariadb_verify_server.sh.tpl ================================================ #!/bin/bash -ex # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. log () { msg_default="Need some text to log" level_default="INFO" component_default="Mariadb Backup Verifier" msg=${1:-$msg_default} level=${2:-$level_default} component=${3:-"$component_default"} echo "$(date +'%Y-%m-%d %H:%M:%S,%3N') - ${component} - ${level} - ${msg}" } log "Starting Mariadb server for backup verification..." mariadb-install-db --user=nobody --ldata=/var/lib/mysql >/dev/null 2>&1 MYSQL_ALLOW_EMPTY_PASSWORD=1 mariadbd --user=nobody --verbose >/dev/null 2>&1 ================================================ FILE: mariadb/templates/bin/_test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex rm -f /tmp/test-success mariadb-slap \ --defaults-file=/etc/mysql/test-params.cnf \ {{ include "helm-toolkit.utils.joinListWithSpace" $.Values.conf.tests.params }} -vv \ --post-system="touch /tmp/test-success" if ! [ -f /tmp/test-success ]; then exit 1 fi ================================================ FILE: mariadb/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "oslo_db" "type" "default" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: mariadb/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{ if eq .Values.endpoints.oslo_db.auth.admin.username .Values.endpoints.oslo_db.auth.sst.username }} {{ fail "the DB admin username should not match the sst user username" }} {{ end }} --- apiVersion: v1 kind: ConfigMap metadata: name: mariadb-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} health.sh: | {{ tuple "bin/_health.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} start.py: | {{ tuple "bin/_start.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} test.sh: | {{ tuple "bin/_test.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- if .Values.conf.backup.enabled }} backup_mariadb.sh: | {{ tuple "bin/_backup_mariadb.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} start_verification_server.sh: | {{ tuple "bin/_start_mariadb_verify_server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} restore_mariadb.sh: | {{ tuple "bin/_restore_mariadb.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} backup_main.sh: | {{ include "helm-toolkit.scripts.db-backup-restore.backup_main" . | indent 4 }} restore_main.sh: | {{ include "helm-toolkit.scripts.db-backup-restore.restore_main" . | indent 4 }} {{- end }} {{- if .Values.manifests.job_ks_user }} ks-user.sh: | {{ include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- end }} {{- if .Values.manifests.deployment_controller }} mariadb_controller.py: | {{ tuple "bin/_mariadb_controller.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} mariadb-wait-for-cluster.py: | {{ tuple "bin/_mariadb-wait-for-cluster.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: mariadb/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License" ); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: mariadb-etc data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "my" ) "key" "my.cnf" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "00_base" ) "key" "00-base.cnf" ) | indent 2 }} {{- if $envAll.Values.conf.database.config_override }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "config_override" ) "key" "20-override.cnf" ) | indent 2 }} {{- end }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "99_force" ) "key" "99-force.cnf" ) | indent 2 }} {{- end }} ================================================ FILE: mariadb/templates/configmap-services-tcp.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_services_tcp }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: mariadb-services-tcp data: {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }}: "{{ .Release.Namespace }}/{{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}:{{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" {{- end }} ================================================ FILE: mariadb/templates/cron-job-backup-mariadb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_mariadb_backup }} {{- $envAll := . }} {{- $serviceAccountName := "mariadb-backup" }} {{- $failoverUserClass := .Values.conf.backup.remote_backup.failover_user_class }} {{ tuple $envAll "mariadb_backup" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: mariadb-backup annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "mariadb-backup" "backup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: schedule: {{ .Values.jobs.mariadb_backup.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.mariadb_backup.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.mariadb_backup.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "mariadb-backup" "backup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "mariadb-backup" "containerNames" (list "init" "backup-perms" "mariadb-backup") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{- if .Values.jobs.mariadb_backup.backoffLimit }} backoffLimit: {{ .Values.jobs.mariadb_backup.backoffLimit }} {{- end }} {{- if .Values.jobs.mariadb_backup.activeDeadlineSeconds }} activeDeadlineSeconds: {{ .Values.jobs.mariadb_backup.activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll "mariadb-backup" "backup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ dict "envAll" $envAll "application" "mariadb_backup" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure shareProcessNamespace: true {{- if $envAll.Values.pod.tolerations.mariadb.enabled }} {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{- end }} {{- if $envAll.Values.pod.affinity }} {{- if $envAll.Values.pod.affinity.mariadb_backup }} affinity: {{ index $envAll.Values.pod.affinity "mariadb_backup" | toYaml | indent 12}} {{- end }} {{- end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "mariadb_backup" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} - name: backup-perms {{ tuple $envAll "mariadb_backup" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.mariadb_backup | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "mariadb_backup" "container" "backup_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - chown - -R - "65534:65534" - $(MARIADB_BACKUP_BASE_DIR) env: - name: MARIADB_BACKUP_BASE_DIR value: {{ .Values.conf.backup.base_path | quote }} volumeMounts: - mountPath: /tmp name: pod-tmp - mountPath: {{ .Values.conf.backup.base_path }} name: mariadb-backup-dir - name: verify-perms {{ tuple $envAll "mariadb_backup" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.mariadb_backup | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "mariadb_backup" "container" "verify_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - chown - -R - "65534:65534" - /var/lib/mysql volumeMounts: - mountPath: /tmp name: pod-tmp - mountPath: /var/lib/mysql name: mysql-data containers: - name: mariadb-backup command: - /bin/sh args: - -c - >- ( /tmp/start_verification_server.sh ) & /tmp/backup_mariadb.sh env: - name: MARIADB_BACKUP_BASE_DIR value: {{ .Values.conf.backup.base_path | quote }} - name: MYSQL_BACKUP_MYSQLDUMP_OPTIONS value: {{ .Values.conf.backup.mysqldump_options | quote }} - name: MARIADB_LOCAL_BACKUP_DAYS_TO_KEEP value: {{ .Values.conf.backup.days_to_keep | quote }} - name: MARIADB_POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: REMOTE_BACKUP_ENABLED value: "{{ .Values.conf.backup.remote_backup.enabled }}" {{- if .Values.conf.backup.remote_backup.enabled }} - name: MARIADB_REMOTE_BACKUP_DAYS_TO_KEEP value: {{ .Values.conf.backup.remote_backup.days_to_keep | quote }} - name: CONTAINER_NAME value: {{ .Values.conf.backup.remote_backup.container_name | quote }} - name: STORAGE_POLICY value: "{{ .Values.conf.backup.remote_backup.storage_policy }}" - name: NUMBER_OF_RETRIES_SEND_BACKUP_TO_REMOTE value: {{ .Values.conf.backup.remote_backup.number_of_retries | quote }} - name: MIN_DELAY_SEND_BACKUP_TO_REMOTE value: {{ .Values.conf.backup.remote_backup.delay_range.min | quote }} - name: MAX_DELAY_SEND_BACKUP_TO_REMOTE value: {{ .Values.conf.backup.remote_backup.delay_range.max | quote }} - name: THROTTLE_BACKUPS_ENABLED value: "{{ .Values.conf.backup.remote_backup.throttle_backups.enabled }}" - name: THROTTLE_LIMIT value: {{ .Values.conf.backup.remote_backup.throttle_backups.sessions_limit | quote }} - name: THROTTLE_LOCK_EXPIRE_AFTER value: {{ .Values.conf.backup.remote_backup.throttle_backups.lock_expire_after | quote }} - name: THROTTLE_RETRY_AFTER value: {{ .Values.conf.backup.remote_backup.throttle_backups.retry_after | quote }} - name: THROTTLE_CONTAINER_NAME value: {{ .Values.conf.backup.remote_backup.throttle_backups.container_name | quote }} {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.mariadb }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 16 }} {{- $failoverIdentityClass := index $envAll.Values.endpoints.identity.auth $failoverUserClass }} {{- if $failoverIdentityClass }} {{- include "helm-toolkit.snippets.keystone_openrc_failover_env_vars" $env | indent 16 }} {{- end }} {{- end }} {{- end }} {{ tuple $envAll "mariadb_backup" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.mariadb_backup | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "mariadb_backup" "container" "mariadb_backup" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} volumeMounts: - name: pod-tmp mountPath: /tmp - mountPath: /tmp/backup_mariadb.sh name: mariadb-bin readOnly: true subPath: backup_mariadb.sh - mountPath: /tmp/backup_main.sh name: mariadb-bin readOnly: true subPath: backup_main.sh - mountPath: {{ .Values.conf.backup.base_path }} name: mariadb-backup-dir - name: mariadb-secrets mountPath: /etc/mysql/admin_user.cnf subPath: admin_user.cnf readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} - name: mariadb-bin mountPath: /tmp/start_verification_server.sh readOnly: true subPath: start_verification_server.sh - name: mysql-data mountPath: /var/lib/mysql - name: var-run mountPath: /run/mysqld volumes: - name: pod-tmp emptyDir: {} - name: mycnfd emptyDir: {} - name: var-run emptyDir: {} - name: mariadb-etc configMap: name: mariadb-etc defaultMode: 0444 - name: mysql-data emptyDir: {} - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 420 - configMap: defaultMode: 365 name: mariadb-bin name: mariadb-bin {{- if and .Values.volume.backup.enabled .Values.manifests.pvc_backup }} - name: mariadb-backup-dir persistentVolumeClaim: claimName: mariadb-backup-data {{- else }} - hostPath: path: {{ .Values.conf.backup.base_path }} type: DirectoryOrCreate name: mariadb-backup-dir {{- end }} {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- end }} ================================================ FILE: mariadb/templates/deployment-controller.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_controller }} {{- $envAll := . }} {{- $serviceAccountName := "mariadb-controller" }} {{ tuple $envAll "controller" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $envAll.Release.Name }}-{{ $serviceAccountName }}-pod namespace: {{ $envAll.Release.Namespace }} rules: - apiGroups: - "" resources: - pods verbs: - get - list - apiGroups: - "" resources: - services verbs: - update - patch - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $envAll.Release.Name }}-{{ $serviceAccountName }}-pod namespace: {{ $envAll.Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $envAll.Release.Name }}-{{ $serviceAccountName }}-pod subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: apps/v1 kind: Deployment metadata: name: mariadb-controller annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "mariadb" "controller" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.controller }} selector: matchLabels: {{ tuple $envAll "mariadb" "controller" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "mariadb" "controller" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "controller" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "mariadb" "controller" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.mariadb.enabled }} {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.controller.node_selector_key }}: {{ .Values.labels.controller.node_selector_value }} initContainers: {{ tuple $envAll "controller" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: controller {{ tuple $envAll "mariadb_controller" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "controller" "container" "controller" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.controller | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/mariadb_controller.py env: {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.mariadb_controller | indent 12 }} - name: MARIADB_CONTROLLER_PODS_NAMESPACE value: {{ $envAll.Release.Namespace }} - name: MARIADB_MASTER_SERVICE_NAME value: {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - mountPath: /tmp/mariadb_controller.py name: mariadb-bin readOnly: true subPath: mariadb_controller.py volumes: - name: pod-tmp emptyDir: {} - name: mariadb-bin configMap: name: mariadb-bin defaultMode: 365 {{- end }} ================================================ FILE: mariadb/templates/exporter-configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.configmap_bin .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: mysql-exporter-bin data: create-mysql-user.sh: | {{ tuple "bin/_prometheus-create-mysql-user.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mysqld-exporter.sh: | {{ tuple "bin/_prometheus-mysqld-exporter.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: mariadb/templates/exporter-job-create-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.job_user_create .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "mariadb-exporter-create-sql-user" }} {{ tuple $envAll "prometheus_create_mysql_user" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: mariadb-exporter-create-sql-user labels: {{ tuple $envAll "prometheus-mysql-exporter" "create-sql-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: backoffLimit: {{ .Values.jobs.exporter_create_sql_user.backoffLimit }} template: metadata: labels: {{ tuple $envAll "prometheus-mysql-exporter" "create-sql-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "create-sql-user" "containerNames" (list "init" "exporter-create-sql-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "prometheus_create_mysql_user" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} activeDeadlineSeconds: {{ .Values.jobs.exporter_create_sql_user.activeDeadlineSeconds }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.prometheus_mysql_exporter.node_selector_key }}: {{ .Values.labels.prometheus_mysql_exporter.node_selector_value }} initContainers: {{ tuple $envAll "prometheus_create_mysql_user" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: exporter-create-sql-user {{ tuple $envAll "prometheus_create_mysql_user" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "prometheus_create_mysql_user" "container" "main" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.prometheus_create_mysql_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/create-mysql-user.sh env: - name: EXPORTER_USER valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_USER - name: EXPORTER_PASSWORD valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_PASSWORD {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: mysql-exporter-bin mountPath: /tmp/create-mysql-user.sh subPath: create-mysql-user.sh readOnly: true - name: mariadb-secrets mountPath: /etc/mysql/admin_user.cnf subPath: admin_user.cnf readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: mysql-exporter-bin configMap: name: mysql-exporter-bin defaultMode: 0555 - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: mariadb/templates/exporter-secrets-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.secret_etc .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $exporter_user := .Values.endpoints.oslo_db.auth.exporter.username }} {{- $exporter_password := .Values.endpoints.oslo_db.auth.exporter.password }} {{- $db_host := "localhost" }} {{- $data_source_name := printf "%s:%s@(%s)/" $exporter_user $exporter_password $db_host }} --- apiVersion: v1 kind: Secret metadata: name: mysql-exporter-secrets type: Opaque data: DATA_SOURCE_NAME: {{ $data_source_name | b64enc }} EXPORTER_USER: {{ .Values.endpoints.oslo_db.auth.exporter.username | b64enc }} EXPORTER_PASSWORD: {{ .Values.endpoints.oslo_db.auth.exporter.password | b64enc }} mysql_user.cnf: {{ tuple "secrets/_prometheus-exporter_user.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} {{- end }} ================================================ FILE: mariadb/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: mariadb/templates/job-cluster-wait.yaml ================================================ {{/* Copyright 2019 Mirantis inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_cluster_wait }} {{- $envAll := . }} {{- $serviceAccountName := print .Release.Name "-cluster-wait" }} {{ tuple $envAll "cluster_wait" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $envAll.Release.Name }}-{{ $serviceAccountName }}-pod namespace: {{ $envAll.Release.Namespace }} rules: - apiGroups: - "" resources: - configmaps verbs: - update - patch - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $envAll.Release.Name }}-{{ $serviceAccountName }}-pod namespace: {{ $envAll.Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $envAll.Release.Name }}-{{ $serviceAccountName }}-pod subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: "{{.Release.Name}}-cluster-wait" labels: {{ tuple $envAll "mariadb" "cluster-wait" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: backoffLimit: {{ .Values.jobs.cluster_wait.clusterCheckRetries }} template: metadata: labels: {{ tuple $envAll "mariadb" "cluster-wait" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "cluster_wait" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "cluster_wait" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: {{.Release.Name}}-mariadb-cluster-wait {{ tuple $envAll "mariadb_scripted_test" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "cluster_wait" "container" "mariadb_cluster_wait" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: MARIADB_HOST value: {{ tuple "oslo_db" "internal" $envAll | include "helm-toolkit.endpoints.endpoint_host_lookup" }} - name: MARIADB_REPLICAS value: {{ .Values.pod.replicas.server | quote }} - name: MARIADB_CLUSTER_CHECK_WAIT value: {{ .Values.jobs.cluster_wait.clusterCheckWait | quote }} - name: MARIADB_CLUSTER_STABILITY_COUNT value: {{ .Values.jobs.cluster_wait.clusterStabilityCount | quote }} - name: MARIADB_CLUSTER_STABILITY_WAIT value: {{ .Values.jobs.cluster_wait.clusterStabilityWait | quote }} - name: MARIADB_CLUSTER_STATE_CONFIGMAP value: {{ printf "%s-%s" .Release.Name "mariadb-state" | quote }} - name: MARIADB_CLUSTER_STATE_CONFIGMAP_NAMESPACE value: {{ $envAll.Release.Namespace }} - name: MARIADB_PASSWORD valueFrom: secretKeyRef: name: mariadb-dbadmin-password key: MYSQL_DBADMIN_PASSWORD command: - /tmp/mariadb-wait-for-cluster.py volumeMounts: - name: pod-tmp mountPath: /tmp - name: mariadb-bin mountPath: /tmp/mariadb-wait-for-cluster.py subPath: mariadb-wait-for-cluster.py readOnly: true - name: mariadb-secrets mountPath: /etc/mysql/admin_user.cnf subPath: admin_user.cnf readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: mariadb-bin configMap: name: mariadb-bin defaultMode: 0555 - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 0444 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: mariadb/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "mariadb" -}} {{- if .Values.pod.tolerations.mariadb.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: mariadb/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user }} {{- $backoffLimit := .Values.jobs.ks_user.backoffLimit }} {{- $activeDeadlineSeconds := .Values.jobs.ks_user.activeDeadlineSeconds }} {{- $ksUserJob := dict "envAll" . "serviceName" "mariadb" "configMapBin" "mariadb-bin" "backoffLimit" $backoffLimit "activeDeadlineSeconds" $activeDeadlineSeconds -}} {{- if .Values.pod.tolerations.mariadb.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: mariadb/templates/mariadb-backup-pvc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.volume.backup.enabled .Values.manifests.pvc_backup }} --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: mariadb-backup-data spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: {{ .Values.volume.backup.size }} storageClassName: {{ .Values.volume.backup.class_name }} {{- end }} ================================================ FILE: mariadb/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "mariadb" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: mariadb/templates/pdb-mariadb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_server }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: mariadb-server spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.mariadb.min_available }} selector: matchLabels: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: mariadb/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $dependencies := .Values.dependencies.static.tests }} {{- $serviceAccountName := print .deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.deployment_name}}-test" labels: {{ tuple $envAll "mariadb" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "mariadb-test" "containerNames" (list "init" "mariadb-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "tests" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} {{ if $envAll.Values.pod.tolerations.mariadb.enabled }} {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: mariadb-test {{ dict "envAll" $envAll "application" "tests" "container" "test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} command: - /tmp/test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: mariadb-bin mountPath: /tmp/test.sh subPath: test.sh readOnly: true - name: mariadb-secrets mountPath: /etc/mysql/test-params.cnf {{ if eq $envAll.Values.conf.tests.endpoint "internal" }} subPath: admin_user_internal.cnf {{ else if eq $envAll.Values.conf.tests.endpoint "direct" }} subPath: admin_user.cnf {{ else }} {{ fail "Either 'direct' or 'internal' should be specified for .Values.conf.tests.endpoint" }} {{ end }} readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} volumes: - name: pod-tmp emptyDir: {} - name: mariadb-bin configMap: name: mariadb-bin defaultMode: 0555 - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} ================================================ FILE: mariadb/templates/secret-backup-restore.yaml ================================================ {{/* This manifest results a secret being created which has the key information needed for backing up and restoring the Mariadb databases. */}} {{- if and .Values.conf.backup.enabled .Values.manifests.secret_backup_restore }} {{- $envAll := . }} {{- $userClass := "backup_restore" }} {{- $secretName := index $envAll.Values.secrets.mariadb $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: BACKUP_ENABLED: {{ $envAll.Values.conf.backup.enabled | quote | b64enc }} BACKUP_BASE_PATH: {{ $envAll.Values.conf.backup.base_path | b64enc }} LOCAL_DAYS_TO_KEEP: {{ $envAll.Values.conf.backup.days_to_keep | quote | b64enc }} MYSQLDUMP_OPTIONS: {{ $envAll.Values.conf.backup.mysqldump_options | b64enc }} REMOTE_BACKUP_ENABLED: {{ $envAll.Values.conf.backup.remote_backup.enabled | quote | b64enc }} REMOTE_BACKUP_CONTAINER: {{ $envAll.Values.conf.backup.remote_backup.container_name | b64enc }} REMOTE_BACKUP_DAYS_TO_KEEP: {{ $envAll.Values.conf.backup.remote_backup.days_to_keep | quote | b64enc }} REMOTE_BACKUP_STORAGE_POLICY: {{ $envAll.Values.conf.backup.remote_backup.storage_policy | b64enc }} REMOTE_BACKUP_RETRIES: {{ $envAll.Values.conf.backup.remote_backup.number_of_retries | quote | b64enc }} REMOTE_BACKUP_SEND_DELAY_MIN: {{ $envAll.Values.conf.backup.remote_backup.delay_range.min | quote | b64enc }} REMOTE_BACKUP_SEND_DELAY_MAX: {{ $envAll.Values.conf.backup.remote_backup.delay_range.max | quote | b64enc }} THROTTLE_BACKUPS_ENABLED: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.enabled | quote | b64enc }} THROTTLE_LIMIT: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.sessions_limit | quote | b64enc }} THROTTLE_LOCK_EXPIRE_AFTER: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.lock_expire_after | quote | b64enc }} THROTTLE_RETRY_AFTER: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.retry_after | quote | b64enc }} THROTTLE_CONTAINER_NAME: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.container_name | quote | b64enc }} ... {{- end }} ================================================ FILE: mariadb/templates/secret-dbadmin-password.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_dbadmin_password }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-dbadmin-password type: Opaque data: MYSQL_DBADMIN_PASSWORD: {{ .Values.endpoints.oslo_db.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: mariadb/templates/secret-dbaudit-password.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_dbaudit_password }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-dbaudit-password type: Opaque data: MYSQL_DBAUDIT_PASSWORD: {{ .Values.endpoints.oslo_db.auth.audit.password | b64enc }} {{- end }} ================================================ FILE: mariadb/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: mariadb/templates/secret-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. This manifest results in two secrets being created: 1) Keystone "mariadb" secret, which is needed to access the cluster (remote or same cluster) for storing mariadb backups. If the cluster is remote, the auth_url would be non-null. 2) Keystone "admin" secret, which is needed to create the "mariadb" keystone account mentioned above. This may not be needed if the account is in a remote cluster (auth_url is non-null in that case). */}} {{- if .Values.conf.backup.remote_backup.enabled }} {{- $envAll := . }} {{- $userClass := .Values.conf.backup.remote_backup.primary_user_class }} {{- $failoverUserClass := .Values.conf.backup.remote_backup.failover_user_class }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- $identityClass := index .Values.endpoints.identity.auth $userClass }} {{- if $identityClass.auth_url }} OS_AUTH_URL: {{ $identityClass.auth_url | b64enc }} {{- else }} OS_AUTH_URL: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} {{- end }} OS_REGION_NAME: {{ $identityClass.region_name | b64enc }} OS_INTERFACE: {{ $identityClass.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME: {{ $identityClass.project_domain_name | b64enc }} OS_PROJECT_NAME: {{ $identityClass.project_name | b64enc }} OS_USER_DOMAIN_NAME: {{ $identityClass.user_domain_name | b64enc }} OS_USERNAME: {{ $identityClass.username | b64enc }} OS_PASSWORD: {{ $identityClass.password | b64enc }} OS_DEFAULT_DOMAIN: {{ $identityClass.default_domain_id | default "default" | b64enc }} {{- $failoverIdentityClass := index .Values.endpoints.identity.auth $failoverUserClass }} {{- if $failoverIdentityClass }} {{- if $failoverIdentityClass.auth_url }} OS_AUTH_URL_FAILOVER: {{ $failoverIdentityClass.auth_url | b64enc }} {{- else }} OS_AUTH_URL_FAILOVER: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} {{- end }} OS_REGION_NAME_FAILOVER: {{ $failoverIdentityClass.region_name | b64enc }} OS_INTERFACE_FAILOVER: {{ $failoverIdentityClass.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME_FAILOVER: {{ $failoverIdentityClass.project_domain_name | b64enc }} OS_PROJECT_NAME_FAILOVER: {{ $failoverIdentityClass.project_name | b64enc }} OS_USER_DOMAIN_NAME_FAILOVER: {{ $failoverIdentityClass.user_domain_name | b64enc }} OS_USERNAME_FAILOVER: {{ $failoverIdentityClass.username | b64enc }} OS_PASSWORD_FAILOVER: {{ $failoverIdentityClass.password | b64enc }} OS_DEFAULT_DOMAIN_FAILOVER: {{ $failoverIdentityClass.default_domain_id | default "default" | b64enc }} {{- end }} ... {{- if .Values.manifests.job_ks_user }} {{- $userClass := "admin" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- $identityClass := index .Values.endpoints.identity.auth $userClass }} {{- if $identityClass.auth_url }} OS_AUTH_URL: {{ $identityClass.auth_url | b64enc }} {{- else }} OS_AUTH_URL: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} {{- end }} OS_REGION_NAME: {{ $identityClass.region_name | b64enc }} OS_INTERFACE: {{ $identityClass.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME: {{ $identityClass.project_domain_name | b64enc }} OS_PROJECT_NAME: {{ $identityClass.project_name | b64enc }} OS_USER_DOMAIN_NAME: {{ $identityClass.user_domain_name | b64enc }} OS_USERNAME: {{ $identityClass.username | b64enc }} OS_PASSWORD: {{ $identityClass.password | b64enc }} OS_DEFAULT_DOMAIN: {{ $identityClass.default_domain_id | default "default" | b64enc }} ... {{- end }} {{- end }} ================================================ FILE: mariadb/templates/secret-sst-password.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_sst_password }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-dbsst-password type: Opaque data: MYSQL_DBSST_PASSWORD: {{ .Values.endpoints.oslo_db.auth.sst.password | b64enc }} {{- end }} ================================================ FILE: mariadb/templates/secrets/_admin_user.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.admin.username }} password = {{ .Values.endpoints.oslo_db.auth.admin.password }} host = {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} port = {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: mariadb/templates/secrets/_admin_user_internal.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.admin.username }} password = {{ .Values.endpoints.oslo_db.auth.admin.password }} host = {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} port = {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: mariadb/templates/secrets/_prometheus-exporter_user.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.exporter.username }} password = {{ .Values.endpoints.oslo_db.auth.exporter.password }} host = localhost port = {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: mariadb/templates/secrets-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-secrets type: Opaque data: admin_user.cnf: {{ tuple "secrets/_admin_user.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} admin_user_internal.cnf: {{ tuple "secrets/_admin_user_internal.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} {{- end }} ================================================ FILE: mariadb/templates/service-discovery.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_discovery }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "oslo_db" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: mysql port: {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: wsrep port: {{ tuple "oslo_db" "direct" "wsrep" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: ist port: {{ tuple "oslo_db" "direct" "ist" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: sst port: {{ tuple "oslo_db" "direct" "sst" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} clusterIP: None publishNotReadyAddresses: false selector: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ .Values.network.mariadb_discovery | include "helm-toolkit.snippets.service_params" | indent 2 }} {{- end }} ================================================ FILE: mariadb/templates/service-master.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_master }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: mysql port: {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ .Values.network.mariadb_master | include "helm-toolkit.snippets.service_params" | indent 2 }} {{- end }} ================================================ FILE: mariadb/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: mysql port: {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ .Values.network.mariadb | include "helm-toolkit.snippets.service_params" | indent 2 }} {{- end }} ================================================ FILE: mariadb/templates/statefulset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "mariadbReadinessProbe" }} exec: command: - /tmp/health.sh - -t - readiness - -d - {{ .Values.pod.probes.server.mariadb.readiness.disk_usage_percent | quote }} {{- end }} {{- define "mariadbLivenessProbe" }} exec: command: - /tmp/health.sh - -t - liveness {{- end }} {{- define "exporterProbeTemplate" }} httpGet: path: /metrics port: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.statefulset }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .deployment_name "mariadb" }} {{ tuple $envAll "mariadb" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} rules: - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resourceNames: - {{ printf "%s-%s" .deployment_name "mariadb-state" | quote }} resources: - configmaps verbs: - get - patch - apiGroups: - "" resourceNames: - {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} resources: - endpoints verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: apps/v1 kind: StatefulSet metadata: # NOTE(portdirect): the statefulset name must match the POD_NAME_PREFIX env var for discovery to work name: {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} mariadb-dbadmin-password-hash: {{ tuple "secret-dbadmin-password.yaml" . | include "helm-toolkit.utils.hash" }} mariadb-sst-password-hash: {{ tuple "secret-dbadmin-password.yaml" . | include "helm-toolkit.utils.hash" }} configmap-bin-exporter-hash: {{ tuple "exporter-configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} secrets-etc-exporter-hash: {{ tuple "exporter-secrets-etc.yaml" . | include "helm-toolkit.utils.hash" }} labels: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: "{{ tuple "oslo_db" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}" podManagementPolicy: "Parallel" replicas: {{ .Values.pod.replicas.server }} selector: matchLabels: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} mariadb-dbadmin-password-hash: {{ tuple "secret-dbadmin-password.yaml" . | include "helm-toolkit.utils.hash" }} mariadb-sst-password-hash: {{ tuple "secret-dbadmin-password.yaml" . | include "helm-toolkit.utils.hash" }} secrets-etc-exporter-hash: {{ tuple "exporter-secrets-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "mariadb-server" "containerNames" (list "init" "mariadb-perms" "mariadb") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "server" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.mariadb.enabled }} {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.server.timeout }} nodeSelector: {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value }} initContainers: {{ tuple $envAll "mariadb" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if .Values.volume.chown_on_start }} - name: mariadb-perms {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: ["/bin/sh", "-c"] args: - set -xe; /bin/chown -R "mysql:mysql" /var/lib/mysql; /bin/chmod 700 /var/lib/mysql; volumeMounts: - name: pod-tmp mountPath: /tmp - name: mysql-data mountPath: /var/lib/mysql {{- end }} containers: - name: mariadb {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "mariadb" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} - name: MARIADB_REPLICAS value: {{ .Values.pod.replicas.server | quote }} - name: POD_NAME_PREFIX value: {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: DISCOVERY_DOMAIN value: {{ tuple "oslo_db" "discovery" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} - name: DIRECT_SVC_NAME value: {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: WSREP_PORT value: {{ tuple "oslo_db" "direct" "wsrep" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: STATE_CONFIGMAP value: {{ printf "%s-%s" .deployment_name "mariadb-state" | quote }} - name: MYSQL_DBADMIN_USERNAME value: {{ .Values.endpoints.oslo_db.auth.admin.username }} - name: MYSQL_DBADMIN_PASSWORD valueFrom: secretKeyRef: name: mariadb-dbadmin-password key: MYSQL_DBADMIN_PASSWORD - name: MYSQL_DBSST_USERNAME value: {{ .Values.endpoints.oslo_db.auth.sst.username }} - name: MYSQL_DBSST_PASSWORD valueFrom: secretKeyRef: name: mariadb-dbsst-password key: MYSQL_DBSST_PASSWORD {{- if .Values.manifests.secret_dbaudit_password }} - name: MYSQL_DBAUDIT_USERNAME value: {{ .Values.endpoints.oslo_db.auth.audit.username }} - name: MYSQL_DBAUDIT_PASSWORD valueFrom: secretKeyRef: name: mariadb-dbaudit-password key: MYSQL_DBAUDIT_PASSWORD {{- end }} - name: MYSQL_HISTFILE value: {{ .Values.conf.database.mysql_histfile }} - name: CLUSTER_LEADER_TTL value: {{ .Values.conf.galera.cluster_leader_ttl | quote }} ports: - name: mysql protocol: TCP containerPort: {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: wsrep protocol: TCP containerPort: {{ tuple "oslo_db" "direct" "wsrep" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: ist protocol: TCP containerPort: {{ tuple "oslo_db" "direct" "ist" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: sst protocol: TCP containerPort: {{ tuple "oslo_db" "direct" "sst" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} command: - /tmp/start.py {{ dict "envAll" . "component" "server" "container" "mariadb" "type" "readiness" "probeTemplate" (include "mariadbReadinessProbe" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "server" "container" "mariadb" "type" "liveness" "probeTemplate" (include "mariadbLivenessProbe" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: var-run mountPath: /var/run/mysqld - name: mycnfd mountPath: /etc/mysql/conf.d - name: mariadb-bin mountPath: /tmp/start.py subPath: start.py readOnly: true - name: mariadb-bin mountPath: /tmp/stop.sh subPath: stop.sh readOnly: true - name: mariadb-bin mountPath: /tmp/health.sh subPath: health.sh readOnly: true - name: mariadb-etc mountPath: /etc/mysql/my.cnf subPath: my.cnf readOnly: true - name: mariadb-etc mountPath: /etc/mysql/conf.d/00-base.cnf subPath: 00-base.cnf readOnly: true {{- if .Values.conf.database.config_override }} - name: mariadb-etc mountPath: /etc/mysql/conf.d/20-override.cnf subPath: 20-override.cnf readOnly: true {{- end }} - name: mariadb-etc mountPath: /etc/mysql/conf.d/99-force.cnf subPath: 99-force.cnf readOnly: true - name: mariadb-secrets mountPath: /etc/mysql/admin_user.cnf subPath: admin_user.cnf readOnly: true - name: mysql-data mountPath: /var/lib/mysql {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- if .Values.monitoring.prometheus.enabled }} - name: mysql-exporter {{ tuple $envAll "prometheus_mysql_exporter" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus_mysql_exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" . "component" "server" "container" "mariadb_exporter" "type" "readiness" "probeTemplate" (include "exporterProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "server" "container" "mariadb_exporter" "type" "liveness" "probeTemplate" (include "exporterProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/mysqld-exporter.sh ports: - name: metrics containerPort: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: EXPORTER_USER valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_USER - name: EXPORTER_PASSWORD valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_PASSWORD - name: DATA_SOURCE_NAME valueFrom: secretKeyRef: name: mysql-exporter-secrets key: DATA_SOURCE_NAME - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: LISTEN_PORT value: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: TELEMETRY_PATH value: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" | quote }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: mysql-exporter-secrets mountPath: /etc/mysql/mysql_user.cnf subPath: mysql_user.cnf readOnly: true - name: mysql-exporter-bin mountPath: /tmp/mysqld-exporter.sh subPath: mysqld-exporter.sh readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: mycnfd emptyDir: {} - name: var-run emptyDir: {} - name: mariadb-bin configMap: name: mariadb-bin defaultMode: 0555 - name: mariadb-etc configMap: name: mariadb-etc defaultMode: 0444 - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- if not .Values.volume.enabled }} - name: mysql-data {{- if .Values.volume.use_local_path_for_single_pod_cluster.enabled }} hostPath: path: {{ .Values.volume.use_local_path_for_single_pod_cluster.host_path }} type: DirectoryOrCreate {{- else }} emptyDir: {} {{- end }} {{- end }} {{- if .Values.monitoring.prometheus.enabled }} - name: mysql-exporter-secrets secret: secretName: mysql-exporter-secrets defaultMode: 0444 - name: mysql-exporter-bin configMap: name: mysql-exporter-bin defaultMode: 0555 {{- end }} {{- if .Values.volume.enabled }} volumeClaimTemplates: - metadata: name: mysql-data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: {{ .Values.volume.size }} {{- if ne .Values.volume.class_name "default" }} storageClassName: {{ .Values.volume.class_name }} {{- end }} {{- end }} {{- end }} ================================================ FILE: mariadb/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for mariadb. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null images: tags: mariadb: quay.io/airshipit/mariadb:latest-ubuntu_noble prometheus_create_mysql_user: quay.io/airshipit/mariadb:11.4.8-noble prometheus_mysql_exporter: docker.io/prom/mysqld-exporter:v0.12.1 prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 mariadb_backup: quay.io/airshipit/porthole-mysqlclient-utility:latest-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble scripted_test: quay.io/airshipit/mariadb:latest-ubuntu_noble mariadb_controller: quay.io/airshipit/mariadb:latest-ubuntu_noble pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled prometheus_mysql_exporter: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled controller: node_selector_key: openstack-control-plane node_selector_value: enabled pod: env: mariadb_controller: MARIADB_CONTROLLER_DEBUG: 0 MARIADB_CONTROLLER_CHECK_PODS_DELAY: 10 MARIADB_CONTROLLER_PYKUBE_REQUEST_TIMEOUT: 60 probes: server: mariadb: readiness: enabled: true disk_usage_percent: 99 params: initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 15 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 30 timeoutSeconds: 15 mariadb_exporter: readiness: enabled: true params: initialDelaySeconds: 5 periodSeconds: 60 timeoutSeconds: 10 liveness: enabled: true params: initialDelaySeconds: 15 periodSeconds: 60 timeoutSeconds: 10 security_context: server: pod: runAsUser: 999 container: perms: runAsUser: 0 readOnlyRootFilesystem: true mariadb: runAsUser: 999 allowPrivilegeEscalation: false readOnlyRootFilesystem: true prometheus_mysql_exporter: pod: runAsUser: 99 container: exporter: runAsUser: 99 allowPrivilegeEscalation: false readOnlyRootFilesystem: true prometheus_create_mysql_user: pod: runAsUser: 0 container: main: allowPrivilegeEscalation: false readOnlyRootFilesystem: true mariadb_backup: pod: runAsUser: 65534 container: backup_perms: runAsUser: 0 readOnlyRootFilesystem: true verify_perms: runAsUser: 0 readOnlyRootFilesystem: true mariadb_backup: runAsUser: 65534 readOnlyRootFilesystem: true allowPrivilegeEscalation: false tests: pod: runAsUser: 999 container: test: runAsUser: 999 readOnlyRootFilesystem: true controller: pod: runAsUser: 65534 container: controller: allowPrivilegeEscalation: false readOnlyRootFilesystem: true cluster_wait: pod: runAsUser: 65534 runAsNonRoot: true container: mariadb_cluster_wait: allowPrivilegeEscalation: false capabilities: drop: - ALL affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: mariadb: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule replicas: server: 3 controller: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: server: timeout: 600 disruption_budget: mariadb: min_available: 0 resources: enabled: false server: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: tests: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" prometheus_create_mysql_user: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" mariadb_backup: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - mariadb-image-repo-sync services: - endpoint: node service: local_image_registry static: mariadb_backup: jobs: - mariadb-ks-user services: - endpoint: internal service: oslo_db prometheus_create_mysql_user: services: - endpoint: internal service: oslo_db image_repo_sync: services: - endpoint: internal service: local_image_registry tests: services: - endpoint: internal service: oslo_db controller: services: null cluster_wait: services: - endpoint: internal service: oslo_db volume: # this value is used for single pod deployments of mariadb to prevent losing all data # if the pod is restarted use_local_path_for_single_pod_cluster: enabled: false host_path: "/tmp/mysql-data" chown_on_start: true enabled: true class_name: general size: 5Gi backup: enabled: true class_name: general size: 5Gi jobs: cluster_wait: clusterCheckWait: 30 clusterCheckRetries: 30 clusterStabilityCount: 30 clusterStabilityWait: 4 exporter_create_sql_user: backoffLimit: 87600 activeDeadlineSeconds: 3600 mariadb_backup: # activeDeadlineSeconds == 0 means no deadline activeDeadlineSeconds: 0 backoffLimit: 6 cron: "0 0 * * *" history: success: 3 failed: 1 ks_user: # activeDeadlineSeconds == 0 means no deadline activeDeadlineSeconds: 0 backoffLimit: 6 conf: tests: # This may either be: # * direct: which will hit the backends directly via a k8s service ip # Note, deadlocks and failure are to be expected with concurrency if # hitting the `direct` endpoint. endpoint: internal # This is a list of tuning params passed to mysqlslap: params: - --auto-generate-sql - --concurrency=100 - --number-of-queries=1000 - --number-char-cols=1 - --number-int-cols=1 mariadb_server: setup_wait: iteration: 30 duration: 5 backup: enabled: false base_path: /var/backup validateData: ageOffset: 120 mysqldump_options: > --single-transaction --quick --add-drop-database --add-drop-table --add-locks --databases days_to_keep: 3 remote_backup: enabled: false container_name: mariadb days_to_keep: 14 storage_policy: default-placement number_of_retries: 5 delay_range: min: 30 max: 60 throttle_backups: enabled: false sessions_limit: 480 lock_expire_after: 7200 retry_after: 3600 container_name: throttle-backups-manager primary_user_class: mariadb failover_user_class: mariadb_failover galera: cluster_leader_ttl: 60 database: mysql_histfile: "/dev/null" my: | [mysqld] datadir=/var/lib/mysql basedir=/usr ignore-db-dirs=lost+found [client-server] !includedir /etc/mysql/conf.d/ 00_base: | [mysqld] # Charset character_set_server=utf8 collation_server=utf8_general_ci skip-character-set-client-handshake # Logging slow_query_log=off slow_query_log_file=/var/log/mysql/mariadb-slow.log log_warnings=2 # General logging has huge performance penalty therefore is disabled by default general_log=off general_log_file=/var/log/mysql/mariadb-error.log long_query_time=3 log_queries_not_using_indexes=on # Networking bind_address=0.0.0.0 port={{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} # When a client connects, the server will perform hostname resolution, # and when DNS is slow, establishing the connection will become slow as well. # It is therefore recommended to start the server with skip-name-resolve to # disable all DNS lookups. The only limitation is that the GRANT statements # must then use IP addresses only. skip_name_resolve # Tuning user=mysql max_allowed_packet=256M open_files_limit=10240 max_connections=8192 max-connect-errors=1000000 # General security settings # Reference: https://dev.mysql.com/doc/mysql-security-excerpt/8.0/en/general-security-issues.html # secure_file_priv is set to '/home' because it is read-only, which will # disable this feature completely. secure_file_priv=/home local_infile=0 symbolic_links=0 sql_mode="STRICT_ALL_TABLES,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" ## Generally, it is unwise to set the query cache to be larger than 64-128M ## as the costs associated with maintaining the cache outweigh the performance ## gains. ## The query cache is a well known bottleneck that can be seen even when ## concurrency is moderate. The best option is to disable it from day 1 ## by setting query_cache_size=0 (now the default on MySQL 5.6) ## and to use other ways to speed up read queries: good indexing, adding ## replicas to spread the read load or using an external cache. query_cache_size=0 query_cache_type=0 sync_binlog=0 thread_cache_size=16 table_open_cache=2048 table_definition_cache=1024 # # InnoDB # # The buffer pool is where data and indexes are cached: having it as large as possible # will ensure you use memory and not disks for most read operations. # Typical values are 50..75% of available RAM. # TODO(tomasz.paszkowski): This needs to by dynamic based on available RAM. innodb_buffer_pool_size=1024M innodb_doublewrite=0 innodb_file_format=Barracuda innodb_file_per_table=1 innodb_flush_method=O_DIRECT innodb_io_capacity=500 innodb_locks_unsafe_for_binlog=1 innodb_log_file_size=128M innodb_old_blocks_time=1000 innodb_read_io_threads=8 innodb_write_io_threads=8 # Clustering binlog_format=ROW default-storage-engine=InnoDB innodb_autoinc_lock_mode=2 innodb_flush_log_at_trx_commit=2 wsrep_cluster_name={{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" | replace "." "_" }} wsrep_on=1 wsrep_provider=/usr/lib/galera/libgalera_smm.so wsrep_provider_options="evs.suspect_timeout=PT30S; gmcast.peer_timeout=PT15S; gmcast.listen_addr=tcp://0.0.0.0:{{ tuple "oslo_db" "direct" "wsrep" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" wsrep_slave_threads=12 wsrep_sst_auth={{ .Values.endpoints.oslo_db.auth.sst.username }}:{{ .Values.endpoints.oslo_db.auth.sst.password }} wsrep_sst_method=mariabackup {{ if .Values.manifests.certificates }} # TLS ssl_ca=/etc/mysql/certs/ca.crt ssl_key=/etc/mysql/certs/tls.key ssl_cert=/etc/mysql/certs/tls.crt # tls_version = TLSv1.2,TLSv1.3 {{ end }} [mysqldump] max-allowed-packet=16M [client] default_character_set=utf8 protocol=tcp port={{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.manifests.certificates }} # TLS ssl_ca=/etc/mysql/certs/ca.crt ssl_key=/etc/mysql/certs/tls.key ssl_cert=/etc/mysql/certs/tls.crt # tls_version = TLSv1.2,TLSv1.3 ssl-verify-server-cert {{ end }} config_override: null # Any configuration here will override the base config. # config_override: |- # [mysqld] # wsrep_slave_threads=1 99_force: | [mysqld] datadir=/var/lib/mysql tmpdir=/tmp monitoring: prometheus: enabled: false mysqld_exporter: scrape: true secrets: identity: admin: keystone-admin-user mariadb: mariadb-backup-user mariadb: backup_restore: mariadb-backup-restore oci_image_registry: mariadb: mariadb-oci-image-registry-key tls: oslo_db: server: public: mariadb-tls-server internal: mariadb-tls-direct # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false mariadb: username: mariadb password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null monitoring: name: prometheus namespace: null hosts: default: prom-metrics public: prometheus host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9090 public: 80 prometheus_mysql_exporter: namespace: null hosts: default: mysql-exporter host_fqdn_override: default: null path: default: /metrics scheme: default: 'http' port: metrics: default: 9104 oslo_db: namespace: null auth: admin: username: root password: password sst: username: sst password: password audit: username: audit password: password exporter: username: exporter password: password hosts: default: mariadb direct: mariadb-server discovery: mariadb-discovery host_fqdn_override: default: null path: null scheme: mysql+pymysql port: mysql: default: 3306 wsrep: default: 4567 ist: default: 4568 sst: default: 4444 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns_tcp: default: 53 dns: default: 53 protocol: UDP identity: name: backup-storage-auth namespace: openstack auth: admin: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default mariadb: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null role: admin region_name: RegionOne username: mariadb-backup-user password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 network: mariadb: {} mariadb_discovery: {} mariadb_master: {} network_policy: mariadb: ingress: - {} egress: - {} prometheus-mysql-exporter: ingress: - {} egress: - {} manifests: certificates: false configmap_bin: true configmap_etc: true configmap_services_tcp: true job_image_repo_sync: true cron_job_mariadb_backup: false job_ks_user: false pvc_backup: false monitoring: prometheus: configmap_bin: true job_user_create: true secret_etc: true pdb_server: true network_policy: false pod_test: true secret_dbadmin_password: true secret_sst_password: true secret_dbaudit_password: true secret_backup_restore: false secret_etc: true secret_registry: true service_discovery: true service_error: false service: true statefulset: true deployment_controller: true service_master: true job_cluster_wait: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: mariadb-backup/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v10.6.14 description: OpenStack-Helm MariaDB backups name: mariadb-backup version: 2025.2.0 home: https://mariadb.com/kb/en/ icon: http://badges.mariadb.org/mariadb-badge-180x60.png sources: - https://github.com/MariaDB/server - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: mariadb-backup/README.rst ================================================ openstack-helm/mariadb-backup ====================== By default, this chart creates a mariadb-backup cronjob that runs in a schedule in order to create mysql backups. This chart depends on mariadb-cluster chart. The backups are stored in a PVC and also are possible to upload then to a remote RGW container. You must ensure that your control nodes that should receive mariadb instances are labeled with ``openstack-control-plane=enabled``, or whatever you have configured in values.yaml for the label configuration: :: kubectl label nodes openstack-control-plane=enabled --all ================================================ FILE: mariadb-backup/templates/bin/_backup_mariadb.sh.tpl ================================================ #!/bin/bash SCOPE=${1:-"all"} # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. source /tmp/backup_main.sh # Export the variables required by the framework # Note: REMOTE_BACKUP_ENABLED, STORAGE_POLICY and CONTAINER_NAME are already # exported. export DB_NAMESPACE=${MARIADB_POD_NAMESPACE} export DB_NAME="mariadb" export LOCAL_DAYS_TO_KEEP=${MARIADB_LOCAL_BACKUP_DAYS_TO_KEEP} export REMOTE_DAYS_TO_KEEP=${MARIADB_REMOTE_BACKUP_DAYS_TO_KEEP} export REMOTE_BACKUP_RETRIES=${NUMBER_OF_RETRIES_SEND_BACKUP_TO_REMOTE} export MIN_DELAY_SEND_REMOTE=${MIN_DELAY_SEND_BACKUP_TO_REMOTE} export MAX_DELAY_SEND_REMOTE=${MAX_DELAY_SEND_BACKUP_TO_REMOTE} export ARCHIVE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${DB_NAMESPACE}/${DB_NAME}/archive # Dump all the database files to existing $TMP_DIR and save logs to $LOG_FILE dump_databases_to_directory() { TMP_DIR=$1 LOG_FILE=$2 SCOPE=${3:-"all"} MYSQL="mariadb \ --defaults-file=/etc/mysql/admin_user.cnf \ --connect-timeout 10" MYSQLDUMP="mariadb-dump \ --defaults-file=/etc/mysql/admin_user.cnf" if [[ "${SCOPE}" == "all" ]]; then MYSQL_DBNAMES=( $($MYSQL --silent --skip-column-names -e \ "show databases;" | \ grep -ivE 'information_schema|performance_schema|mysql|sys') ) else if [[ "${SCOPE}" != "information_schema" && "${SCOPE}" != "performance_schema" && "${SCOPE}" != "mysql" && "${SCOPE}" != "sys" ]]; then MYSQL_DBNAMES=( ${SCOPE} ) else log ERROR "It is not allowed to backup database ${SCOPE}." return 1 fi fi #check if there is a database to backup, otherwise exit if [[ -z "${MYSQL_DBNAMES// }" ]] then log INFO "There is no database to backup" return 0 fi #Create a list of Databases printf "%s\n" "${MYSQL_DBNAMES[@]}" > $TMP_DIR/db.list if [[ "${SCOPE}" == "all" ]]; then #Retrieve and create the GRANT file for all the users {{- if .Values.manifests.certificates }} SSL_DSN=";mysql_ssl=1" SSL_DSN="$SSL_DSN;mysql_ssl_client_key=/etc/mysql/certs/tls.key" SSL_DSN="$SSL_DSN;mysql_ssl_client_cert=/etc/mysql/certs/tls.crt" SSL_DSN="$SSL_DSN;mysql_ssl_ca_file=/etc/mysql/certs/ca.crt" if ! pt-show-grants --defaults-file=/etc/mysql/admin_user.cnf $SSL_DSN \ {{- else }} if ! pt-show-grants --defaults-file=/etc/mysql/admin_user.cnf \ {{- end }} 2>>"$LOG_FILE" > "$TMP_DIR"/grants.sql; then log ERROR "Failed to create GRANT for all the users" return 1 fi fi #Retrieve and create the GRANT files per DB for db in "${MYSQL_DBNAMES[@]}" do echo $($MYSQL --skip-column-names -e "select concat('show grants for ',user,';') \ from mysql.db where ucase(db)=ucase('$db');") | \ sed -r "s/show grants for ([a-zA-Z0-9_-]*)/show grants for '\1'/g" | \ $MYSQL --silent --skip-column-names 2>>$LOG_FILE > $TMP_DIR/${db}_grant.sql if [ "$?" -eq 0 ] then sed -i 's/$/;/' $TMP_DIR/${db}_grant.sql else log ERROR "Failed to create GRANT files for ${db}" return 1 fi done #Dumping the database SQL_FILE=mariadb.$MARIADB_POD_NAMESPACE.${SCOPE} $MYSQLDUMP $MYSQL_BACKUP_MYSQLDUMP_OPTIONS "${MYSQL_DBNAMES[@]}" \ > $TMP_DIR/${SQL_FILE}.sql 2>>$LOG_FILE if [[ $? -eq 0 && -s $TMP_DIR/${SQL_FILE}.sql ]] then log INFO "Database(s) dumped successfully. (SCOPE = ${SCOPE})" return 0 else log ERROR "Backup failed and need attention. (SCOPE = ${SCOPE})" return 1 fi } # functions from mariadb-verifier chart get_time_delta_secs () { second_delta=0 input_date_second=$( date --date="$1" +%s ) if [ -n "$input_date_second" ]; then current_date=$( date +"%Y-%m-%dT%H:%M:%SZ" ) current_date_second=$( date --date="$current_date" +%s ) ((second_delta=current_date_second-input_date_second)) if [ "$second_delta" -lt 0 ]; then second_delta=0 fi fi echo $second_delta } check_data_freshness () { archive_file=$(basename "$1") archive_date=$(echo "$archive_file" | cut -d'.' -f 4) SCOPE=$2 if [[ "${SCOPE}" != "all" ]]; then log "Data freshness check is skipped for individual database." return 0 fi log "Checking for data freshness in the backups..." # Get some idea of which database.table has changed in the last 30m # Excluding the system DBs and aqua_test_database # changed_tables=$(${MYSQL_LIVE} -e "select TABLE_SCHEMA,TABLE_NAME from \ information_schema.tables where UPDATE_TIME >= SUBTIME(now(),'00:30:00') AND TABLE_SCHEMA \ NOT IN('information_schema', 'mysql', 'performance_schema', 'sys', 'aqua_test_database');" | \ awk '{print $1 "." $2}') if [ -n "${changed_tables}" ]; then delta_secs=$(get_time_delta_secs "$archive_date") age_offset={{ .Values.conf.backup.validateData.ageOffset }} ((age_threshold=delta_secs+age_offset)) data_freshness=false skipped_freshness=false for table in ${changed_tables}; do tab_schema=$(echo "$table" | awk -F. '{print $1}') tab_name=$(echo "$table" | awk -F. '{print $2}') local_table_existed=$(${MYSQL_LOCAL_SHORT_SILENT} -e "select TABLE_SCHEMA,TABLE_NAME from \ INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=\"${tab_schema}\" AND TABLE_NAME=\"${tab_name}\";") if [ -n "$local_table_existed" ]; then # TODO: If last updated field of a table structure has different # patterns (updated/timstamp), it may be worth to parameterize the patterns. datetime=$(${MYSQL_LOCAL_SHORT_SILENT} -e "describe ${table};" | \ awk '(/updated/ || /timestamp/) && /datetime/ {print $1}') if [ -n "${datetime}" ]; then data_ages=$(${MYSQL_LOCAL_SHORT_SILENT} -e "select \ time_to_sec(timediff(now(),${datetime})) from ${table} where ${datetime} is not null order by 1 limit 10;") for age in $data_ages; do if [ "$age" -le $age_threshold ]; then data_freshness=true break fi done # As long as there is an indication of data freshness, no need to check further if [ "$data_freshness" = true ] ; then break fi else skipped_freshness=true log "No indicator to determine data freshness for table $table. Skipped data freshness check." # Dumping out table structure to determine if enhancement is needed to include this table debug_info=$(${MYSQL_LOCAL} --skip-column-names -e "describe ${table};" | awk '{print $2 " " $1}') log "$debug_info" "DEBUG" fi else log "Table $table doesn't exist in local database" skipped_freshness=true fi done if [ "$data_freshness" = true ] ; then log "Database passed integrity (data freshness) check." else if [ "$skipped_freshness" = false ] ; then log "Local backup database restore failed integrity check." "ERROR" log "The backup may not have captured the up-to-date data." "INFO" return 1 fi fi else log "No tables changed in this backup. Skipped data freshness check as the" log "check should have been performed by previous validation runs." fi return 0 } cleanup_local_databases () { old_local_dbs=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|sys' || true) for db in $old_local_dbs; do ${MYSQL_LOCAL_SHORT_SILENT} -e "drop database $db;" done } list_archive_dir () { archive_dir_content=$(ls -1R "$ARCHIVE_DIR") if [ -n "$archive_dir_content" ]; then log "Content of $ARCHIVE_DIR" log "${archive_dir_content}" fi } remove_remote_archive_file () { archive_file=$(basename "$1") token_req_file=$(mktemp --suffix ".json") header_file=$(mktemp) resp_file=$(mktemp --suffix ".json") http_resp="404" HEADER_CONTENT_TYPE="Content-Type: application/json" HEADER_ACCEPT="Accept: application/json" cat << JSON_EOF > "$token_req_file" { "auth": { "identity": { "methods": [ "password" ], "password": { "user": { "domain": { "name": "${OS_USER_DOMAIN_NAME}" }, "name": "${OS_USERNAME}", "password": "${OS_PASSWORD}" } } }, "scope": { "project": { "domain": { "name": "${OS_PROJECT_DOMAIN_NAME}" }, "name": "${OS_PROJECT_NAME}" } } } } JSON_EOF http_resp=$(curl -s -X POST "$OS_AUTH_URL/auth/tokens" -H "${HEADER_CONTENT_TYPE}" \ -H "${HEADER_ACCEPT}" -d @"${token_req_file}" -D "$header_file" -o "$resp_file" -w "%{http_code}") if [ "$http_resp" = "201" ]; then OS_TOKEN=$(grep -i "x-subject-token" "$header_file" | cut -d' ' -f2 | tr -d "\r") if [ -n "$OS_TOKEN" ]; then OS_OBJ_URL=$(python3 -c "import json,sys;print([[ep['url'] for ep in obj['endpoints'] if ep['interface']=='public'] for obj in json.load(sys.stdin)['token']['catalog'] if obj['type']=='object-store'][0][0])" < "$resp_file") if [ -n "$OS_OBJ_URL" ]; then http_resp=$(curl -s -X DELETE "$OS_OBJ_URL/$CONTAINER_NAME/$archive_file" \ -H "${HEADER_CONTENT_TYPE}" -H "${HEADER_ACCEPT}" \ -H "X-Auth-Token: ${OS_TOKEN}" -D "$header_file" -o "$resp_file" -w "%{http_code}") fi fi fi if [ "$http_resp" == "404" ] ; then log "Failed to cleanup remote backup. Container object $archive_file is not on RGW." return 1 fi if [ "$http_resp" != "204" ] ; then log "Failed to cleanup remote backup. Cannot delete container object $archive_file" "ERROR" cat "$header_file" cat "$resp_file" fi return 0 } handle_bad_archive_file () { archive_file=$1 if [ ! -d "$BAD_ARCHIVE_DIR" ]; then mkdir -p "$BAD_ARCHIVE_DIR" fi # Move the file to quarantine directory such that # file won't be used for restore in case of recovery # log "Moving $i to $BAD_ARCHIVE_DIR..." mv "$i" "$BAD_ARCHIVE_DIR" log "Removing $i from remote RGW..." if remove_remote_archive_file "$i"; then log "File $i has been successfully removed from RGW." else log "FIle $i cannot be removed form RGW." "ERROR" return 1 fi # Atmost only three bad files are kept. Deleting the oldest if # number of files exceeded the threshold. # bad_files=$(find "$BAD_ARCHIVE_DIR" -name "*.tar.gz" 2>/dev/null | wc -l) if [ "$bad_files" -gt 3 ]; then ((bad_files=bad_files-3)) delete_files=$(find "$BAD_ARCHIVE_DIR" -name "*.tar.gz" 2>/dev/null | sort | head --lines=$bad_files) for b in $delete_files; do log "Deleting $b..." rm -f "${b}" done fi return 0 } cleanup_old_validation_result_file () { clean_files=$(find "$ARCHIVE_DIR" -maxdepth 1 -name "*.passed" 2>/dev/null) for d in $clean_files; do archive_file=${d/.passed} if [ ! -f "$archive_file" ]; then log "Deleting $d as its associated archive file $archive_file nolonger existed." rm -f "${d}" fi done } validate_databases_backup () { archive_file=$1 SCOPE=${2:-"all"} restore_log='/tmp/restore_error.log' tmp_dir=$(mktemp -d) rm -f $restore_log cd "$tmp_dir" log "Decompressing archive $archive_file..." if ! tar zxvf - < "$archive_file" 1>/dev/null; then log "Database restore from local backup failed. Archive decompression failed." "ERROR" return 1 fi db_list_file="$tmp_dir/db.list" if [[ -e "$db_list_file" ]]; then dbs=$(sort < "$db_list_file" | grep -ivE sys | tr '\n' ' ') else dbs=" " fi sql_file="${tmp_dir}/mariadb.${MARIADB_POD_NAMESPACE}.${SCOPE}.sql" if [[ "${SCOPE}" == "all" ]]; then grant_file="${tmp_dir}/grants.sql" else grant_file="${tmp_dir}/${SCOPE}_grant.sql" fi if [[ -f $sql_file ]]; then if $MYSQL_LOCAL < "$sql_file" 2>$restore_log; then local_dbs=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|sys' | sort | tr '\n' ' ') if [ "$dbs" = "$local_dbs" ]; then log "Databases restored successful." else log "Database restore from local backup failed. Database mismatched between local backup and local server" "ERROR" log "Databases restored on local server: $local_dbs" "DEBUG" log "Databases in the local backup: $dbs" "DEBUG" return 1 fi else log "Database restore from local backup failed. $dbs" "ERROR" cat $restore_log return 1 fi if [[ -f $grant_file ]]; then if $MYSQL_LOCAL < "$grant_file" 2>$restore_log; then if ! $MYSQL_LOCAL -e 'flush privileges;'; then log "Database restore from local backup failed. Failed to flush privileges." "ERROR" return 1 fi log "Databases permission restored successful." else log "Database restore from local backup failed. Databases permission failed to restore." "ERROR" cat "$restore_log" cat "$grant_file" log "Local DBs: $local_dbs" "DEBUG" return 1 fi else log "Database restore from local backup failed. There is no permission file available" "ERROR" return 1 fi if ! check_data_freshness "$archive_file" ${SCOPE}; then # Log has already generated during check data freshness return 1 fi else log "Database restore from local backup failed. There is no database file available to restore from" "ERROR" return 1 fi return 0 } # end of functions form mariadb verifier chart # Verify all the databases backup archives verify_databases_backup_archives() { SCOPE=${1:-"all"} # verification code export DB_NAME="mariadb" export ARCHIVE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${MARIADB_POD_NAMESPACE}/${DB_NAME}/archive export BAD_ARCHIVE_DIR=${ARCHIVE_DIR}/quarantine export MYSQL_OPTS="--silent --skip-column-names" export MYSQL_LIVE="mariadb ${MYSQL_OPTS}" export MYSQL_LOCAL_OPTS="" export MYSQL_LOCAL_SHORT="mariadb ${MYSQL_LOCAL_OPTS} --connect-timeout 2" export MYSQL_LOCAL_SHORT_SILENT="${MYSQL_LOCAL_SHORT} ${MYSQL_OPTS}" export MYSQL_LOCAL="mariadb ${MYSQL_LOCAL_OPTS} --connect-timeout 10" max_wait={{ .Values.conf.mariadb_server.setup_wait.iteration }} duration={{ .Values.conf.mariadb_server.setup_wait.duration }} counter=0 dbisup=false log "Waiting for Mariadb backup verification server to start..." # During Mariadb init/startup process, a temporary server is startup # and shutdown prior to starting up the normal server. # To avoid prematurely determine server availability, lets snooze # a bit to give time for the process to complete prior to issue # mysql commands. # while [ $counter -lt $max_wait ]; do if ! $MYSQL_LOCAL_SHORT -e 'select 1' > /dev/null 2>&1 ; then sleep $duration ((counter=counter+1)) else # Lets sleep for an additional duration just in case async # init takes a bit more time to complete. # sleep $duration dbisup=true counter=$max_wait fi done if ! $dbisup; then log "Mariadb backup verification server is not running" "ERROR" return 1 fi # During Mariadb init process, a test database will be briefly # created and deleted. Adding to the exclusion list for some # edge cases # clean_db=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|test|sys' || true) if [[ -z "${clean_db// }" ]]; then log "Clean Server is up and running" else cleanup_local_databases log "Old databases found on the Mariadb backup verification server were cleaned." clean_db=$(${MYSQL_LOCAL_SHORT_SILENT} -e 'show databases;' | \ grep -ivE 'information_schema|performance_schema|mysql|test|sys' || true) if [[ -z "${clean_db// }" ]]; then log "Clean Server is up and running" else log "Cannot clean old databases on verification server." "ERROR" return 1 fi log "The server is ready for verification." fi # Starting with 10.4.13, new definer mariadb.sys was added. However, mariadb.sys was deleted # during init mariadb as it was not on the exclusion list. This corrupted the view of mysql.user. # Insert the tuple back to avoid other similar issues with error i.e # The user specified as a definer ('mariadb.sys'@'localhost') does not exist # # Before insert the tuple mentioned above, we should make sure that the MariaDB version is 10.4.+ mariadb_version=$($MYSQL_LOCAL_SHORT -e "status" | grep -E '^Server\s+version:') log "Current database ${mariadb_version}" if [[ ! -z ${mariadb_version} && -z $(grep '10.2' <<< ${mariadb_version}) ]]; then if [[ -z $(grep 'mariadb.sys' <<< $($MYSQL_LOCAL_SHORT mysql -e "select * from global_priv where user='mariadb.sys'")) ]]; then $MYSQL_LOCAL_SHORT -e "insert into mysql.global_priv values ('localhost','mariadb.sys',\ '{\"access\":0,\"plugin\":\"mysql_native_password\",\"authentication_string\":\"\",\"account_locked\":true,\"password_last_changed\":0}');" $MYSQL_LOCAL_SHORT -e 'flush privileges;' fi fi # Ensure archive dir existed if [ -d "$ARCHIVE_DIR" ]; then # List archive dir before list_archive_dir # Ensure the local databases are clean for each restore validation # cleanup_local_databases if [[ "${SCOPE}" == "all" ]]; then archive_files=$(find "$ARCHIVE_DIR" -maxdepth 1 -name "*.tar.gz" 2>/dev/null | sort) for i in $archive_files; do archive_file_passed=$i.passed if [ ! -f "$archive_file_passed" ]; then log "Validating archive file $i..." if validate_databases_backup "$i"; then touch "$archive_file_passed" else if handle_bad_archive_file "$i"; then log "File $i has been removed from RGW." else log "File $i cannot be removed from RGW." "ERROR" return 1 fi fi fi done else archive_files=$(find "$ARCHIVE_DIR" -maxdepth 1 -name "*.tar.gz" 2>/dev/null | grep "${SCOPE}" | sort) for i in $archive_files; do archive_file_passed=$i.passed if [ ! -f "$archive_file_passed" ]; then log "Validating archive file $i..." if validate_databases_backup "${i}" "${SCOPE}"; then touch "$archive_file_passed" else if handle_bad_archive_file "$i"; then log "File $i has been removed from RGW." else log "File $i cannot be removed from RGW." "ERROR" return 1 fi fi fi done fi # Cleanup passed files if its archive file nolonger existed cleanup_old_validation_result_file # List archive dir after list_archive_dir fi return 0 } # Call main program to start the database backup backup_databases ${SCOPE} ================================================ FILE: mariadb-backup/templates/bin/_restore_mariadb.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. {{- $envAll := . }} # Capture the user's command line arguments ARGS=("$@") if [[ -s /tmp/restore_main.sh ]]; then source /tmp/restore_main.sh else echo "File /tmp/restore_main.sh does not exist." exit 1 fi # Export the variables needed by the framework export DB_NAME="mariadb" export DB_NAMESPACE=${MARIADB_POD_NAMESPACE} export ARCHIVE_DIR=${MARIADB_BACKUP_BASE_DIR}/db/${DB_NAMESPACE}/${DB_NAME}/archive RESTORE_USER='restoreuser' RESTORE_PW=$(pwgen 16 1) RESTORE_LOG='/tmp/restore_error.log' rm -f $RESTORE_LOG # This is for commands which require admin access MYSQL="mariadb \ --defaults-file=/etc/mysql/admin_user.cnf \ --connect-timeout 10" # This is for commands which we want the temporary "restore" user # to execute RESTORE_CMD="mariadb \ --user=${RESTORE_USER} \ --password=${RESTORE_PW} \ --host={{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} \ --port={{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} \ {{- if .Values.manifests.certificates }} --ssl-ca=/etc/mysql/certs/ca.crt \ --ssl-key=/etc/mysql/certs/tls.key \ --ssl-cert=/etc/mysql/certs/tls.crt \ {{- end }} --connect-timeout 10" # Get a single database data from the SQL file. # $1 - database name # $2 - sql file path current_db_desc() { PATTERN="-- Current Database:" sed -n "/${PATTERN} \`$1\`/,/${PATTERN}/p" $2 } #Return all database from an archive get_databases() { TMP_DIR=$1 DB_FILE=$2 if [[ -e ${TMP_DIR}/db.list ]] then DBS=$(cat ${TMP_DIR}/db.list | \ grep -ivE 'information_schema|performance_schema|mysql|sys' ) else DBS=" " fi echo $DBS > $DB_FILE } # Determine sql file from 2 options - current and legacy one # if current is not found check that there is no other namespaced dump file # before falling back to legacy one _get_sql_file() { TMP_DIR=$1 SQL_FILE="${TMP_DIR}/mariadb.${MARIADB_POD_NAMESPACE}.*.sql" LEGACY_SQL_FILE="${TMP_DIR}/mariadb.*.sql" INVALID_SQL_FILE="${TMP_DIR}/mariadb.*.*.sql" if [ -f ${SQL_FILE} ] then echo "Found $(ls ${SQL_FILE})" > /dev/stderr printf ${SQL_FILE} elif [ -f ${INVALID_SQL_FILE} ] then echo "Expected to find ${SQL_FILE} or ${LEGACY_SQL_FILE}, but found $(ls ${INVALID_SQL_FILE})" > /dev/stderr elif [ -f ${LEGACY_SQL_FILE} ] then echo "Falling back to legacy naming ${LEGACY_SQL_FILE}. Found $(ls ${LEGACY_SQL_FILE})" > /dev/stderr printf ${LEGACY_SQL_FILE} fi } # Extract all tables of a database from an archive and put them in the requested # file. get_tables() { DATABASE=$1 TMP_DIR=$2 TABLE_FILE=$3 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then current_db_desc ${DATABASE} ${SQL_FILE} \ | grep "^CREATE TABLE" | awk -F '`' '{print $2}' \ > $TABLE_FILE else # Error, cannot report the tables echo "No SQL file found - cannot extract the tables" return 1 fi } # Extract all rows in the given table of a database from an archive and put # them in the requested file. get_rows() { DATABASE=$1 TABLE=$2 TMP_DIR=$3 ROW_FILE=$4 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then current_db_desc ${DATABASE} ${SQL_FILE} \ | grep "INSERT INTO \`${TABLE}\` VALUES" > $ROW_FILE return 0 else # Error, cannot report the rows echo "No SQL file found - cannot extract the rows" return 1 fi } # Extract the schema for the given table in the given database belonging to # the archive file found in the TMP_DIR. get_schema() { DATABASE=$1 TABLE=$2 TMP_DIR=$3 SCHEMA_FILE=$4 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then DB_FILE=$(mktemp -p /tmp) current_db_desc ${DATABASE} ${SQL_FILE} > ${DB_FILE} sed -n /'CREATE TABLE `'$TABLE'`'/,/'--'/p ${DB_FILE} > ${SCHEMA_FILE} if [[ ! (-s ${SCHEMA_FILE}) ]]; then sed -n /'CREATE TABLE IF NOT EXISTS `'$TABLE'`'/,/'--'/p ${DB_FILE} \ > ${SCHEMA_FILE} fi rm -f ${DB_FILE} else # Error, cannot report the rows echo "No SQL file found - cannot extract the schema" return 1 fi } # Create temporary user for restoring specific databases. create_restore_user() { restore_db=$1 # Ensure any old restore user is removed first, if it exists. # If it doesn't exist it may return error, so do not exit the # script if that's the case. delete_restore_user "dont_exit_on_error" $MYSQL --execute="GRANT SELECT ON *.* TO ${RESTORE_USER}@'%' IDENTIFIED BY '${RESTORE_PW}';" 2>>$RESTORE_LOG if [[ "$?" -eq 0 ]] then $MYSQL --execute="GRANT ALL ON ${restore_db}.* TO ${RESTORE_USER}@'%' IDENTIFIED BY '${RESTORE_PW}';" 2>>$RESTORE_LOG if [[ "$?" -ne 0 ]] then cat $RESTORE_LOG echo "Failed to grant restore user ALL permissions on database ${restore_db}" return 1 fi else cat $RESTORE_LOG echo "Failed to grant restore user select permissions on all databases" return 1 fi } # Delete temporary restore user delete_restore_user() { error_handling=$1 $MYSQL --execute="DROP USER ${RESTORE_USER}@'%';" 2>>$RESTORE_LOG if [[ "$?" -ne 0 ]] then if [ "$error_handling" == "exit_on_error" ] then cat $RESTORE_LOG echo "Failed to delete temporary restore user - needs attention to avoid a security hole" return 1 fi fi } #Restore a single database restore_single_db() { SINGLE_DB_NAME=$1 TMP_DIR=$2 if [[ -z "$SINGLE_DB_NAME" ]] then echo "Restore single DB called but with wrong parameter." return 1 fi SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then # Restoring a single database requires us to create a temporary user # which has capability to only restore that ONE database. One gotcha # is that the mysql command to restore the database is going to throw # errors because of all the other databases that it cannot access. So # because of this reason, the --force option is used to prevent the # command from stopping on an error. create_restore_user $SINGLE_DB_NAME if [[ $? -ne 0 ]] then echo "Restore $SINGLE_DB_NAME failed create restore user." return 1 fi $RESTORE_CMD --force < $SQL_FILE 2>>$RESTORE_LOG if [[ "$?" -eq 0 ]] then echo "Database $SINGLE_DB_NAME Restore successful." else cat $RESTORE_LOG delete_restore_user "exit_on_error" echo "Database $SINGLE_DB_NAME Restore failed." return 1 fi delete_restore_user "exit_on_error" if [[ $? -ne 0 ]] then echo "Restore $SINGLE_DB_NAME failed delete restore user." return 1 fi if [ -f ${TMP_DIR}/${SINGLE_DB_NAME}_grant.sql ] then $MYSQL < ${TMP_DIR}/${SINGLE_DB_NAME}_grant.sql 2>>$RESTORE_LOG if [[ "$?" -eq 0 ]] then if ! $MYSQL --execute="FLUSH PRIVILEGES;"; then echo "Failed to flush privileges for $SINGLE_DB_NAME." return 1 fi echo "Database $SINGLE_DB_NAME Permission Restore successful." else cat $RESTORE_LOG echo "Database $SINGLE_DB_NAME Permission Restore failed." return 1 fi else echo "There is no permission file available for $SINGLE_DB_NAME" return 1 fi else echo "There is no database file available to restore from" return 1 fi return 0 } #Restore all the databases restore_all_dbs() { TMP_DIR=$1 SQL_FILE=$(_get_sql_file $TMP_DIR) if [ ! -z $SQL_FILE ]; then # Check the scope of the archive. SCOPE=$(echo ${SQL_FILE} | awk -F'.' '{print $(NF-1)}') if [[ "${SCOPE}" != "all" ]]; then # This is just a single database backup. The user should # instead use the single database restore option. echo "Cannot use the restore all option for an archive containing only a single database." echo "Please use the single database restore option." return 1 fi $MYSQL < $SQL_FILE 2>$RESTORE_LOG if [[ "$?" -eq 0 ]] then echo "Databases $( echo $DBS | tr -d '\n') Restore successful." else cat $RESTORE_LOG echo "Databases $( echo $DBS | tr -d '\n') Restore failed." return 1 fi if [[ -f ${TMP_DIR}/grants.sql ]] then $MYSQL < ${TMP_DIR}/grants.sql 2>$RESTORE_LOG if [[ "$?" -eq 0 ]] then if ! $MYSQL --execute="FLUSH PRIVILEGES;"; then echo "Failed to flush privileges." return 1 fi echo "Databases Permission Restore successful." else cat $RESTORE_LOG echo "Databases Permission Restore failed." return 1 fi else echo "There is no permission file available" return 1 fi else echo "There is no database file available to restore from" return 1 fi return 0 } # Call the CLI interpreter, providing the archive directory path and the # user arguments passed in cli_main ${ARGS[@]} ================================================ FILE: mariadb-backup/templates/bin/_start_mariadb_verify_server.sh.tpl ================================================ #!/bin/bash -ex # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. log () { msg_default="Need some text to log" level_default="INFO" component_default="Mariadb Backup Verifier" msg=${1:-$msg_default} level=${2:-$level_default} component=${3:-"$component_default"} echo "$(date +'%Y-%m-%d %H:%M:%S,%3N') - ${component} - ${level} - ${msg}" } log "Starting Mariadb server for backup verification..." mysql_install_db --user=nobody --ldata=/var/lib/mysql >/dev/null 2>&1 MYSQL_ALLOW_EMPTY_PASSWORD=1 mysqld --user=nobody --verbose >/dev/null 2>&1 ================================================ FILE: mariadb-backup/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{ if eq .Values.endpoints.oslo_db.auth.admin.username .Values.endpoints.oslo_db.auth.sst.username }} {{ fail "the DB admin username should not match the sst user username" }} {{ end }} --- apiVersion: v1 kind: ConfigMap metadata: name: mariadb-backup-bin data: backup_mariadb.sh: | {{ tuple "bin/_backup_mariadb.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} start_verification_server.sh: | {{ tuple "bin/_start_mariadb_verify_server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} restore_mariadb.sh: | {{ tuple "bin/_restore_mariadb.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} backup_main.sh: | {{ include "helm-toolkit.scripts.db-backup-restore.backup_main" . | indent 4 }} restore_main.sh: | {{ include "helm-toolkit.scripts.db-backup-restore.restore_main" . | indent 4 }} {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.manifests.job_ks_user }} ks-user.sh: | {{ include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- end }} {{- end }} ... ================================================ FILE: mariadb-backup/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License" ); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: mariadb-backup-etc data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "my" ) "key" "my.cnf" ) | indent 2 }} {{- end }} ================================================ FILE: mariadb-backup/templates/cron-job-backup-mariadb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_mariadb_backup }} {{- $envAll := . }} {{- $serviceAccountName := "mariadb-backup" }} {{- $failoverUserClass := .Values.conf.backup.remote_backup.failover_user_class }} {{ tuple $envAll "mariadb_backup" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: mariadb-backup annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "mariadb-backup" "backup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: schedule: {{ .Values.jobs.mariadb_backup.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.mariadb_backup.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.mariadb_backup.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "mariadb-backup" "backup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "mariadb-backup" "containerNames" (list "init" "backup-perms" "mariadb-backup") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{- if .Values.jobs.mariadb_backup.backoffLimit }} backoffLimit: {{ .Values.jobs.mariadb_backup.backoffLimit }} {{- end }} {{- if .Values.jobs.mariadb_backup.activeDeadlineSeconds }} activeDeadlineSeconds: {{ .Values.jobs.mariadb_backup.activeDeadlineSeconds }} {{- end }} template: metadata: labels: {{ tuple $envAll "mariadb-backup" "backup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ dict "envAll" $envAll "application" "mariadb_backup" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure shareProcessNamespace: true {{- if $envAll.Values.pod.tolerations.mariadb.enabled }} {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{- end }} {{- if $envAll.Values.pod.affinity }} {{- if $envAll.Values.pod.affinity.mariadb_backup }} affinity: {{ index $envAll.Values.pod.affinity "mariadb_backup" | toYaml | indent 12}} {{- end }} {{- end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "mariadb_backup" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} - name: backup-perms {{ tuple $envAll "mariadb_backup" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.mariadb_backup | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "mariadb_backup" "container" "backup_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - chown - -R - "65534:65534" - $(MARIADB_BACKUP_BASE_DIR) env: - name: MARIADB_BACKUP_BASE_DIR value: {{ .Values.conf.backup.base_path | quote }} volumeMounts: - mountPath: /tmp name: pod-tmp - mountPath: {{ .Values.conf.backup.base_path }} name: mariadb-backup-dir - name: verify-perms {{ tuple $envAll "mariadb_backup" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.mariadb_backup | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "mariadb_backup" "container" "verify_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - chown - -R - "65534:65534" - /var/lib/mysql volumeMounts: - mountPath: /tmp name: pod-tmp - mountPath: /var/lib/mysql name: mysql-data containers: - name: mariadb-backup command: - /bin/sh args: - -c - >- ( /tmp/start_verification_server.sh ) & /tmp/backup_mariadb.sh env: - name: MARIADB_BACKUP_BASE_DIR value: {{ .Values.conf.backup.base_path | quote }} - name: MYSQL_BACKUP_MYSQLDUMP_OPTIONS value: {{ .Values.conf.backup.mysqldump_options | quote }} - name: MARIADB_LOCAL_BACKUP_DAYS_TO_KEEP value: {{ .Values.conf.backup.days_to_keep | quote }} - name: MARIADB_POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: REMOTE_BACKUP_ENABLED value: "{{ .Values.conf.backup.remote_backup.enabled }}" {{- if .Values.conf.backup.remote_backup.enabled }} - name: MARIADB_REMOTE_BACKUP_DAYS_TO_KEEP value: {{ .Values.conf.backup.remote_backup.days_to_keep | quote }} - name: CONTAINER_NAME value: {{ .Values.conf.backup.remote_backup.container_name | quote }} - name: STORAGE_POLICY value: "{{ .Values.conf.backup.remote_backup.storage_policy }}" - name: NUMBER_OF_RETRIES_SEND_BACKUP_TO_REMOTE value: {{ .Values.conf.backup.remote_backup.number_of_retries | quote }} - name: MIN_DELAY_SEND_BACKUP_TO_REMOTE value: {{ .Values.conf.backup.remote_backup.delay_range.min | quote }} - name: MAX_DELAY_SEND_BACKUP_TO_REMOTE value: {{ .Values.conf.backup.remote_backup.delay_range.max | quote }} - name: THROTTLE_BACKUPS_ENABLED value: "{{ .Values.conf.backup.remote_backup.throttle_backups.enabled }}" - name: THROTTLE_LIMIT value: {{ .Values.conf.backup.remote_backup.throttle_backups.sessions_limit | quote }} - name: THROTTLE_LOCK_EXPIRE_AFTER value: {{ .Values.conf.backup.remote_backup.throttle_backups.lock_expire_after | quote }} - name: THROTTLE_RETRY_AFTER value: {{ .Values.conf.backup.remote_backup.throttle_backups.retry_after | quote }} - name: THROTTLE_CONTAINER_NAME value: {{ .Values.conf.backup.remote_backup.throttle_backups.container_name | quote }} {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.mariadb }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 16 }} {{- $failoverIdentityClass := index $envAll.Values.endpoints.identity.auth $failoverUserClass }} {{- if $failoverIdentityClass }} {{- include "helm-toolkit.snippets.keystone_openrc_failover_env_vars" $env | indent 16 }} {{- end }} {{- end }} {{- end }} {{ tuple $envAll "mariadb_backup" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.mariadb_backup | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "mariadb_backup" "container" "mariadb_backup" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} volumeMounts: - name: pod-tmp mountPath: /tmp - mountPath: /tmp/backup_mariadb.sh name: mariadb-backup-bin readOnly: true subPath: backup_mariadb.sh - mountPath: /tmp/backup_main.sh name: mariadb-backup-bin readOnly: true subPath: backup_main.sh - mountPath: {{ .Values.conf.backup.base_path }} name: mariadb-backup-dir - name: mariadb-backup-secrets mountPath: /etc/mysql/admin_user.cnf subPath: admin_user.cnf readOnly: true - name: mariadb-backup-bin mountPath: /tmp/start_verification_server.sh readOnly: true subPath: start_verification_server.sh - name: mysql-data mountPath: /var/lib/mysql - name: var-run mountPath: /run/mysqld {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} volumes: - name: pod-tmp emptyDir: {} - name: mycnfd emptyDir: {} - name: var-run emptyDir: {} - name: mariadb-backup-etc configMap: name: mariadb-backup-etc defaultMode: 0444 - name: mysql-data emptyDir: {} - name: mariadb-backup-secrets secret: secretName: mariadb-backup-secrets defaultMode: 420 - configMap: defaultMode: 365 name: mariadb-backup-bin name: mariadb-backup-bin {{- if and .Values.volume.backup.enabled .Values.manifests.pvc_backup }} - name: mariadb-backup-dir persistentVolumeClaim: claimName: mariadb-backup-data {{- else }} - hostPath: path: {{ .Values.conf.backup.base_path }} type: DirectoryOrCreate name: mariadb-backup-dir {{- end }} {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- end }} ================================================ FILE: mariadb-backup/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: mariadb-backup/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $serviceName := tuple "oslo_db" "server" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" $serviceName -}} {{- if .Values.pod.tolerations.mariadb.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: mariadb-backup/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user }} {{- $backoffLimit := .Values.jobs.ks_user.backoffLimit }} {{- $activeDeadlineSeconds := .Values.jobs.ks_user.activeDeadlineSeconds }} {{- $serviceName := tuple "oslo_db" "server" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $ksUserJob := dict "envAll" . "serviceName" $serviceName "configMapBin" "mariadb-backup-bin" "backoffLimit" $backoffLimit "activeDeadlineSeconds" $activeDeadlineSeconds -}} {{- if .Values.pod.tolerations.mariadb.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: mariadb-backup/templates/mariadb-backup-pvc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.volume.backup.enabled .Values.manifests.pvc_backup }} --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: mariadb-backup-data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: {{ .Values.volume.backup.size }} storageClassName: {{ .Values.volume.backup.class_name }} ... {{- end }} ================================================ FILE: mariadb-backup/templates/secret-backup-restore.yaml ================================================ {{/* This manifest results a secret being created which has the key information needed for backing up and restoring the Mariadb databases. */}} {{- if and .Values.conf.backup.enabled .Values.manifests.secret_backup_restore }} {{- $envAll := . }} {{- $userClass := "backup_restore" }} {{- $secretName := index $envAll.Values.secrets.mariadb $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: BACKUP_ENABLED: {{ $envAll.Values.conf.backup.enabled | quote | b64enc }} BACKUP_BASE_PATH: {{ $envAll.Values.conf.backup.base_path | b64enc }} LOCAL_DAYS_TO_KEEP: {{ $envAll.Values.conf.backup.days_to_keep | quote | b64enc }} MYSQLDUMP_OPTIONS: {{ $envAll.Values.conf.backup.mysqldump_options | b64enc }} REMOTE_BACKUP_ENABLED: {{ $envAll.Values.conf.backup.remote_backup.enabled | quote | b64enc }} REMOTE_BACKUP_CONTAINER: {{ $envAll.Values.conf.backup.remote_backup.container_name | b64enc }} REMOTE_BACKUP_DAYS_TO_KEEP: {{ $envAll.Values.conf.backup.remote_backup.days_to_keep | quote | b64enc }} REMOTE_BACKUP_STORAGE_POLICY: {{ $envAll.Values.conf.backup.remote_backup.storage_policy | b64enc }} REMOTE_BACKUP_RETRIES: {{ $envAll.Values.conf.backup.remote_backup.number_of_retries | quote | b64enc }} REMOTE_BACKUP_SEND_DELAY_MIN: {{ $envAll.Values.conf.backup.remote_backup.delay_range.min | quote | b64enc }} REMOTE_BACKUP_SEND_DELAY_MAX: {{ $envAll.Values.conf.backup.remote_backup.delay_range.max | quote | b64enc }} THROTTLE_BACKUPS_ENABLED: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.enabled | quote | b64enc }} THROTTLE_LIMIT: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.sessions_limit | quote | b64enc }} THROTTLE_LOCK_EXPIRE_AFTER: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.lock_expire_after | quote | b64enc }} THROTTLE_RETRY_AFTER: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.retry_after | quote | b64enc }} THROTTLE_CONTAINER_NAME: {{ $envAll.Values.conf.backup.remote_backup.throttle_backups.container_name | quote | b64enc }} ... {{- end }} ================================================ FILE: mariadb-backup/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: mariadb-backup/templates/secret-rgw.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. This manifest results in two secrets being created: 1) Keystone "mariadb" secret, which is needed to access the cluster (remote or same cluster) for storing mariadb backups. If the cluster is remote, the auth_url would be non-null. 2) Keystone "admin" secret, which is needed to create the "mariadb" keystone account mentioned above. This may not be needed if the account is in a remote cluster (auth_url is non-null in that case). */}} {{- if .Values.conf.backup.remote_backup.enabled }} {{- $envAll := . }} {{- $userClass := .Values.conf.backup.remote_backup.primary_user_class }} {{- $failoverUserClass := .Values.conf.backup.remote_backup.failover_user_class }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- $identityClass := index .Values.endpoints.identity.auth $userClass }} {{- if $identityClass.auth_url }} OS_AUTH_URL: {{ $identityClass.auth_url | b64enc }} {{- else }} OS_AUTH_URL: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} {{- end }} OS_REGION_NAME: {{ $identityClass.region_name | b64enc }} OS_INTERFACE: {{ $identityClass.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME: {{ $identityClass.project_domain_name | b64enc }} OS_PROJECT_NAME: {{ $identityClass.project_name | b64enc }} OS_USER_DOMAIN_NAME: {{ $identityClass.user_domain_name | b64enc }} OS_USERNAME: {{ $identityClass.username | b64enc }} OS_PASSWORD: {{ $identityClass.password | b64enc }} OS_DEFAULT_DOMAIN: {{ $identityClass.default_domain_id | default "default" | b64enc }} {{- $failoverIdentityClass := index .Values.endpoints.identity.auth $failoverUserClass }} {{- if $failoverIdentityClass }} {{- if $failoverIdentityClass.auth_url }} OS_AUTH_URL_FAILOVER: {{ $failoverIdentityClass.auth_url | b64enc }} {{- else }} OS_AUTH_URL_FAILOVER: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} {{- end }} OS_REGION_NAME_FAILOVER: {{ $failoverIdentityClass.region_name | b64enc }} OS_INTERFACE_FAILOVER: {{ $failoverIdentityClass.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME_FAILOVER: {{ $failoverIdentityClass.project_domain_name | b64enc }} OS_PROJECT_NAME_FAILOVER: {{ $failoverIdentityClass.project_name | b64enc }} OS_USER_DOMAIN_NAME_FAILOVER: {{ $failoverIdentityClass.user_domain_name | b64enc }} OS_USERNAME_FAILOVER: {{ $failoverIdentityClass.username | b64enc }} OS_PASSWORD_FAILOVER: {{ $failoverIdentityClass.password | b64enc }} OS_DEFAULT_DOMAIN_FAILOVER: {{ $failoverIdentityClass.default_domain_id | default "default" | b64enc }} {{- end }} ... {{- if .Values.manifests.job_ks_user }} {{- $userClass := "admin" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- $identityClass := index .Values.endpoints.identity.auth $userClass }} {{- if $identityClass.auth_url }} OS_AUTH_URL: {{ $identityClass.auth_url | b64enc }} {{- else }} OS_AUTH_URL: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} {{- end }} OS_REGION_NAME: {{ $identityClass.region_name | b64enc }} OS_INTERFACE: {{ $identityClass.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME: {{ $identityClass.project_domain_name | b64enc }} OS_PROJECT_NAME: {{ $identityClass.project_name | b64enc }} OS_USER_DOMAIN_NAME: {{ $identityClass.user_domain_name | b64enc }} OS_USERNAME: {{ $identityClass.username | b64enc }} OS_PASSWORD: {{ $identityClass.password | b64enc }} OS_DEFAULT_DOMAIN: {{ $identityClass.default_domain_id | default "default" | b64enc }} ... {{- end }} {{- end }} ================================================ FILE: mariadb-backup/templates/secrets/_admin_user.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.admin.username }} password = {{ .Values.endpoints.oslo_db.auth.admin.password }} host = {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} port = {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: mariadb-backup/templates/secrets/_admin_user_internal.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.admin.username }} password = {{ .Values.endpoints.oslo_db.auth.admin.password }} host = {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} port = {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: mariadb-backup/templates/secrets-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-backup-secrets type: Opaque data: admin_user.cnf: {{ tuple "secrets/_admin_user.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} admin_user_internal.cnf: {{ tuple "secrets/_admin_user_internal.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} {{- end }} ================================================ FILE: mariadb-backup/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for mariadb. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null images: tags: mariadb: quay.io/airshipit/mariadb:latest-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble mariadb_backup: quay.io/airshipit/porthole-mysqlclient-utility:latest-ubuntu_noble pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled pod: security_context: server: pod: runAsUser: 999 container: perms: runAsUser: 0 readOnlyRootFilesystem: true init: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: false agent: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: false mariadb: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: false mariadb_backup: pod: runAsUser: 65534 container: backup_perms: runAsUser: 0 readOnlyRootFilesystem: true verify_perms: runAsUser: 0 readOnlyRootFilesystem: true mariadb_backup: runAsUser: 65534 readOnlyRootFilesystem: true allowPrivilegeEscalation: false tests: pod: runAsUser: 999 container: test: runAsUser: 999 readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: mariadb: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule replicas: server: 3 prometheus_mysql_exporter: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: prometheus_mysql_exporter: timeout: 30 error_pages: timeout: 10 disruption_budget: mariadb: min_available: 0 resources: enabled: false server: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: tests: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" mariadb_backup: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - mariadb-server-image-repo-sync services: - endpoint: node service: local_image_registry static: mariadb_server_ks_user: services: - endpoint: internal service: oslo_db mariadb_backup: services: - endpoint: internal service: oslo_db image_repo_sync: services: - endpoint: internal service: local_image_registry tests: services: - endpoint: internal service: oslo_db volume: backup: enabled: true class_name: general size: 5Gi jobs: mariadb_backup: # activeDeadlineSeconds == 0 means no deadline activeDeadlineSeconds: 0 backoffLimit: 6 cron: "0 0 * * *" history: success: 3 failed: 1 ks_user: # activeDeadlineSeconds == 0 means no deadline activeDeadlineSeconds: 0 backoffLimit: 6 conf: mariadb_server: setup_wait: iteration: 30 duration: 5 database: my: | [mysqld] datadir=/var/lib/mysql basedir=/usr ignore-db-dirs=lost+found [client-server] !includedir /etc/mysql/conf.d/ backup: enabled: false base_path: /var/backup validateData: ageOffset: 120 mysqldump_options: > --single-transaction --quick --add-drop-database --add-drop-table --add-locks --databases days_to_keep: 3 remote_backup: enabled: false container_name: mariadb days_to_keep: 14 storage_policy: default-placement number_of_retries: 5 delay_range: min: 30 max: 60 throttle_backups: enabled: false sessions_limit: 480 lock_expire_after: 7200 retry_after: 3600 container_name: throttle-backups-manager primary_user_class: mariadb-server failover_user_class: mariadb-server_failover secrets: identity: admin: keystone-admin-user mariadb-server: mariadb-backup-user mariadb: backup_restore: mariadb-backup-restore oci_image_registry: mariadb: mariadb-oci-image-registry-key tls: oslo_db: server: public: mariadb-tls-server internal: mariadb-tls-direct # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false mariadb: username: mariadb password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null oslo_db: namespace: null auth: admin: username: root password: password sst: username: sst password: password audit: username: audit password: password exporter: username: exporter password: password hosts: default: mariadb-server-primary direct: mariadb-server-internal discovery: mariadb-discovery server: mariadb-server host_fqdn_override: default: null path: null scheme: mysql+pymysql port: mysql: default: 3306 wsrep: default: 4567 identity: name: backup-storage-auth namespace: openstack auth: admin: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default mariadb: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null role: admin region_name: RegionOne username: mariadb-backup-user password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 network_policy: mariadb: ingress: - {} egress: - {} manifests: certificates: false configmap_bin: true configmap_etc: true job_ks_user: false cron_job_mariadb_backup: true pvc_backup: true network_policy: false pod_test: true secret_dbadmin_password: true secret_sst_password: true secret_dbaudit_password: true secret_backup_restore: true secret_etc: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: mariadb-cluster/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *~ # Various IDEs .project .idea/ *.tmproj ================================================ FILE: mariadb-cluster/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v10.6.14 description: OpenStack-Helm MariaDB controlled by mariadb-operator name: mariadb-cluster version: 2025.2.0 home: https://mariadb.com/kb/en/ icon: http://badges.mariadb.org/mariadb-badge-180x60.png sources: - https://github.com/MariaDB/server - https://github.com/mariadb-operator/mariadb-operator - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: mariadb-cluster/README.rst ================================================ openstack-helm/mariadb ====================== By default, this chart creates a 3-member mariadb galera cluster. This chart depends on mariadb-operator chart. The StatefulSets all leverage PVCs to provide stateful storage to ``/var/lib/mysql``. You must ensure that your control nodes that should receive mariadb instances are labeled with ``openstack-control-plane=enabled``, or whatever you have configured in values.yaml for the label configuration: :: kubectl label nodes openstack-control-plane=enabled --all ================================================ FILE: mariadb-cluster/templates/bin/_liveness.sh.tpl ================================================ #!/usr/bin/env bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e MYSQL="mariadb \ --defaults-file=/etc/mysql/admin_user.cnf \ --host=localhost \ {{- if .Values.manifests.certificates }} --ssl-verify-server-cert=false \ --ssl-ca=/etc/mysql/certs/ca.crt \ --ssl-key=/etc/mysql/certs/tls.key \ --ssl-cert=/etc/mysql/certs/tls.crt \ {{- end }} --connect-timeout 2" mysql_status_query () { STATUS=$1 $MYSQL -e "show status like \"${STATUS}\"" | \ awk "/${STATUS}/ { print \$NF; exit }" } {{- if eq (int .Values.pod.replicas.server) 1 }} if ! $MYSQL -e 'select 1' > /dev/null 2>&1 ; then exit 1 fi {{- else }} # if [ -f /var/lib/mysql/sst_in_progress ]; then # # SST in progress, with this node receiving a snapshot. # # MariaDB won't be up yet; avoid killing. # exit 0 # fi if [ "x$(mysql_status_query wsrep_ready)" != "xON" ]; then # WSREP says the node can receive queries exit 1 fi if [ "x$(mysql_status_query wsrep_connected)" != "xON" ]; then # WSREP connected exit 1 fi if [ "x$(mysql_status_query wsrep_cluster_status)" != "xPrimary" ]; then # Not in primary cluster exit 1 fi wsrep_local_state_comment=$(mysql_status_query wsrep_local_state_comment) if [ "x${wsrep_local_state_comment}" != "xSynced" ] && [ "x${wsrep_local_state_comment}" != "xDonor/Desynced" ]; then # WSREP not synced or not sending SST exit 1 fi {{- end }} ================================================ FILE: mariadb-cluster/templates/bin/_readiness.sh.tpl ================================================ #!/usr/bin/env bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e MYSQL="mariadb \ --defaults-file=/etc/mysql/admin_user.cnf \ --host=localhost \ {{- if .Values.manifests.certificates }} --ssl-verify-server-cert=false \ --ssl-ca=/etc/mysql/certs/ca.crt \ --ssl-key=/etc/mysql/certs/tls.key \ --ssl-cert=/etc/mysql/certs/tls.crt \ {{- end }} --connect-timeout 2" mysql_status_query () { STATUS=$1 $MYSQL -e "show status like \"${STATUS}\"" | \ awk "/${STATUS}/ { print \$NF; exit }" } if ! $MYSQL -e 'select 1' > /dev/null 2>&1 ; then exit 1 fi {{- if gt (int .Values.pod.replicas.server) 1 }} if [ "x$(mysql_status_query wsrep_ready)" != "xON" ]; then # WSREP says the node can receive queries exit 1 fi if [ "x$(mysql_status_query wsrep_connected)" != "xON" ]; then # WSREP connected exit 1 fi if [ "x$(mysql_status_query wsrep_cluster_status)" != "xPrimary" ]; then # Not in primary cluster exit 1 fi if [ "x$(mysql_status_query wsrep_local_state_comment)" != "xSynced" ]; then # WSREP not synced exit 1 fi {{- end }} ================================================ FILE: mariadb-cluster/templates/bin/_test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex rm -f /tmp/test-success mysqlslap \ --defaults-file=/etc/mysql/test-params.cnf \ {{ include "helm-toolkit.utils.joinListWithSpace" $.Values.conf.tests.params }} -vv \ --post-system="touch /tmp/test-success" if ! [ -f /tmp/test-success ]; then exit 1 fi ================================================ FILE: mariadb-cluster/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "oslo_db" "type" "default" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: mariadb-cluster/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{ if eq .Values.endpoints.oslo_db.auth.admin.username .Values.endpoints.oslo_db.auth.sst.username }} {{ fail "the DB admin username should not match the sst user username" }} {{ end }} --- apiVersion: v1 kind: ConfigMap metadata: name: mariadb-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "init_script" ) "key" "init.sh" ) | indent 2 }} readiness.sh: | {{ tuple "bin/_readiness.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} liveness.sh: | {{ tuple "bin/_liveness.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} test.sh: | {{ tuple "bin/_test.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- if .Values.manifests.job_ks_user }} ks-user.sh: | {{ include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- end }} {{- end }} ================================================ FILE: mariadb-cluster/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License" ); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: mariadb-etc data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "my" ) "key" "my.cnf" ) | indent 2 }} {{- end }} ================================================ FILE: mariadb-cluster/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: mariadb-cluster/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $serviceName := tuple "oslo_db" "server" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" $serviceName -}} {{- if .Values.pod.tolerations.mariadb.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: mariadb-cluster/templates/job-refresh-statefulset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.mariadb }} {{- $envAll := . }} {{- $serviceAccountName := "mariadb-cluster-refresh-statefulset" }} {{ tuple $envAll "mariadb_cluster_refresh_statefulset" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} rules: - apiGroups: - "" - extensions - batch - apps resources: - statefulsets verbs: - get - list - delete --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: name: mariadb-cluster-refresh-statefulset labels: {{ tuple $envAll "mariadb-cluster" "refresh-statefulset" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": "post-upgrade" "helm.sh/hook-weight": "5" "helm.sh/hook-delete-policy": "before-hook-creation" spec: backoffLimit: {{ .Values.jobs.mariadb_cluster_refresh_statefulset.backoffLimit }} template: metadata: labels: {{ tuple $envAll "mariadb-cluster" "refresh-statefulset" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "" "containerNames" (list "init" "exporter-create-sql-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "job" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} activeDeadlineSeconds: {{ .Values.jobs.mariadb_cluster_refresh_statefulset.activeDeadlineSeconds }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "mariadb_cluster_refresh_statefulset" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: refresh-statefulset {{ tuple $envAll "mariadb_cluster_refresh_statefulset" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "mariadb_cluster_refresh_statefulset" "container" "main" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.mariadb_cluster_refresh_statefulset | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: ["/bin/sh", "-c"] args: ["kubectl delete statefulset ${STATEFULSET_NAME} --namespace=${NAMESPACE}"] env: - name: STATEFULSET_NAME value: {{ tuple "oslo_db" "server" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace volumeMounts: - name: pod-tmp mountPath: /tmp volumes: - name: pod-tmp emptyDir: {} {{- end }} ================================================ FILE: mariadb-cluster/templates/mariadb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "mariadbReadinessProbe" }} exec: command: - /tmp/readiness.sh {{- end }} {{- define "mariadbLivenessProbe" }} exec: command: - /tmp/liveness.sh {{- end }} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.mariadb }} {{- $envAll := . }} --- apiVersion: mariadb.mmontes.io/v1alpha1 kind: MariaDB metadata: # NOTE(portdirect): the statefulset name must match the POD_NAME_PREFIX env var for discovery to work name: {{ tuple "oslo_db" "server" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} mariadb-dbadmin-password-hash: {{ tuple "secret-dbadmin-password.yaml" . | include "helm-toolkit.utils.hash" }} labels: {{ tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: rootPasswordSecretKeyRef: name: mariadb-dbadmin-password key: MYSQL_DBADMIN_PASSWORD {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.image" | indent 2 }} initContainers: - command: - /tmp/init.sh {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.image" | indent 6 }} {{ dict "envAll" $envAll "application" "server" "container" "perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ if $envAll.Values.conf.galera.enabled }} galera: enabled: true primary: podIndex: {{ .Values.conf.galera.primary.podIndex }} automaticFailover: {{ .Values.conf.galera.primary.automaticFailover }} sst: {{ .Values.conf.galera.sst }} replicaThreads: {{ .Values.conf.galera.replicaThreads }} agent: {{ tuple $envAll "agent" | include "helm-toolkit.snippets.image" | indent 6 }} {{- dict "envAll" $envAll "application" "server" "container" "agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} args: - '--graceful-shutdown-timeout=5s' - '--recovery-timeout=5m0s' - '-log-dev' - '-log-level=debug' port: {{ .Values.conf.galera.agent.port }} {{- if $envAll.Values.conf.galera.agent.kubernetesAuth.enabled }} kubernetesAuth: enabled: true {{- end }} gracefulShutdownTimeout: {{ .Values.conf.galera.agent.gracefulShutdownTimeout }} {{- if $envAll.Values.conf.galera.recovery.enabled }} recovery: enabled: true clusterHealthyTimeout: {{ .Values.conf.galera.recovery.clusterHealthyTimeout }} clusterBootstrapTimeout: {{ .Values.conf.galera.recovery.clusterBootstrapTimeout }} podRecoveryTimeout: {{ .Values.conf.galera.recovery.podRecoveryTimeout }} podSyncTimeout: {{ .Values.conf.galera.recovery.podSyncTimeout }} {{- end }} initContainer: {{ tuple $envAll "initContainer" | include "helm-toolkit.snippets.image" | indent 6 }} {{- dict "envAll" $envAll "application" "server" "container" "init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} args: - '-log-dev' - '-log-level=debug' # galera volume templates volumeClaimTemplate: resources: requests: storage: {{ .Values.volume.galera.size }} accessModes: - ReadWriteOnce storageClassName: {{ .Values.volume.galera.class_name }} {{ end }} {{ include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" ( index $envAll.Values.conf.database "galera" ) "key" "myCnf" ) | indent 2 }} replicas: {{ .Values.pod.replicas.server }} affinity: {{- tuple $envAll "mariadb" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 4 }} {{ if $envAll.Values.pod.tolerations.mariadb.enabled }} {{- tuple $envAll "mariadb" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{- end }} updateStrategy: type: {{ .Values.pod.lifecycle.upgrades.deployments.pod_replacement_strategy }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 2 }} {{ dict "envAll" $envAll "application" "server" "container" "mariadb" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 2 }} nodeSelector: {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value }} podAnnotations: {{- dict "envAll" $envAll "podName" "mariadb-server" "containerNames" (list "init-0" "init" "agent" "mariadb") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} podDisruptionBudget: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.mariadb.min_available }} {{ dict "envAll" . "component" "server" "container" "mariadb" "type" "readiness" "probeTemplate" (include "mariadbReadinessProbe" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 2 }} {{ dict "envAll" . "component" "server" "container" "mariadb" "type" "liveness" "probeTemplate" (include "mariadbLivenessProbe" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 2 }} {{ if .Values.monitoring.prometheus.enabled }} metrics: exporter: {{ tuple $envAll "prometheus_mysql_exporter" | include "helm-toolkit.snippets.image" | indent 6 }} {{ dict "envAll" $envAll "application" "prometheus_mysql_exporter" "container" "exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus_mysql_exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} port: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if $envAll.Values.manifests.certificates }} volumeMounts: {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{- end }} serviceMonitor: prometheusRelease: prometheus-mysql-exporter interval: 10s scrapeTimeout: 10s {{ end }} env: - name: MYSQL_HISTFILE value: {{ .Values.conf.database.mysql_histfile }} {{ if .Values.conf.database.auto_upgrade.enabled }} - name: MARIADB_AUTO_UPGRADE value: {{ .Values.conf.database.auto_upgrade.enabled | quote }} - name: MARIADB_DISABLE_UPGRADE_BACKUP value: {{ .Values.conf.database.auto_upgrade.disable_upgrade_backup | quote }} {{ end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: mariadb-secrets mountPath: /etc/mysql/admin_user.cnf subPath: admin_user.cnf readOnly: true - name: mariadb-secrets mountPath: /docker-entrypoint-initdb.d/privileges.sql subPath: privileges.sql readOnly: true - name: mariadb-bin mountPath: /tmp/init.sh subPath: init.sh - name: mariadb-bin mountPath: /tmp/readiness.sh subPath: readiness.sh readOnly: true - name: mariadb-bin mountPath: /tmp/liveness.sh subPath: liveness.sh readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 4 }} volumes: - name: pod-tmp emptyDir: {} - name: mariadb-bin configMap: name: mariadb-bin defaultMode: 0555 - name: mariadb-etc configMap: name: mariadb-etc defaultMode: 0444 - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} # storage volume templates volumeClaimTemplate: resources: requests: storage: {{ .Values.volume.size }} accessModes: - ReadWriteOnce {{- if ne .Values.volume.class_name "default" }} storageClassName: {{ .Values.volume.class_name }} {{- end }} {{- end }} ================================================ FILE: mariadb-cluster/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "mariadb" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: mariadb-cluster/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $dependencies := .Values.dependencies.static.tests }} {{- $serviceAccountName := print .deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.deployment_name}}-test" labels: {{ tuple $envAll "mariadb" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "mariadb-test" "containerNames" (list "init" "mariadb-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "tests" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} {{ if $envAll.Values.pod.tolerations.mariadb.enabled }} {{ tuple $envAll "mariadb" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: mariadb-test {{ dict "envAll" $envAll "application" "tests" "container" "test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} command: - /tmp/test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: mariadb-bin mountPath: /tmp/test.sh subPath: test.sh readOnly: true - name: mariadb-secrets mountPath: /etc/mysql/test-params.cnf {{ if eq $envAll.Values.conf.tests.endpoint "internal" }} subPath: admin_user_internal.cnf {{ else if eq $envAll.Values.conf.tests.endpoint "direct" }} subPath: admin_user.cnf {{ else }} {{ fail "Either 'direct' or 'internal' should be specified for .Values.conf.tests.endpoint" }} {{ end }} readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} volumes: - name: pod-tmp emptyDir: {} - name: mariadb-bin configMap: name: mariadb-bin defaultMode: 0555 - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} ================================================ FILE: mariadb-cluster/templates/secret-dbadmin-password.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_dbadmin_password }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-dbadmin-password type: Opaque data: MYSQL_DBADMIN_PASSWORD: {{ .Values.endpoints.oslo_db.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: mariadb-cluster/templates/secret-dbaudit-password.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_dbaudit_password }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-dbaudit-password type: Opaque data: MYSQL_DBAUDIT_PASSWORD: {{ .Values.endpoints.oslo_db.auth.audit.password | b64enc }} {{- end }} ================================================ FILE: mariadb-cluster/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: mariadb-cluster/templates/secret-sst-password.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_sst_password }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-dbsst-password type: Opaque data: MYSQL_DBSST_PASSWORD: {{ .Values.endpoints.oslo_db.auth.sst.password | b64enc }} {{- end }} ================================================ FILE: mariadb-cluster/templates/secrets/_admin_user.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.admin.username }} password = {{ .Values.endpoints.oslo_db.auth.admin.password }} host = {{ tuple "oslo_db" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} port = {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: mariadb-cluster/templates/secrets/_admin_user_internal.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.admin.username }} password = {{ .Values.endpoints.oslo_db.auth.admin.password }} host = {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} port = {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: mariadb-cluster/templates/secrets/_privileges.sql.tpl ================================================ ########################################### # The lines not confirmed to be working with operator are disabled ########################################### # DELETE FROM mysql.user WHERE user != 'mariadb.sys'; # CREATE OR REPLACE USER '{{ .Values.endpoints.oslo_db.auth.admin.username }}'@'%' IDENTIFIED BY '{{ .Values.endpoints.oslo_db.auth.admin.password }}'; {{- if .Values.manifests.certificates }} GRANT ALL ON *.* TO '{{ .Values.endpoints.oslo_db.auth.admin.username }}'@'%' REQUIRE X509 WITH GRANT OPTION; {{- else }} GRANT ALL ON *.* TO '{{ .Values.endpoints.oslo_db.auth.admin.username }}'@'%' WITH GRANT OPTION; {{- end }} DROP DATABASE IF EXISTS test ; # CREATE OR REPLACE USER '{{ .Values.endpoints.oslo_db.auth.sst.username }}'@'127.0.0.1' IDENTIFIED BY '{{ .Values.endpoints.oslo_db.auth.sst.password }}'; # GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO '{{ .Values.endpoints.oslo_db.auth.sst.username }}'@'127.0.0.1' ; CREATE OR REPLACE USER '{{ .Values.endpoints.oslo_db.auth.audit.username }}'@'%' IDENTIFIED BY '{{ .Values.endpoints.oslo_db.auth.audit.password }}'; {{- if .Values.manifests.certificates }} GRANT SELECT ON *.* TO '{{ .Values.endpoints.oslo_db.auth.audit.username }}'@'%' REQUIRE X509; {{- else }} GRANT SELECT ON *.* TO '{{ .Values.endpoints.oslo_db.auth.audit.username }}'@'%' ; {{- end }} FLUSH PRIVILEGES ; ================================================ FILE: mariadb-cluster/templates/secrets-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: mariadb-secrets type: Opaque data: admin_user.cnf: {{ tuple "secrets/_admin_user.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} admin_user_internal.cnf: {{ tuple "secrets/_admin_user_internal.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} privileges.sql: {{ tuple "secrets/_privileges.sql.tpl" . | include "helm-toolkit.utils.template" | b64enc }} {{- end }} ================================================ FILE: mariadb-cluster/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for mariadb. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null images: tags: agent: ghcr.io/mariadb-operator/agent:v0.0.3 initContainer: ghcr.io/mariadb-operator/init:v0.0.6 mariadb: quay.io/airshipit/mariadb:latest-ubuntu_noble prometheus_mysql_exporter: docker.io/prom/mysqld-exporter:v0.12.1 prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: quay.io/airshipit/docker:27.5.0 scripted_test: quay.io/airshipit/mariadb:latest-ubuntu_noble mariadb_cluster_refresh_statefulset: quay.io/airshipit/porthole-mysqlclient-utility:latest-ubuntu_noble pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled pod: probes: server: mariadb: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 15 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 30 timeoutSeconds: 15 security_context: server: pod: runAsUser: 0 container: init-0: runAsUser: 0 readOnlyRootFilesystem: true init: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: false agent: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: false mariadb: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: false mariadb_cluster_refresh_statefulset: pod: runAsUser: 0 container: main: allowPrivilegeEscalation: false readOnlyRootFilesystem: true tests: pod: runAsUser: 999 container: test: runAsUser: 999 readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: mariadb: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule replicas: server: 3 prometheus_mysql_exporter: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: prometheus_mysql_exporter: timeout: 30 disruption_budget: mariadb: min_available: 0 resources: enabled: false server: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: tests: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" mariadb_cluster_refresh_statefulset: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - mariadb-server-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry tests: services: - endpoint: internal service: oslo_db volume: enabled: true class_name: general size: 5Gi backup: enabled: true class_name: general size: 5Gi galera: enabled: true class_name: general size: 300Mi jobs: mariadb_cluster_refresh_statefulset: backoffLimit: 87600 activeDeadlineSeconds: 3600 conf: galera: enabled: true primary: podIndex: 0 automaticFailover: true sst: mariabackup replicaThreads: 1 agent: port: 5555 kubernetesAuth: enabled: true gracefulShutdownTimeout: 5s recovery: enabled: true clusterHealthyTimeout: 3m clusterBootstrapTimeout: 10m podRecoveryTimeout: 5m podSyncTimeout: 5m tests: # This may either be: # * internal: which will hit the endpoint exposed by the ingress controller # * direct: which will hit the backends directly via a k8s service ip # Note, deadlocks and failure are to be expected with concurrency if # hitting the `direct` endpoint. endpoint: internal # This is a list of tuning params passed to mysqlslap: params: - --auto-generate-sql - --concurrency=100 - --number-of-queries=1000 - --number-char-cols=1 - --number-int-cols=1 mariadb_server: setup_wait: iteration: 30 duration: 5 database: auto_upgrade: enabled: true disable_upgrade_backup: false mysql_histfile: "/dev/null" init_script: | #!/usr/bin/env bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x chown -R "mysql:mysql" /var/lib/mysql; chmod 771 /var/lib/mysql; galera: | [mariadb] bind-address=0.0.0.0 default_storage_engine=InnoDB binlog_format=row innodb_autoinc_lock_mode=2 max_allowed_packet=256M ######################## # ######################## ignore-db-dirs=lost+found # Charset character_set_server=utf8 collation_server=utf8_general_ci skip-character-set-client-handshake # Logging slow_query_log=off slow_query_log_file=/var/log/mysql/mariadb-slow.log log_warnings=2 # General logging has huge performance penalty therefore is disabled by default general_log=off general_log_file=/var/log/mysql/mariadb-error.log long_query_time=3 log_queries_not_using_indexes=on # Networking bind_address=0.0.0.0 port={{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} # When a client connects, the server will perform hostname resolution, # and when DNS is slow, establishing the connection will become slow as well. # It is therefore recommended to start the server with skip-name-resolve to # disable all DNS lookups. The only limitation is that the GRANT statements # must then use IP addresses only. skip_name_resolve # Tuning user=mysql max_allowed_packet=256M open_files_limit=10240 max_connections=8192 max-connect-errors=1000000 # General security settings # Reference: https://dev.mysql.com/doc/mysql-security-excerpt/8.0/en/general-security-issues.html # secure_file_priv is set to '/home' because it is read-only, which will # disable this feature completely. secure_file_priv=/home local_infile=0 symbolic_links=0 sql_mode="STRICT_ALL_TABLES,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" ## Generally, it is unwise to set the query cache to be larger than 64-128M ## as the costs associated with maintaining the cache outweigh the performance ## gains. ## The query cache is a well known bottleneck that can be seen even when ## concurrency is moderate. The best option is to disable it from day 1 ## by setting query_cache_size=0 (now the default on MySQL 5.6) ## and to use other ways to speed up read queries: good indexing, adding ## replicas to spread the read load or using an external cache. query_cache_size=0 query_cache_type=0 sync_binlog=0 thread_cache_size=16 table_open_cache=2048 table_definition_cache=1024 # # InnoDB # # The buffer pool is where data and indexes are cached: having it as large as possible # will ensure you use memory and not disks for most read operations. # Typical values are 50..75% of available RAM. # TODO(tomasz.paszkowski): This needs to by dynamic based on available RAM. innodb_buffer_pool_size=1024M innodb_doublewrite=0 innodb_file_per_table=1 innodb_flush_method=O_DIRECT innodb_io_capacity=500 innodb_log_file_size=128M innodb_old_blocks_time=1000 innodb_read_io_threads=8 innodb_write_io_threads=8 {{ if .Values.manifests.certificates }} # TLS ssl_ca=/etc/mysql/certs/ca.crt ssl_key=/etc/mysql/certs/tls.key ssl_cert=/etc/mysql/certs/tls.crt # tls_version = TLSv1.2,TLSv1.3 {{ end }} [mysqldump] max-allowed-packet=16M [client] default_character_set=utf8 {{ if .Values.manifests.certificates }} # TLS ssl_ca=/etc/mysql/certs/ca.crt ssl_key=/etc/mysql/certs/tls.key ssl_cert=/etc/mysql/certs/tls.crt # tls_version = TLSv1.2,TLSv1.3 {{ end }} my: | [mysqld] datadir=/var/lib/mysql basedir=/usr ignore-db-dirs=lost+found [client-server] !includedir /etc/mysql/conf.d/ config_override: null # Any configuration here will override the base config. # config_override: |- # [mysqld] # wsrep_slave_threads=1 monitoring: prometheus: enabled: false mysqld_exporter: scrape: true secrets: identity: admin: keystone-admin-user oci_image_registry: mariadb: mariadb-oci-image-registry-key tls: oslo_db: server: public: mariadb-tls-server internal: mariadb-tls-direct # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false mariadb: username: mariadb password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null monitoring: name: prometheus namespace: null hosts: default: prom-metrics public: prometheus host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9090 public: 80 prometheus_mysql_exporter: namespace: null hosts: default: mysql-exporter host_fqdn_override: default: null path: default: /metrics scheme: default: 'http' port: metrics: default: 9104 oslo_db: namespace: null auth: admin: username: root password: password sst: username: sst password: password audit: username: audit password: password exporter: username: exporter password: password hosts: default: mariadb-server-primary direct: mariadb-server-internal discovery: mariadb-discovery server: mariadb-server host_fqdn_override: default: null path: null scheme: mysql+pymysql port: mysql: default: 3306 wsrep: default: 4567 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns_tcp: default: 53 dns: default: 53 protocol: UDP identity: name: backup-storage-auth namespace: openstack auth: admin: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default mariadb-server: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null role: admin region_name: RegionOne username: mariadb-backup-user password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 network_policy: mariadb: ingress: - {} egress: - {} manifests: certificates: false configmap_bin: true configmap_etc: true job_image_repo_sync: true network_policy: false pod_test: true secret_dbadmin_password: true secret_sst_password: true secret_dbaudit_password: true secret_etc: true secret_registry: true service_primary: true mariadb: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: masakari/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *.orig *~ # Various IDEs .project .idea/ *.tmproj .vscode/ ================================================ FILE: masakari/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Masakari name: masakari version: 2025.2.0 home: https://docs.openstack.org/developer/masakari icon: https://www.openstack.org/themes/openstack/images/project-mascots/Masakari/OpenStack_Project_masakari_vertical.png sources: - https://opendev.org/openstack/masakari - https://opendev.org/openstack/masakari-monitors - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: masakari/templates/bin/_manage-db.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} exec -ex masakari-manage db sync ================================================ FILE: masakari/templates/bin/_masakari-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec masakari-api --config-file /etc/masakari/masakari.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: masakari/templates/bin/_masakari-engine.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec masakari-engine --config-file /etc/masakari/masakari.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: masakari/templates/bin/_masakari-host-monitor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec masakari-hostmonitor --config-file /etc/masakari/masakarimonitors.conf \ --config-file /tmp/pod-shared/masakarimonitors.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: masakari/templates/bin/_masakari-instance-monitor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec masakari-instancemonitor --config-file /etc/masakari/masakarimonitors.conf \ --config-file /tmp/pod-shared/masakarimonitors.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: masakari/templates/bin/_masakari-introspective-instance-monitor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec masakari-introspectiveinstancemonitor --config-file /etc/masakari/masakarimonitors.conf \ --config-file /tmp/pod-shared/masakarimonitors.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: masakari/templates/bin/_masakari-monitors-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex nova_compute_hostname="$COMPUTE_NODE_NAME" cat </tmp/pod-shared/masakarimonitors.conf [DEFAULT] hostname=$nova_compute_hostname EOF ================================================ FILE: masakari/templates/bin/_masakari-process-monitor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec masakari-processmonitor --config-file /etc/masakari/masakarimonitors.conf \ --config-file /tmp/pod-shared/masakarimonitors.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: masakari/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: masakari-bin data: masakari-engine.sh: | {{ tuple "bin/_masakari-engine.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} masakari-api.sh: | {{ tuple "bin/_masakari-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} manage-db.sh: | {{ tuple "bin/_manage-db.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} masakari-host-monitor.sh: | {{ tuple "bin/_masakari-host-monitor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} masakari-process-monitor.sh: | {{ tuple "bin/_masakari-process-monitor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} masakari-instance-monitor.sh: | {{ tuple "bin/_masakari-instance-monitor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} masakari-introspective-instance-monitor.sh: | {{ tuple "bin/_masakari-introspective-instance-monitor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} masakari-monitors-init.sh: | {{ tuple "bin/_masakari-monitors-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: masakari/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "masakari.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty .Values.conf.masakari.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.masakari.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.masakari.keystone_authtoken "region_name" .Values.endpoints.identity.auth.masakari.region_name -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.masakari.keystone_authtoken "project_name" .Values.endpoints.identity.auth.masakari.project_name -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.masakari.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.masakari.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.masakari.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.masakari.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.username -}} {{- $_ := set .Values.conf.masakari.keystone_authtoken "username" .Values.endpoints.identity.auth.masakari.username -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.password -}} {{- $_ := set .Values.conf.masakari.keystone_authtoken "password" .Values.endpoints.identity.auth.masakari.password -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.masakari.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.masakari.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.masakari.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.masakari.database.connection)) (empty .Values.conf.masakari.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "masakari" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.masakari.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.masakari.database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "masakari" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.masakari.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.os_privileged_user_name -}} {{- $_ := set .Values.conf.masakari.DEFAULT "os_privileged_user_name" .Values.endpoints.identity.auth.masakari.username }} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.os_privileged_user_password -}} {{- $_ := set .Values.conf.masakari.DEFAULT "os_privileged_user_password" .Values.endpoints.identity.auth.masakari.password }} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.os_privileged_user_auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.masakari.DEFAULT "os_privileged_user_auth_url" }} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.os_privileged_user_tenant -}} {{- $_ := set .Values.conf.masakari.DEFAULT "os_privileged_user_tenant" .Values.endpoints.identity.auth.masakari.project_name }} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.os_region_name -}} {{- $_ := set .Values.conf.masakari.DEFAULT "os_region_name" .Values.endpoints.identity.auth.masakari.region_name }} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.os_user_domain_name -}} {{- $_ := set .Values.conf.masakari.DEFAULT "os_user_domain_name" .Values.endpoints.identity.auth.masakari.user_domain_name }} {{- end -}} {{- if empty .Values.conf.masakari.DEFAULT.os_project_domain_name -}} {{- $_ := set .Values.conf.masakari.DEFAULT "os_project_domain_name" .Values.endpoints.identity.auth.masakari.user_domain_name }} {{- end -}} {{- if empty .Values.conf.masakarimonitors.api.region -}} {{- $_ := set .Values.conf.masakarimonitors.api "region" .Values.endpoints.identity.auth.masakari.region_name -}} {{- end -}} {{- if empty .Values.conf.masakarimonitors.api.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.masakarimonitors.api "auth_url" }} {{- end -}} {{- if empty .Values.conf.masakarimonitors.api.project_name -}} {{- $_ := set .Values.conf.masakarimonitors.api "project_name" .Values.endpoints.identity.auth.masakari.project_name }} {{- end -}} {{- if empty .Values.conf.masakarimonitors.api.project_domain_name -}} {{- $_ := set .Values.conf.masakarimonitors.api "project_domain_name" .Values.endpoints.identity.auth.masakari.project_name }} {{- end -}} {{- if empty .Values.conf.masakarimonitors.api.username -}} {{- $_ := set .Values.conf.masakarimonitors.api "username" .Values.endpoints.identity.auth.masakari.username }} {{- end -}} {{- if empty .Values.conf.masakarimonitors.api.user_domain_name -}} {{- $_ := set .Values.conf.masakarimonitors.api "user_domain_name" .Values.endpoints.identity.auth.masakari.user_domain_name }} {{- end -}} {{- if empty .Values.conf.masakarimonitors.api.password -}} {{- $_ := set .Values.conf.masakarimonitors.api "password" .Values.endpoints.identity.auth.masakari.password }} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.masakari.taskflow.connection)) (empty .Values.conf.masakari.taskflow.connection) -}} {{- $connection := tuple "oslo_db" "internal" "masakari" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.masakari.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.masakari.taskflow "connection" $connection -}} {{- end -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: masakari.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.masakari | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.paste | b64enc }} masakarimonitors.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.masakarimonitors | b64enc }} masakari_sudoers: {{ $envAll.Values.conf.masakari_sudoers | b64enc }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "masakari-etc" . | include "masakari.configmap.etc" }} {{- end }} ================================================ FILE: masakari/templates/daemonset-host-monitor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.host_monitor }} {{- $envAll := . }} {{- $daemonset := "masakari-host-monitor" }} {{- $mounts_masakari_host_monitor := .Values.pod.mounts.masakari_host_monitor.masakari_host_monitor }} {{- $mounts_masakari_host_monitor_init := .Values.pod.mounts.masakari_host_monitor.init_container }} {{- $serviceAccountName := "masakari-host-monitor" }} {{- tuple $envAll "masakari_host_monitor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: masakari-host-monitor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{- dict "envAll" $envAll "podName" "masakari-host-monitor" "containerNames" (list "masakari-monitor") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "masakari_host_monitor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "masakari-host-monitor" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.monitors.node_selector_key }}: {{ .Values.labels.monitors.node_selector_value }} initContainers: {{ tuple $envAll "masakari_host_monitor" $mounts_masakari_host_monitor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: hostmonitor-init {{ tuple $envAll "masakari_host_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_host_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_host_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-monitors-init.sh env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-monitors-init.sh subPath: masakari-monitors-init.sh readOnly: true hostNetwork: true containers: - name: masakari-host-monitor {{ tuple $envAll "masakari_host_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_host_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_host_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-host-monitor.sh - start env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName lifecycle: preStop: exec: command: - /tmp/masakari-host-monitor.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.masakari.oslo_concurrency.lock_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-host-monitor.sh subPath: masakari-host-monitor.sh - name: masakari-etc mountPath: /etc/masakari/masakarimonitors.conf subPath: masakarimonitors.conf - name: masakari-etc mountPath: /etc/sudoers.d/masakari_sudoers subPath: masakari_sudoers - name: masakarietc mountPath: /etc/masakari - name: varrun mountPath: /var/run - name: run mountPath: /run - name: shm mountPath: /dev/shm volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-shared emptyDir: {} - name: masakarietc emptyDir: {} - name: shm hostPath: path: /dev/shm - name: varrun hostPath: path: /var/run - name: run hostPath: path: /run - name: masakari-bin configMap: name: masakari-bin defaultMode: 0555 - name: masakari-etc secret: secretName: masakari-etc defaultMode: 0444 {{- end }} ================================================ FILE: masakari/templates/daemonset-instance-monitor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.instance_monitor }} {{- $envAll := . }} {{- $daemonset := "masakari-instance-monitor" }} {{- $mounts_masakari_instance_monitor := .Values.pod.mounts.masakari_instance_monitor.masakari_instance_monitor }} {{- $mounts_masakari_instance_monitor_init := .Values.pod.mounts.masakari_instance_monitor.init_container }} {{- $serviceAccountName := "masakari-instance-monitor" }} {{- tuple $envAll "masakari_instance_monitor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: masakari-instance-monitor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{- dict "envAll" $envAll "podName" "masakari-instance-monitor" "containerNames" (list "masakari-monitor") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "masakari_instance_monitor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "masakari-instance-monitor" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.monitors.node_selector_key }}: {{ .Values.labels.monitors.node_selector_value }} initContainers: {{ tuple $envAll "masakari_instance_monitor" $mounts_masakari_instance_monitor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: instancemonitor-init {{ tuple $envAll "masakari_instance_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_instance_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_instance_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-monitors-init.sh env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-monitors-init.sh subPath: masakari-monitors-init.sh readOnly: true containers: - name: masakari-instance-monitor {{ tuple $envAll "masakari_instance_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_instance_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_instance_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-instance-monitor.sh - start env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName lifecycle: preStop: exec: command: - /tmp/masakari-instance-monitor.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.masakari.oslo_concurrency.lock_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-instance-monitor.sh subPath: masakari-instance-monitor.sh - name: masakari-etc mountPath: /etc/masakari/masakarimonitors.conf subPath: masakarimonitors.conf - name: masakarietc mountPath: /etc/masakari - name: varrun mountPath: /var/run - name: run mountPath: /run volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-shared emptyDir: {} - name: masakarietc emptyDir: {} - name: varrun hostPath: path: /var/run - name: run hostPath: path: /run - name: masakari-bin configMap: name: masakari-bin defaultMode: 0555 - name: masakari-etc secret: secretName: masakari-etc defaultMode: 0444 {{- end }} ================================================ FILE: masakari/templates/daemonset-introspective-instance-monitor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.introspective_instance_monitor }} {{- $envAll := . }} {{- $daemonset := "masakari-introspective-instance-monitor" }} {{- $mounts_masakari_introspective_instance_monitor := .Values.pod.mounts.masakari_introspective_instance_monitor.masakari_introspective_instance_monitor }} {{- $mounts_masakari_introspective_instance_monitor_init := .Values.pod.mounts.masakari_introspective_instance_monitor.init_container }} {{- $serviceAccountName := "masakari-introspective-instance-monitor" }} {{- tuple $envAll "masakari_introspective_instance_monitor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: masakari-introspective-instance-monitor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{- dict "envAll" $envAll "podName" "masakari-introspective-instance-monitor" "containerNames" (list "masakari-monitor") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "masakari_introspective_instance_monitor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "masakari-introspective-instance-monitor" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.monitors.node_selector_key }}: {{ .Values.labels.monitors.node_selector_value }} initContainers: {{ tuple $envAll "masakari_introspective_instance_monitor" $mounts_masakari_introspective_instance_monitor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: introspective-instance-monitor-init {{ tuple $envAll "masakari_introspective_instance_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_introspective_instance_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_introspective_instance_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-monitors-init.sh env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-monitors-init.sh subPath: masakari-monitors-init.sh readOnly: true hostNetwork: true containers: - name: masakari-introspective-instance-monitor {{ tuple $envAll "masakari_introspective_instance_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_introspective_instance_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_introspective_instance_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName command: - /tmp/masakari-introspective-instance-monitor.sh - start lifecycle: preStop: exec: command: - /tmp/masakari-introspective-instance-monitor.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.masakari.oslo_concurrency.lock_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-introspective-instance-monitor.sh subPath: masakari-introspective-instance-monitor.sh - name: masakari-etc mountPath: /etc/masakari/masakarimonitors.conf subPath: masakarimonitors.conf - name: masakari-etc mountPath: /etc/sudoers.d/masakari_sudoers subPath: masakari_sudoers - name: masakarietc mountPath: /etc/masakari - name: varrun mountPath: /var/run - name: run mountPath: /run - name: shm mountPath: /dev/shm volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-shared emptyDir: {} - name: masakarietc emptyDir: {} - name: shm hostPath: path: /dev/shm - name: varrun hostPath: path: /var/run - name: run hostPath: path: /run - name: masakari-bin configMap: name: masakari-bin defaultMode: 0555 - name: masakari-etc secret: secretName: masakari-etc defaultMode: 0444 {{- end }} ================================================ FILE: masakari/templates/daemonset-process-monitor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.process_monitor }} {{- $envAll := . }} {{- $daemonset := "masakari-process-monitor" }} {{- $mounts_masakari_process_monitor := .Values.pod.mounts.masakari_process_monitor.masakari_process_monitor }} {{- $mounts_masakari_process_monitor_init := .Values.pod.mounts.masakari_process_monitor.init_container }} {{- $serviceAccountName := "masakari-process-monitor" }} {{- tuple $envAll "masakari_process_monitor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: masakari-process-monitor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{- dict "envAll" $envAll "podName" "masakari-process-monitor" "containerNames" (list "masakari-monitor") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "masakari_process_monitor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "masakari-process-monitor" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.monitors.node_selector_key }}: {{ .Values.labels.monitors.node_selector_value }} initContainers: {{ tuple $envAll "masakari_process_monitor" $mounts_masakari_process_monitor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: procressemonitor-init {{ tuple $envAll "masakari_instance_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_instance_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_process_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-monitors-init.sh env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-monitors-init.sh subPath: masakari-monitors-init.sh readOnly: true containers: - name: masakari-process-monitor {{ tuple $envAll "masakari_process_monitor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_process_monitor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_process_monitor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-process-monitor.sh - start env: - name: COMPUTE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName lifecycle: preStop: exec: command: - /tmp/masakari-process-monitor.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.masakari.oslo_concurrency.lock_path }} - name: etcmasakari mountPath: /etc/masakari - name: pod-shared mountPath: /tmp/pod-shared - name: masakari-bin mountPath: /tmp/masakari-process-monitor.sh subPath: masakari-process-monitor.sh - name: masakari-etc mountPath: /etc/masakari/masakarimonitors.conf subPath: masakarimonitors.conf - name: varrun mountPath: /var/run - name: run mountPath: /run volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: etcmasakari emptyDir: {} - name: pod-shared emptyDir: {} - name: varrun hostPath: path: /var/run - name: run hostPath: path: /run - name: masakari-bin configMap: name: masakari-bin defaultMode: 0555 - name: masakari-etc secret: secretName: masakari-etc defaultMode: 0444 {{- end }} ================================================ FILE: masakari/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "masakariApiLivenessProbeTemplate" }} httpGet: scheme: {{ tuple "instance_ha" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "instance_ha" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "masakariApiReadinessProbeTemplate" }} httpGet: scheme: HTTP path: / port: {{ tuple "instance_ha" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_masakari_api := .Values.pod.mounts.masakari_api.masakari_api }} {{- $mounts_masakari_api_init := .Values.pod.mounts.masakari_api.init_container }} {{- $serviceAccountName := "masakari-api" }} {{- tuple $envAll "masakari_api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: masakari-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "masakari" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.masakari_api }} selector: matchLabels: {{ tuple $envAll "masakari" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "masakari" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "masakari_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "masakari-api" "containerNames" (list "masakari-api-init" "masakari-api" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "masakari" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "masakari" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.masakari.node_selector_key }}: {{ .Values.labels.masakari.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.masakari_api.timeout | default "30" }} initContainers: {{ tuple $envAll "masakari_api" $mounts_masakari_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: masakari-api {{ tuple $envAll "masakari_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-api.sh - start lifecycle: preStop: exec: command: - /tmp/masakari-api.sh - stop ports: - name: n-api containerPort: {{ tuple "instance_ha" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "masakari" "container" "default" "type" "liveness" "probeTemplate" (include "masakariApiLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "masakari" "container" "default" "type" "readiness" "probeTemplate" (include "masakariApiReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.masakari.oslo_concurrency.lock_path }} - name: masakari-bin mountPath: /tmp/masakari-api.sh subPath: masakari-api.sh - name: etcmasakari mountPath: /etc/masakari - name: masakari-etc mountPath: /etc/masakari/masakari.conf subPath: masakari.conf - name: masakari-etc mountPath: /etc/masakari/api-paste.ini subPath: api-paste.ini volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: etcmasakari emptyDir: {} - name: masakari-bin configMap: name: masakari-bin defaultMode: 0555 - name: masakari-etc secret: secretName: masakari-etc defaultMode: 0444 {{- end }} ================================================ FILE: masakari/templates/deployment-engine.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_engine }} {{- $envAll := . }} {{- $mounts_masakari_engine := .Values.pod.mounts.masakari_engine.masakari_engine }} {{- $mounts_masakari_engine_init := .Values.pod.mounts.masakari_engine.init_container }} {{- $serviceAccountName := "masakari-engine" }} {{- tuple $envAll "masakari_engine" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: masakari-engine annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "masakari" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.masakari_engine }} selector: matchLabels: {{ tuple $envAll "masakari" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "masakari" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "masakari_engine" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "masakari-engine" "containerNames" (list "masakari-engine-init" "masakari-engine" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "masakari-engine" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "masakari" "engine" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.masakari.node_selector_key }}: {{ .Values.labels.masakari.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.masakari_engine.timeout | default "30" }} initContainers: {{ tuple $envAll "masakari_engine" $mounts_masakari_engine_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: masakari-engine {{ tuple $envAll "masakari_engine" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.masakari_engine | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_engine" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/masakari-engine.sh - start lifecycle: preStop: exec: command: - /tmp/masakari-engine.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.masakari.oslo_concurrency.lock_path }} - name: masakari-bin mountPath: /tmp/masakari-engine.sh subPath: masakari-engine.sh readOnly: true - name: etcmasakari mountPath: /etc/masakari - name: masakari-etc mountPath: /etc/masakari/masakari.conf subPath: masakari.conf {{ if $mounts_masakari_engine.volumeMounts }}{{ toYaml $mounts_masakari_engine.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: etcmasakari emptyDir: {} - name: masakari-bin configMap: name: masakari-bin defaultMode: 0555 - name: masakari-etc secret: secretName: masakari-etc defaultMode: 0444 {{ if $mounts_masakari_engine.volumes}}{{ toYaml $mounts_masakari_engine.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: masakari/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: masakari/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbToDrop := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.masakari -}} {{- $dbDropJob := dict "envAll" . "serviceName" "masakari" "dbToDrop" $dbToDrop -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: masakari/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "masakari" -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml ) }} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: masakari/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_sync }} {{- $envAll := . }} {{- $serviceAccountName := "masakari-db-sync" }} {{ tuple $envAll "db_sync" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: masakari-db-sync annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} "helm.sh/hook": "post-install,post-upgrade" "helm.sh/hook-weight": "-4" spec: template: metadata: labels: {{ tuple $envAll "masakari" "db-migrate" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "db_migrate" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: masakari-db-sync {{ tuple $envAll "db_sync" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "masakari" "container" "masakari_db_migrate" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/manage-db.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: masakari-bin mountPath: /tmp/manage-db.sh subPath: manage-db.sh - name: etcmasakari mountPath: /etc/masakari - name: masakari-etc mountPath: /etc/masakari/masakari.conf subPath: masakari.conf volumes: - name: pod-tmp emptyDir: {} - name: etcmasakari emptyDir: {} - name: masakari-etc secret: secretName: masakari-etc defaultMode: 0444 - name: masakari-bin configMap: name: masakari-bin defaultMode: 0555 {{- end }} ================================================ FILE: masakari/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "masakari" "serviceTypes" ( tuple "instance-ha" ) -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml ) }} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: masakari/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "masakari" "serviceTypes" ( tuple "instance-ha" ) -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml ) }} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: masakari/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "masakari" -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml ) }} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: masakari/templates/job-rabbitmq-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "masakari" -}} {{- $_ := set $rmqUserJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: masakari/templates/pbd-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: masakari-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.masakari_api.min_available }} selector: matchLabels: {{ tuple $envAll "masakari" "masakari_api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: masakari/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "masakari" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: masakari/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "masakari" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: masakari/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "masakari" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} TRANSPORT_URL: {{ tuple "oslo_messaging" "internal" $userClass "amqp" $envAll | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: masakari/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: masakari/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "instance_ha" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: n-api port: {{ tuple "instance_ha" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.masakari_api.node_port.enabled }} nodePort: {{ .Values.network.masakari_api.node_port.port }} {{ end }} selector: {{ tuple $envAll "masakari" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.masakari_api.node_port.enabled }} type: NodePort {{ if .Values.network.masakari_api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: masakari/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_sync: quay.io/airshipit/masakari:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble masakari_api: quay.io/airshipit/masakari:2025.1-ubuntu_noble masakari_engine: quay.io/airshipit/masakari:2025.1-ubuntu_noble masakari_host_monitor: quay.io/airshipit/masakari-monitors:2025.1-ubuntu_noble masakari_process_monitor: quay.io/airshipit/masakari-monitors:2025.1-ubuntu_noble masakari_instance_monitor: quay.io/airshipit/masakari-monitors:2025.1-ubuntu_noble masakari_introspective_instance_monitor: quay.io/airshipit/masakari-monitors:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: masakari: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled monitors: node_selector_key: openstack-compute-node node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false masakari: username: masakari password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null instance_ha: name: masakari hosts: default: masakari-api public: masakari-api host_fqdn_override: default: null path: default: "/v1/%(tenant_id)s" scheme: default: "http" port: api: default: 15868 public: 80 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct masakari: username: masakari password: password hosts: default: mariadb host_fqdn_override: default: null path: /masakari scheme: mysql+pymysql port: mysql: default: 3306 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default masakari: role: admin region_name: RegionOne username: masakari password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: neutron-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct masakari: username: masakari password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /masakari scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: "http" port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 secrets: identity: admin: masakari-keystone-admin masakari: masakari-keystone-user test: masakari-keystone-test oslo_db: admin: masakari-db-admin masakari: masakari-db-user oslo_messaging: admin: masakari-rabbitmq-admin masakari: masakari-rabbitmq-user oci_image_registry: masakari: masakari-oci-image-registry dependencies: static: masakari_api: jobs: - masakari-db-sync - masakari-ks-user - masakari-ks-endpoints - masakari-ks-service services: - endpoint: internal service: identity masakari_engine: jobs: - masakari-db-sync - masakari-ks-user - masakari-ks-endpoints - masakari-ks-service services: - endpoint: internal service: identity db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - masakari-db-init services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - masakari-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity pod: security_context: masakari: pod: runAsUser: 42424 container: masakari_api: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 42424 masakari_engine: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 42424 masakari_db_sync: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 42424 masakari_host_monitor: readOnlyRootFilesystem: false allowPrivilegeEscalation: true runAsUser: 42424 masakari_process_monitir: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 42424 masakari_instance_monitor: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 0 masakari_introspective_instance_monitor: readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsUser: 0 test: pod: runAsUser: 42424 container: horizon_test: readOnlyRootFilesystem: true allowPrivilegeEscalation: false probes: rpc_timeout: 60 rpc_retries: 2 masakari: default: liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 90 timeoutSeconds: 70 readiness: enabled: true params: initialDelaySeconds: 80 periodSeconds: 90 timeoutSeconds: 70 masakari-engine: default: liveness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: masakari_api: 1 masakari_engine: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 daemonsets: pod_replacement_strategy: RollingUpdate compute: enabled: true min_ready_seconds: 0 max_unavailable: 1 disruption_budget: masakari_api: min_available: 0 masakari_engine: min_available: 0 termination_grace_period: masakari_api: timeout: 30 masakari_engine: timeout: 30 mounts: masakari_api: init_container: null masakari_api: volumeMounts: volumes: masakari_engine: init_container: null masakari_engine: volumeMounts: volumes: masakari_instance_monitor: init_container: null masakari_instance_monitor: volumeMounts: volumes: masakari_host_monitor: init_container: null masakari_host_monitor: volumeMounts: volumes: masakari_process_monitor: init_container: null masakari_process_monitor: volumeMounts: volumes: masakari_introspective_instance_monitor: init_container: null masakari_introspective_instance_monitor: volumeMounts: volumes: masakari_db_sync: masakari_db_sync: volumeMounts: volumes: masakari_db_init: masakari_db_sync: volumeMounts: volumes: masakari_ks_users: masakari_db_sync: volumeMounts: volumes: masakari_ks_service: masakari_db_sync: volumeMounts: volumes: resources: enabled: false masakari_api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" masakari_engine: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" masakari_host_monitor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" masakari_instance_monitor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" masakari_process_monitor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" masakari_introspective_instance_monitor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conf: paste: composite:masakari_api: use: call:masakari.api.urlmap:urlmap_factory /: apiversions /v1: masakari_api_v1 composite:masakari_api_v1: use: call:masakari.api.auth:pipeline_factory_v1 keystone: cors http_proxy_to_wsgi request_id faultwrap sizelimit authtoken keystonecontext osapi_masakari_app_v1 noauth2: cors http_proxy_to_wsgi request_id faultwrap sizelimit noauth2 osapi_masakari_app_v1 filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: masakari filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:faultwrap: paste.filter_factory: masakari.api.openstack:FaultWrapper.factory filter:sizelimit: paste.filter_factory: oslo_middleware:RequestBodySizeLimiter.factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:keystonecontext: paste.filter_factory: masakari.api.auth:MasakariKeystoneContext.factory filter:noauth2: paste.filter_factory: masakari.api.auth:NoAuthMiddleware.factory app:osapi_masakari_app_v1: paste.app_factory: masakari.api.openstack.ha:APIRouterV1.factory pipeline:apiversions: pipeline: faultwrap http_proxy_to_wsgi apiversionsapp app:apiversionsapp: paste.app_factory: masakari.api.openstack.ha.versions:Versions.factory masakari: DEFAULT: auth_strategy: keystone duplicate_notification_detection_interval: 180 host_failure_recovery_threads: 1 masakari_api_workers: 1 graceful_shutdown_timeout: 5 keystone_authtoken: auth_type: password service_type: instance-ha database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" oslo_concurrency: lock_path: /var/lock # Connection string is evaluated though the endpoints for taskflow. taskflow: # -- Taskflow persistence connection URI. When empty the URI is ## auto-generated from endpoints.oslo_db. Set to null to disable ## auto-generation. connection: "" wsgi: api_paste_config: /etc/masakari/api-paste.ini masakarimonitors: DEFAULT: debug: False api: api_version: v1 api_interface: internal callback: retry_max: 10 retry_interval: 10 introspectiveinstancemonitor: guest_monitor_interval: 10 guest_monitor_timeout: 5 host: monitoring_driver: default monitoring_interval: 120 monitoring_samples: 1 disable_ipmi_checks: true corosync_multicast_ports: 5405 pacemaker_node_type: remote masakari_sudoers: | Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin" masakari-monitors ALL=(ALL:ALL) NOPASSWD: /var/lib/openstack/bin/privsep-helper network: masakari_api: node_port: enabled: false port: 33033 external_policy_local: false manifests: job_ks_user: true job_db_sync: true job_db_init: true job_db_drop: false job_ks_endpoints: true job_ks_service: true deployment_api: true deployment_engine: true configmap_bin: true configmap_etc: true secret_db: true secret_rabbitmq: true secret_keystone: true secret_registry: true job_rabbit_init: true service_api: true pdb_api: true # Host Monitors in containers needs pacemaker remote. host_monitor: false instance_monitor: false process_monitor: false introspective_instance_monitor: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: memcached/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.5.5 description: OpenStack-Helm Memcached name: memcached version: 2025.2.0 home: https://github.com/memcached/memcached dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: memcached/templates/bin/_memcached.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex memcached --version exec memcached -v \ -p ${MEMCACHED_PORT} \ -U 0 \ {{- if not .Values.conf.memcached.stats_cachedump.enabled }} -X \ {{- end }} -c ${MEMCACHED_MAX_CONNECTIONS} \ -m ${MEMCACHED_MEMORY} ================================================ FILE: memcached/templates/configmap-apparmor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- dict "envAll" . "component" "memcached" | include "helm-toolkit.snippets.kubernetes_apparmor_configmap" }} ================================================ FILE: memcached/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $configMapBinName := printf "%s-%s" $envAll.deployment_name "memcached-bin" }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapBinName }} data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} memcached.sh: | {{ tuple "bin/_memcached.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: memcached/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: memcached/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "memcached" -}} {{- if .Values.pod.tolerations.memcached.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: memcached/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "memcached" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: memcached/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: memcached/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "oslo_cache" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: sessionAffinity: ClientIP ports: - name: memcache port: {{ tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- with .Values.memcached.extraServicePorts }} {{- tpl (toYaml .) $ | nindent 4 }} {{- end }} selector: {{ tuple $envAll "memcached" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ .Values.network.memcached | include "helm-toolkit.snippets.service_params" | indent 2 }} {{- end }} ================================================ FILE: memcached/templates/statefulset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- define "memcachedProbeTemplate" }} tcpSocket: port: {{ tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.statefulset }} {{- $envAll := . }} {{- $rcControllerName := printf "%s-%s" $envAll.deployment_name "memcached" }} {{- $configMapBinName := printf "%s-%s" $envAll.deployment_name "memcached-bin" }} {{ tuple $envAll "memcached" $rcControllerName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ $rcControllerName | quote }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "memcached" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: podManagementPolicy: Parallel replicas: {{ .Values.pod.replicas.server }} serviceName: "{{ tuple "oslo_cache" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}" selector: matchLabels: {{ tuple $envAll "memcached" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: annotations: {{ dict "envAll" $envAll "podName" "memcached" "containerNames" (list "init" "memcached") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} labels: {{ tuple $envAll "memcached" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "server" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} shareProcessNamespace: true serviceAccountName: {{ $rcControllerName | quote }} affinity: {{ tuple $envAll "memcached" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value | quote }} {{ if $envAll.Values.pod.tolerations.memcached.enabled }} {{ tuple $envAll "memcached" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.memcached.timeout | default "30" }} initContainers: {{ tuple $envAll "memcached" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{ dict "envAll" $envAll | include "helm-toolkit.snippets.kubernetes_apparmor_loader_init_container" | indent 8 }} containers: - name: memcached {{ tuple $envAll "memcached" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "memcached" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: MEMCACHED_PORT value: {{ tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: MEMCACHED_MAX_CONNECTIONS value: {{ .Values.conf.memcached.max_connections | quote }} - name: MEMCACHED_MEMORY value: {{ .Values.conf.memcached.memory | quote }} command: - /tmp/memcached.sh ports: - containerPort: {{ tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "memcached" "container" "memcached" "type" "readiness" "probeTemplate" (include "memcachedProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "memcached" "container" "memcached" "type" "liveness" "probeTemplate" (include "memcachedProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: memcached-bin mountPath: /tmp/memcached.sh subPath: memcached.sh readOnly: true {{- with .Values.memcached.extraContainers }} {{- tpl (toYaml .) $ | nindent 8 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: memcached-bin configMap: name: {{ $configMapBinName | quote }} defaultMode: 360 {{ dict "envAll" $envAll "component" "memcached" "requireSys" true | include "helm-toolkit.snippets.kubernetes_apparmor_volumes" | indent 8 }} {{- end }} ================================================ FILE: memcached/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for memcached. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- conf: memcached: max_connections: 8192 # NOTE(pordirect): this should match the value in # `pod.resources.memcached.memory` memory: 1024 stats_cachedump: enabled: true dependencies: dynamic: common: local_image_registry: jobs: - memcached-image-repo-sync services: - endpoint: node service: local_image_registry static: memcached: jobs: null image_repo_sync: services: - endpoint: internal service: local_image_registry secrets: oci_image_registry: memcached: memcached-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false memcached: username: memcached password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null oslo_cache: namespace: null host_fqdn_override: default: null hosts: default: memcached port: memcache: default: 11211 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns_tcp: default: 53 dns: default: 53 protocol: UDP network: memcached: {} network_policy: memcached: ingress: - {} egress: - {} images: pull_policy: IfNotPresent tags: dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' memcached: 'quay.io/airshipit/memcached:1.6.32' image_repo_sync: quay.io/airshipit/docker:27.5.0 local_registry: active: false exclude: - dep_check - image_repo_sync labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled manifests: configmap_bin: true statefulset: true job_image_repo_sync: true network_policy: false service: true secret_registry: true memcached: extraContainers: [] extraServicePorts: [] pod: security_context: server: pod: runAsUser: 65534 runAsNonRoot: true fsGroup: 65534 container: memcached: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL probes: memcached: memcached: readiness: enabled: True params: initialDelaySeconds: 0 periodSeconds: 10 timeoutSeconds: 5 liveness: enabled: True params: initialDelaySeconds: 10 periodSeconds: 15 timeoutSeconds: 10 affinity: anti: topologyKey: default: kubernetes.io/hostname type: default: requiredDuringSchedulingIgnoredDuringExecution weight: default: 10 tolerations: memcached: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule lifecycle: upgrades: deployments: pod_replacement_strategy: RollingUpdate revision_history: 3 rolling_update: max_unavailable: 1 termination_grace_period: memcached: timeout: 30 replicas: server: 1 resources: enabled: false memcached: limits: cpu: "2000m" memory: "1024Mi" requests: cpu: "500m" memory: "128Mi" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: mistral/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Mistral name: mistral version: 2025.2.0 home: https://docs.openstack.org/mistral/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Mistral/OpenStack_Project_Mistral_vertical.png sources: - https://opendev.org/openstack/mistral - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: mistral/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: mistral/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex mistral-db-manage --config-file /etc/mistral/mistral.conf upgrade head mistral-db-manage --config-file /etc/mistral/mistral.conf populate ================================================ FILE: mistral/templates/bin/_mistral-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec mistral-server \ --server api \ --config-file /etc/mistral/mistral.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: mistral/templates/bin/_mistral-engine.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec mistral-server \ --server engine \ --config-file /etc/mistral/mistral.conf ================================================ FILE: mistral/templates/bin/_mistral-event-engine.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec mistral-server \ --server event-engine \ --config-file /etc/mistral/mistral.conf ================================================ FILE: mistral/templates/bin/_mistral-executor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec mistral-server \ --server executor \ --config-file /etc/mistral/mistral.conf ================================================ FILE: mistral/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: mistral-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} mistral-api.sh: | {{ tuple "bin/_mistral-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mistral-engine.sh: | {{ tuple "bin/_mistral-engine.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mistral-event-engine.sh: | {{ tuple "bin/_mistral-event-engine.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mistral-executor.sh: | {{ tuple "bin/_mistral-executor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: mistral/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.mistral.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.mistral.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.mistral.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.mistral.keystone_authtoken "region_name" .Values.endpoints.identity.auth.mistral.region_name -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.mistral.keystone_authtoken "project_name" .Values.endpoints.identity.auth.mistral.project_name -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.mistral.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.mistral.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.mistral.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.mistral.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.username -}} {{- $_ := set .Values.conf.mistral.keystone_authtoken "username" .Values.endpoints.identity.auth.mistral.username -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.password -}} {{- $_ := set .Values.conf.mistral.keystone_authtoken "password" .Values.endpoints.identity.auth.mistral.password -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.mistral.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.mistral.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.mistral.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.mistral.database.connection)) (empty .Values.conf.mistral.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "mistral" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set .Values.conf.mistral.database "connection" -}} {{- end -}} {{- if empty .Values.conf.mistral.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "mistral" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.mistral.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.mistral.api.port -}} {{- $_ := tuple "workflowv2" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.mistral.api "port" -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: mistral-etc type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} mistral.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.mistral | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} {{ printf "test_template_%d" $key }}: {{ $value.template | b64enc }} {{- end }} {{- end }} ================================================ FILE: mistral/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_mistral_api := .Values.pod.mounts.mistral_api.mistral_api }} {{- $mounts_mistral_api_init := .Values.pod.mounts.mistral_api.init_container }} {{- $serviceAccountName := "mistral-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: mistral-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "mistral" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "mistral" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "mistral" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "mistral_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "mistral" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_mistral_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: mistral-api {{ tuple $envAll "mistral_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: {{ .Values.pod.user.mistral.uid }} command: - /tmp/mistral-api.sh - start lifecycle: preStop: exec: command: - /tmp/mistral-api.sh - stop ports: - name: w-api containerPort: {{ tuple "workflowv2" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: {{ tuple "workflowv2" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "workflowv2" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.mistral.oslo_concurrency.lock_path }} - name: pod-etc-mistral mountPath: /etc/mistral - name: mistral-bin mountPath: /tmp/mistral-api.sh subPath: mistral-api.sh readOnly: true - name: mistral-etc mountPath: /etc/mistral/mistral.conf subPath: mistral.conf readOnly: true {{- if .Values.conf.mistral.DEFAULT.log_config_append }} - name: mistral-etc mountPath: {{ .Values.conf.mistral.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.mistral.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: mistral-etc mountPath: /etc/mistral/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_mistral_api.volumeMounts }}{{ toYaml $mounts_mistral_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-mistral emptyDir: {} - name: mistral-bin configMap: name: mistral-bin defaultMode: 0555 - name: mistral-etc secret: secretName: mistral-etc defaultMode: 0444 {{ if $mounts_mistral_api.volumes }}{{ toYaml $mounts_mistral_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: mistral/templates/deployment-executor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_executor }} {{- $envAll := . }} {{- $mounts_mistral_executor := .Values.pod.mounts.mistral_executor.mistral_executor }} {{- $mounts_mistral_executor_init := .Values.pod.mounts.mistral_executor.init_container }} {{- $serviceAccountName := "mistral-executor" }} {{ tuple $envAll "executor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: mistral-executor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "mistral" "executor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.executor }} selector: matchLabels: {{ tuple $envAll "mistral" "executor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "mistral" "executor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "mistral_executor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "mistral" "executor" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.executor.node_selector_key }}: {{ .Values.labels.executor.node_selector_value }} initContainers: {{ tuple $envAll "executor" $mounts_mistral_executor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: mistral-executor {{ tuple $envAll "mistral_executor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.executor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: {{ .Values.pod.user.mistral.uid }} command: - /tmp/mistral-executor.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.mistral.oslo_concurrency.lock_path }} - name: pod-etc-mistral mountPath: /etc/mistral - name: mistral-bin mountPath: /tmp/mistral-executor.sh subPath: mistral-executor.sh readOnly: true - name: mistral-etc mountPath: /etc/mistral/mistral.conf subPath: mistral.conf readOnly: true {{- if .Values.conf.mistral.DEFAULT.log_config_append }} - name: mistral-etc mountPath: {{ .Values.conf.mistral.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.mistral.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_mistral_executor.volumeMounts }}{{ toYaml $mounts_mistral_executor.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-mistral emptyDir: {} - name: mistral-bin configMap: name: mistral-bin defaultMode: 0555 - name: mistral-etc secret: secretName: mistral-etc defaultMode: 0444 {{ if $mounts_mistral_executor.volumes }}{{ toYaml $mounts_mistral_executor.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: mistral/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: mistral/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "workflowv2" "backendPort" "w-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: mistral/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.bootstrap" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "5" {{- end }} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "mistral" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.mistral.DEFAULT.log_config_append "jobAnnotations" (include "metadata.annotations.job.bootstrap" . | fromYaml) -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: mistral/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "mistral" -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: mistral/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "mistral" "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: mistral/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "mistral" "podVolMounts" .Values.pod.mounts.mistral_db_sync.mistral_db_sync.volumeMounts "podVols" .Values.pod.mounts.mistral_db_sync.mistral_db_sync.volumes "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: mistral/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "mistral" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: mistral/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "mistral" "serviceTypes" ( tuple "workflowv2" ) "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: mistral/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "mistral" "serviceTypes" ( tuple "workflowv2" ) "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: mistral/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "mistral" "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: mistral/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "mistral" "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: mistral/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "mistral" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: mistral/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: mistral-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "mistral" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: mistral/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.mistral_tests.mistral_tests }} {{- $mounts_tests_init := .Values.pod.mounts.mistral_tests.init_container }} {{- $serviceAccountName := print $envAll.Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.Release.Name "-test" }} labels: {{ tuple $envAll "mistral" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: {{ .Release.Name }}-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: mistral-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: {{ .Release.Name }}-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.Release.Name}} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: mistral-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: mistral-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} - name: mistral-etc mountPath: {{ $value.name }} subPath: {{ printf "test_template_%d" $key }} readOnly: true {{- end }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: mistral-etc secret: secretName: mistral-etc defaultMode: 0444 - name: mistral-bin configMap: name: mistral-bin defaultMode: 0555 - name: rally-db emptyDir: {} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: mistral/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "mistral" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: DB_CONNECTION: {{ tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc -}} {{- end }} {{- end }} ================================================ FILE: mistral/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "mistral" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: mistral/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "mistral" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: mistral/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: mistral/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "workflowv2" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: w-api port: {{ tuple "workflowv2" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "mistral" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: mistral/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "workflowv2" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: mistral/templates/statefulset-engine.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset_engine }} {{- $envAll := . }} {{- $mounts_mistral_engine := .Values.pod.mounts.mistral_engine.mistral_engine }} {{- $mounts_mistral_engine_init := .Values.pod.mounts.mistral_engine.init_container }} {{- $serviceAccountName := "mistral-engine" }} {{ tuple $envAll "engine" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mistral-engine annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "mistral" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: mistral-engine replicas: {{ .Values.pod.replicas.engine }} selector: matchLabels: {{ tuple $envAll "mistral" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "mistral" "engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "mistral" "engine" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.engine.node_selector_key }}: {{ .Values.labels.engine.node_selector_value }} initContainers: {{ tuple $envAll "engine" $mounts_mistral_engine_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: mistral-engine {{ tuple $envAll "mistral_engine" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.engine | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: {{ .Values.pod.user.mistral.uid }} command: - /tmp/mistral-engine.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.mistral.oslo_concurrency.lock_path }} - name: pod-etc-mistral mountPath: /etc/mistral - name: mistral-bin mountPath: /tmp/mistral-engine.sh subPath: mistral-engine.sh readOnly: true - name: mistral-etc mountPath: /etc/mistral/mistral.conf subPath: mistral.conf readOnly: true {{- if .Values.conf.mistral.DEFAULT.log_config_append }} - name: mistral-etc mountPath: {{ .Values.conf.mistral.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.mistral.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_mistral_engine.volumeMounts }}{{ toYaml $mounts_mistral_engine.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-mistral emptyDir: {} - name: mistral-bin configMap: name: mistral-bin defaultMode: 0555 - name: mistral-etc secret: secretName: mistral-etc defaultMode: 0444 {{ if $mounts_mistral_engine.volumes }}{{ toYaml $mounts_mistral_engine.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: mistral/templates/statefulset-event-engine.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset_event_engine }} {{- $envAll := . }} {{- $mounts_mistral_event_engine := .Values.pod.mounts.mistral_event_engine.mistral_event_engine }} {{- $mounts_mistral_event_engine_init := .Values.pod.mounts.mistral_event_engine.init_container }} {{- $serviceAccountName := "mistral-event-engine" }} {{ tuple $envAll "event_engine" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: mistral-event-engine annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "mistral" "event-engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: mistral-event-engine replicas: {{ .Values.pod.replicas.event_engine }} selector: matchLabels: {{ tuple $envAll "mistral" "event-engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "mistral" "event-engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "mistral" "event-engine" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.event_engine.node_selector_key }}: {{ .Values.labels.event_engine.node_selector_value }} initContainers: {{ tuple $envAll "event_engine" $mounts_mistral_event_engine_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: mistral-event-engine {{ tuple $envAll "mistral_event_engine" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.event_engine | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: {{ .Values.pod.user.mistral.uid }} command: - /tmp/mistral-event-engine.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.mistral.oslo_concurrency.lock_path }} - name: pod-etc-mistral mountPath: /etc/mistral - name: mistral-bin mountPath: /tmp/mistral-event-engine.sh subPath: mistral-event-engine.sh readOnly: true - name: mistral-etc mountPath: /etc/mistral/mistral.conf subPath: mistral.conf readOnly: true {{- if .Values.conf.mistral.DEFAULT.log_config_append }} - name: mistral-etc mountPath: {{ .Values.conf.mistral.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.mistral.DEFAULT.log_config_append }} readOnly: true {{- end }} {{ if $mounts_mistral_event_engine.volumeMounts }}{{ toYaml $mounts_mistral_event_engine.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-mistral emptyDir: {} - name: mistral-bin configMap: name: mistral-bin defaultMode: 0555 - name: mistral-etc secret: secretName: mistral-etc defaultMode: 0444 {{ if $mounts_mistral_event_engine.volumes }}{{ toYaml $mounts_mistral_event_engine.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: mistral/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for mistral. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled engine: node_selector_key: openstack-control-plane node_selector_value: enabled event_engine: node_selector_key: openstack-control-plane node_selector_value: enabled executor: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble mistral_db_sync: quay.io/airshipit/mistral:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble mistral_api: quay.io/airshipit/mistral:2025.1-ubuntu_noble mistral_engine: quay.io/airshipit/mistral:2025.1-ubuntu_noble mistral_event_engine: quay.io/airshipit/mistral:2025.1-ubuntu_noble mistral_executor: quay.io/airshipit/mistral:2025.1-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 28989 bootstrap: enabled: false ks_user: mistral script: | openstack token issue dependencies: dynamic: common: local_image_registry: jobs: - mistral-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - mistral-db-sync - mistral-ks-user - mistral-ks-endpoints - mistral-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - mistral-db-init services: - endpoint: internal service: oslo_db engine: jobs: - mistral-db-sync - mistral-ks-user - mistral-ks-endpoints - mistral-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity event_engine: jobs: - mistral-db-sync - mistral-ks-user - mistral-ks-endpoints - mistral-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity executor: jobs: - mistral-db-sync - mistral-ks-user - mistral-ks-endpoints - mistral-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity ks_endpoints: jobs: - mistral-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - service: oslo_messaging endpoint: internal tests: services: - endpoint: internal service: identity - endpoint: internal service: workflowv2 image_repo_sync: services: - endpoint: internal service: local_image_registry # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: mistral-keystone-admin mistral: mistral-keystone-user test: mistral-keystone-test oslo_db: admin: mistral-db-admin mistral: mistral-db-user oslo_messaging: admin: mistral-rabbitmq-admin mistral: mistral-rabbitmq-user oci_image_registry: mistral: mistral-oci-image-registry # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false mistral: username: mistral password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default mistral: role: admin region_name: RegionOne username: mistral password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: mistral-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 workflowv2: name: mistral hosts: default: mistral-api public: mistral host_fqdn_override: default: null path: default: /v2 scheme: default: 'http' port: api: default: 8989 public: 80 oslo_db: auth: admin: username: root password: password mistral: username: mistral password: password hosts: default: mariadb host_fqdn_override: default: null path: /mistral scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password mistral: username: mistral password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /mistral scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 conf: rally_tests: run_tempest: false tests: MistralWorkbooks.create_workbook: - args: definition: /tmp/rally-jobs/mistral_wb.yaml do_delete: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 MistralExecutions.create_execution_from_workbook: - args: definition: /tmp/rally-jobs/mistral_wb.yaml do_delete: true params: /tmp/rally-jobs/mistral_params.json wf_input: /tmp/rally-jobs/mistral_input.json workflow_name: wf1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 MistralWorkbooks.list_workbooks: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 MistralExecutions.list_executions: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 templates: - name: /tmp/rally-jobs/mistral_wb.yaml template: | version: "2.0" name: wb workflows: wf1: type: direct input: - input1: input1 - some_json_input: {} tasks: hello: action: std.echo output="Hello" publish: result: $ - name: /tmp/rally-jobs/mistral_input.json template: | {"input1": "value1", "some_json_input": {"a": "b"}} - name: /tmp/rally-jobs/mistral_params.json template: | {"env": {"env_param": "env_param_value"}} policy: {} mistral: DEFAULT: log_config_append: /etc/mistral/logging.conf transport_url: null api: # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. port: null api_workers: 8 coordination: backend_url: "" database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT oslo_policy: policy_file: /etc/mistral/policy.yaml oslo_concurrency: lock_path: /var/lock logging: loggers: keys: - root - mistral handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_mistral: level: INFO handlers: - stdout qualname: mistral logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" pod: user: mistral: uid: 1000 affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: mistral_api: init_container: null mistral_api: volumeMounts: volumes: mistral_executor: init_container: null mistral_executor: volumeMounts: volumes: mistral_engine: init_container: null mistral_engine: volumeMounts: volumes: mistral_event_engine: init_container: null mistral_event_engine: volumeMounts: volumes: mistral_bootstrap: init_container: null mistral_bootstrap: volumeMounts: volumes: mistral_tests: init_container: null mistral_tests: volumeMounts: volumes: mistral_db_sync: mistral_db_sync: volumeMounts: volumes: replicas: api: 1 engine: 1 event_engine: 1 executor: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" engine: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" event_engine: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" executor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network_policy: mistral: ingress: - {} egress: - {} manifests: configmap_bin: true configmap_etc: true deployment_api: true deployment_executor: true ingress_api: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pdb_api: true pod_rally_test: true network_policy: false secret_db: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_ingress_api: true service_api: true statefulset_engine: true statefulset_event_engine: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: nagios/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Nagios name: nagios version: 2025.2.0 home: https://www.nagios.org sources: - https://opendev.org/openstack/openstack-helm-addons maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: nagios/templates/bin/_apache.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ev COMMAND="${@:-start}" function start () { if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/httpd/apache2/envvars fi # Apache gets grumpy about PID files pre-existing rm -f /etc/httpd/logs/httpd.pid if [ -f /usr/local/apache2/conf/.htpasswd ]; then htpasswd -b /usr/local/apache2/conf/.htpasswd "$NAGIOSADMIN_USER" "$NAGIOSADMIN_PASS" else htpasswd -cb /usr/local/apache2/conf/.htpasswd "$NAGIOSADMIN_USER" "$NAGIOSADMIN_PASS" fi #Launch Apache on Foreground exec httpd -DFOREGROUND } function stop () { apachectl -k graceful-stop } $COMMAND ================================================ FILE: nagios/templates/bin/_nagios-readiness.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # NOTE(sw5822): Redirect no-op operator output to Nagios log file to clean out # Nagios's log file, since Nagios doesn't support logging to /dev/null : > /opt/nagios/var/log/nagios.log # Check whether Nagios endpoint is reachable reply=$(curl -s -o /dev/null -w %{http_code} http://127.0.0.1:8000/nagios) if [ \"$reply\" -lt 200 -o \"$reply\" -ge 400 ]; then exit 1 fi ================================================ FILE: nagios/templates/bin/_selenium-tests.py.tpl ================================================ #!/usr/bin/env python3 {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} import os import logging import sys from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options {{- if .Values.selenium_v4 }} from selenium.webdriver.chrome.service import Service {{- end }} from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import ScreenshotException # Create logger, console handler and formatter logger = logging.getLogger('Nagios Selenium Tests') logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) def get_variable(env_var): if env_var in os.environ: logger.info('Found "{}"'.format(env_var)) return os.environ[env_var] else: logger.critical('Variable "{}" is not defined!'.format(env_var)) sys.exit(1) def click_link_by_name(link_name): try: logger.info("Clicking '{}' link".format(link_name)) {{- if .Values.selenium_v4 }} link = browser.find_element(By.LINK_TEXT, link_name) {{- else }} link = browser.find_element_by_link_text(link_name) {{- end }} link.click() except NoSuchElementException: logger.error("Failed clicking '{}' link".format(link_name)) browser.quit() sys.exit(1) def take_screenshot(page_name, artifacts_dir='/tmp/artifacts/'): # nosec file_name = page_name.replace(' ', '_') try: el = WebDriverWait(browser, 15) browser.save_screenshot('{}{}.png'.format(artifacts_dir, file_name)) logger.info("Successfully captured {} screenshot".format(page_name)) except ScreenshotException: logger.error("Failed to capture {} screenshot".format(page_name)) browser.quit() sys.exit(1) username = get_variable('NAGIOS_USER') password = get_variable('NAGIOS_PASSWORD') nagios_uri = get_variable('NAGIOS_URI') nagios_url = 'http://{0}:{1}@{2}'.format(username, password, nagios_uri) chrome_driver = '/etc/selenium/chromedriver' options = Options() options.add_argument('--headless=new') options.add_argument('--no-sandbox') options.add_argument('--window-size=1920x1080') {{- if .Values.selenium_v4 }} service = Service(executable_path=chrome_driver) browser = webdriver.Chrome(service=service, options=options) {{- else }} browser = webdriver.Chrome(chrome_driver, chrome_options=options) {{- end }} try: logger.info('Attempting to connect to Nagios') browser.get(nagios_url) el = WebDriverWait(browser, 15).until( EC.title_contains('Nagios') ) logger.info('Connected to Nagios') except TimeoutException: logger.critical('Timed out waiting for Nagios') browser.quit() sys.exit(1) try: logger.info('Switching Focus to Navigation side frame') sideFrame = browser.switch_to.frame('side') except NoSuchElementException: logger.error('Failed selecting side frame') browser.quit() sys.exit(1) try: logger.info('Attempting to visit Services page') click_link_by_name('Services') take_screenshot('Nagios Services') except TimeoutException: logger.error('Failed to load Services page') browser.quit() sys.exit(1) try: logger.info('Attempting to visit Host Groups page') click_link_by_name('Host Groups') take_screenshot('Nagios Host Groups') except TimeoutException: logger.error('Failed to load Host Groups page') browser.quit() sys.exit(1) try: logger.info('Attempting to visit Hosts page') click_link_by_name('Hosts') take_screenshot('Nagios Hosts') except TimeoutException: logger.error('Failed to load Hosts page') browser.quit() sys.exit(1) logger.info("The following screenshots were captured:") for root, dirs, files in os.walk("/tmp/artifacts/"): # nosec for name in files: logger.info(os.path.join(root, name)) browser.quit() ================================================ FILE: nagios/templates/configmap-additional-plugins.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_additional_plugins }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: nagios-additional-plugins type: Opaque data: {{- range .Values.conf.nagios.additionalPlugins }} {{ .name }}: {{ .content | b64enc | quote }} {{- end }} {{- end }} ================================================ FILE: nagios/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: nagios-bin data: apache.sh: | {{ tuple "bin/_apache.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nagios-readiness.sh: | {{ tuple "bin/_nagios-readiness.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} selenium-tests.py: | {{ tuple "bin/_selenium-tests.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: |+ {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: nagios/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: nagios-etc type: Opaque data: {{- if not (empty .Values.conf.nagios.query_es_clauses) }} query_es_clauses.json: {{ .Values.conf.nagios.query_es_clauses | toJson | b64enc }} {{- end }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.nagios.nagios.template "key" "nagios.cfg" "format" "Secret") | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.nagios.cgi.template "key" "cgi.cfg" "format" "Secret") | indent 2 }} {{- range $objectType, $config := $envAll.Values.conf.nagios.objects }} {{- $objectFile := printf "%s.cfg" $objectType -}} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" $config.template "key" $objectFile "format" "Secret") | indent 2 }} {{- end }} # NOTE(portdirect): this must be last, to work round helm ~2.7 bug. {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.httpd "key" "httpd.conf" "format" "Secret") | indent 2 }} {{- end }} ================================================ FILE: nagios/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "apacheProxyReadinessProbeTemplate" }} tcpSocket: port: {{ tuple "nagios" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "nagiosReadinessProbeTemplate" }} exec: command: - /tmp/nagios-readiness.sh {{- end }} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $nagiosUserSecret := .Values.secrets.nagios.admin }} {{- $serviceAccountName := "nagios" }} {{ tuple $envAll "nagios" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - nodes - nodes/proxy - services - endpoints - pods - pods/exec - persistentvolumes - persistentvolumeclaims verbs: - get - list - watch - apiGroups: - "" resources: - configmaps verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: Deployment metadata: name: nagios annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nagios" "monitoring" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.nagios }} selector: matchLabels: {{ tuple $envAll "nagios" "monitoring" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nagios" "monitoring" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "nagios" "containerNames" (list "apache-proxy" "nagios" "init" "define-nagios-hosts") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "monitoring" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "nagios" "monitoring" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.nagios.node_selector_key }}: {{ .Values.labels.nagios.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.nagios.timeout | default "30" }} {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "nagios" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: define-nagios-hosts {{ tuple $envAll "nagios" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.nagios | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "monitoring" "container" "define_nagios_hosts" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /usr/lib/nagios/plugins/define-nagios-hosts.py - --object_file_loc - /opt/nagios/etc/conf.d/nagios-hosts.cfg volumeMounts: - name: pod-tmp mountPath: /tmp - name: nagios-confd mountPath: /opt/nagios/etc/conf.d env: {{- if .Values.pod.env }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env | indent 12 }} {{- end }} containers: - name: apache-proxy {{ tuple $envAll "apache_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.apache_proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "monitoring" "container" "apache_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "monitoring" "container" "apache_proxy" "type" "readiness" "probeTemplate" (include "apacheProxyReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/apache.sh - start ports: - name: http containerPort: {{ tuple "nagios" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: NAGIOSADMIN_USER valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: NAGIOSADMIN_USER - name: NAGIOSADMIN_PASS valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: NAGIOSADMIN_PASS volumeMounts: - name: pod-tmp mountPath: /tmp - name: nagios-bin mountPath: /tmp/apache.sh subPath: apache.sh readOnly: true - name: nagios-etc mountPath: /usr/local/apache2/conf/httpd.conf subPath: httpd.conf readOnly: true - name: nagios {{ tuple $envAll "nagios" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.nagios | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "monitoring" "container" "nagios" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "monitoring" "container" "nagios" "type" "readiness" "probeTemplate" (include "nagiosReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} ports: - name: nagios containerPort: {{ tuple "nagios" "internal" "nagios" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: {{- if .Values.pod.env }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env | indent 12 }} {{- end }} - name: SNMP_NOTIF_PRIMARY_TARGET_WITH_PORT value: {{ $envAll.Values.conf.nagios.notification.snmp.primary_target }} - name: SNMP_NOTIF_SECONDARY_TARGET_WITH_PORT value: {{ $envAll.Values.conf.nagios.notification.snmp.secondary_target }} - name: REST_NOTIF_PRIMARY_TARGET_URL value: {{ $envAll.Values.conf.nagios.notification.http.primary_target }} - name: REST_NOTIF_SECONDARY_TARGET_URL value: {{ $envAll.Values.conf.nagios.notification.http.secondary_target }} - name: CEPH_MGR_SERVICE value: {{ tuple "ceph_mgr" "internal" "metrics" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }}/metrics - name: PROMETHEUS_SERVICE valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: PROMETHEUS_SERVICE - name: ELASTICSEARCH_SERVICE valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: ELASTICSEARCH_SERVICE - name: NAGIOSADMIN_USER valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: NAGIOSADMIN_USER - name: NAGIOSADMIN_PASS valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: NAGIOSADMIN_PASS {{- if .Values.manifests.certificates }} - name: CA_CERT_PATH value: "/etc/ssl/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: nagios-confd mountPath: /opt/nagios/etc/conf.d - name: nagios-etc mountPath: /opt/nagios/etc/nagios.cfg subPath: nagios.cfg readOnly: true - name: nagios-etc mountPath: /opt/nagios/etc/cgi.cfg subPath: cgi.cfg readOnly: true {{- $objectKeys := keys $envAll.Values.conf.nagios.objects -}} {{- range $objectType := $objectKeys }} - name: nagios-etc mountPath: /opt/nagios/etc/{{$objectType}}.cfg subPath: {{$objectType}}.cfg readOnly: true {{- end }} - name: nagios-bin mountPath: /tmp/nagios-readiness.sh subPath: nagios-readiness.sh readOnly: true {{- if not (empty .Values.conf.nagios.query_es_clauses) }} - name: nagios-etc mountPath: /opt/nagios/etc/objects/query_es_clauses.json subPath: query_es_clauses.json readOnly: true {{- end }} - name: pod-var-log mountPath: /opt/nagios/var/log {{- if not (empty .Values.conf.nagios.additionalPlugins) }} {{- range .Values.conf.nagios.additionalPlugins }} - name: additional-plugins mountPath: /usr/lib/nagios/plugins/{{ .name }} subPath: {{ .name }} readOnly: true {{- end }} {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" $envAll.Values.endpoints.monitoring.auth.admin.secret.tls.internal "path" "/etc/ssl/certs" "certs" tuple "ca.crt" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: pod-var-log emptyDir: {} - name: nagios-confd emptyDir: {} - name: nagios-etc secret: secretName: nagios-etc defaultMode: 0444 - name: nagios-bin configMap: name: nagios-bin defaultMode: 0555 - name: additional-plugins secret: secretName: nagios-additional-plugins defaultMode: 0755 {{- dict "enabled" .Values.manifests.certificates "name" $envAll.Values.endpoints.monitoring.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: nagios/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: nagios/templates/ingress-nagios.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.nagios.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendService" "nagios" "backendServiceType" "nagios" "backendPort" "http" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: nagios/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "nagios" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: nagios/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "nagios" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: nagios/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_helm_test }} {{- $envAll := . }} {{- $nagiosUserSecret := .Values.secrets.nagios.admin }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.Release.Name}}-test" labels: {{ tuple $envAll "nagios" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "nagios-test" "containerNames" (list "init" "nagios-helm-tests") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "monitoring" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: nagios-helm-tests {{ tuple $envAll "selenium_tests" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "monitoring" "container" "helm_tests" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/selenium-tests.py env: - name: NAGIOS_USER valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: NAGIOSADMIN_USER - name: NAGIOS_PASSWORD valueFrom: secretKeyRef: name: {{ $nagiosUserSecret }} key: NAGIOSADMIN_PASS - name: NAGIOS_URI value: {{ tuple "nagios" "internal" "http" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} - name: CHROME_CONFIG_HOME value: /tmp/google-chrome volumeMounts: - name: pod-tmp mountPath: /tmp - name: artifacts mountPath: /tmp/artifacts - name: nagios-bin mountPath: /tmp/selenium-tests.py subPath: selenium-tests.py readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: artifacts emptyDir: {} - name: nagios-bin configMap: name: nagios-bin defaultMode: 0555 {{- end }} ================================================ FILE: nagios/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "nagios" "backendService" "nagios" ) }} {{- end }} ================================================ FILE: nagios/templates/secret-nagios.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_nagios }} {{- $envAll := . }} {{- $secretName := index $envAll.Values.secrets.nagios.admin }} {{- $prometheusService := tuple "monitoring" "internal" "admin" "http" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} {{- $elasticsearchService := tuple "elasticsearch" "internal" "admin" "http" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: NAGIOSADMIN_USER: {{ .Values.endpoints.nagios.auth.admin.username | b64enc }} NAGIOSADMIN_PASS: {{ .Values.endpoints.nagios.auth.admin.password | b64enc }} BIND_DN: {{ .Values.endpoints.ldap.auth.admin.bind | b64enc }} BIND_PASSWORD: {{ .Values.endpoints.ldap.auth.admin.password | b64enc }} PROMETHEUS_SERVICE: {{ $prometheusService | b64enc }} ELASTICSEARCH_SERVICE: {{ $elasticsearchService | b64enc }} {{- end }} ================================================ FILE: nagios/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: nagios/templates/service-ingress-nagios.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.nagios.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "nagios" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: nagios/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "nagios" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: http port: {{ tuple "nagios" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.nagios.node_port.enabled }} nodePort: {{ .Values.network.nagios.node_port.port }} {{ end }} selector: {{ tuple $envAll "nagios" "monitoring" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.nagios.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: nagios/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for nagios. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: apache_proxy: docker.io/library/httpd:2.4 nagios: quay.io/airshipit/nagios:latest-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy selenium_tests: quay.io/airshipit/osh-selenium:latest-ubuntu_noble image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync # Use selenium v4 syntax selenium_v4: true labels: nagios: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled dependencies: dynamic: common: jobs: - nagios-image-repo-sync services: - service: local_image_registry endpoint: node static: image_repo_sync: services: - service: local_image_registry endpoint: internal nagios: services: null tests: services: - service: nagios endpoint: internal secrets: nagios: admin: nagios-admin-creds oci_image_registry: nagios: nagios-oci-image-registry-key tls: nagios: nagios: public: nagios-tls-public endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false nagios: username: nagios password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null monitoring: name: prometheus auth: admin: username: admin password: changeme secret: tls: internal: prometheus-tls-api hosts: default: prom-metrics public: prometheus host_fqdn_override: default: null path: default: null scheme: default: http port: http: default: 80 nagios: name: nagios namespace: null auth: admin: username: nagiosadmin password: password hosts: default: nagios-metrics public: nagios host_fqdn_override: default: null # NOTE(srwilkers): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: http port: nagios: default: 8000 http: default: 80 ldap: hosts: default: ldap auth: admin: bind: "cn=admin,dc=cluster,dc=local" password: password host_fqdn_override: default: null path: default: "/ou=People,dc=cluster,dc=local" scheme: default: ldap port: ldap: default: 389 elasticsearch: name: elasticsearch namespace: null auth: admin: username: admin password: changeme hosts: default: elasticsearch-logging host_fqdn_override: default: null path: default: / scheme: default: http port: http: default: 80 ceph_mgr: namespace: null hosts: default: ceph-mgr host_fqdn_override: default: null port: mgr: default: 7000 metrics: default: 9283 scheme: default: http network: nagios: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/affinity: cookie nginx.ingress.kubernetes.io/session-cookie-name: kube-ingress-session-nagios nginx.ingress.kubernetes.io/session-cookie-hash: sha1 nginx.ingress.kubernetes.io/session-cookie-expires: "600" nginx.ingress.kubernetes.io/session-cookie-max-age: "600" nginx.ingress.kubernetes.io/configuration-snippet: | more_set_headers "X-Content-Type-Options: 'nosniff'"; more_set_headers "X-Frame-Options: SAMEORIGIN"; more_set_headers "Content-Security-Policy: script-src 'self'"; more_set_headers "X-XSS-Protection: 1; mode=block"; haproxy.org/path-rewrite: / haproxy.org/cookie-persistence: "kube-ingress-session-nagios" haproxy.org/response-set-header: | X-Content-Type-Options nosniff X-Frame-Options SAMEORIGIN Content-Security-Policy "script-src 'self'" X-XSS-Protection "1; mode=block" node_port: enabled: false port: 30925 network_policy: nagios: ingress: - {} egress: - {} pod: security_context: monitoring: pod: runAsUser: 0 container: define_nagios_hosts: readOnlyRootFilesystem: false apache_proxy: readOnlyRootFilesystem: false nagios: readOnlyRootFilesystem: false helm_tests: readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: nagios: timeout: 30 # env: # # NOTE(megheisler): This value can be used to hold # the domain name. Functionality has been added in # plugins to append the domain to the host name in # the nagios dashboard # # NODE_DOMAIN: replicas: nagios: 1 probes: monitoring: nagios: readiness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 10 apache_proxy: readiness: enabled: true params: initialDelaySeconds: 20 periodSeconds: 10 resources: enabled: false nagios: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" apache_proxy: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" jobs: image_repo_sync: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" tests: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" manifests: certificates: false configmap_additional_plugins: false configmap_bin: true configmap_etc: true deployment: true ingress: true job_image_repo_sync: true network_policy: false pod_helm_test: true secret_nagios: true secret_ingress_tls: true secret_registry: true service: true service_ingress: true conf: httpd: | ServerRoot "/usr/local/apache2" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule slotmem_shm_module modules/mod_slotmem_shm.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so User daemon Group daemon AllowOverride none Require all denied Require all denied ErrorLog /dev/stderr LogLevel warn LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout common CustomLog /dev/stdout combined CustomLog /dev/stdout proxy env=forwarded AllowOverride None Options None Require all granted RequestHeader unset Proxy early Include conf/extra/proxy-html.conf ProxyPass http://localhost:{{ tuple "nagios" "internal" "nagios" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ ProxyPassReverse http://localhost:{{ tuple "nagios" "internal" "nagios" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ AuthName "Nagios" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user nagios: notification: snmp: primary_target: 127.0.0.1:15162 secondary_target: 127.0.0.1:15162 http: primary_target: 127.0.0.1:3904/events secondary_target: 127.0.0.1:3904/events objects: base: template: | define host { address 127.0.0.1 alias Prometheus Monitoring check_command check-prometheus-host-alive host_name {{ tuple "monitoring" "public" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} hostgroups prometheus-hosts use linux-server } define contact { alias notifying contact contact_name notifying_contact host_notification_options d,u,r,f,s host_notification_period 24x7 name notifying_contact register 0 service_notification_options w,u,c,r,f,s service_notification_period 24x7 } define contact { alias snmp contact contact_name snmp_notifying_contact host_notification_commands send_host_snmp_trap name snmp_notifying_contact service_notification_commands send_service_snmp_trap use notifying_contact } define contact { alias HTTP contact contact_name http_notifying_contact host_notification_commands send_host_http_post name http_notifying_contact service_notification_commands send_service_http_post use notifying_contact } define contactgroup { alias SNMP and HTTP notifying group contactgroup_name snmp_and_http_notifying_contact_group members snmp_notifying_contact,http_notifying_contact } define hostgroup { alias Prometheus Virtual Host hostgroup_name prometheus-hosts } define hostgroup { alias all hostgroup_name all } define hostgroup { alias base-os hostgroup_name base-os } define command { command_line $USER1$/send_service_trap.sh '$USER8$' '$HOSTNAME$' '$SERVICEDESC$' $SERVICESTATEID$ '$SERVICEOUTPUT$' '$USER4$' '$USER5$' command_name send_service_snmp_trap } define command { command_line $USER1$/send_host_trap.sh '$USER8$' '$HOSTNAME$' $HOSTSTATEID$ '$HOSTOUTPUT$' '$USER4$' '$USER5$' command_name send_host_snmp_trap } define command { command_line $USER1$/send_http_post_event.py --type service --hostname '$HOSTNAME$' --servicedesc '$SERVICEDESC$' --state_id $SERVICESTATEID$ --output '$SERVICEOUTPUT$' --monitoring_hostname '$HOSTNAME$' --primary_url '$USER6$' --secondary_url '$USER7$' command_name send_service_http_post } define command { command_line $USER1$/send_http_post_event.py --type host --hostname '$HOSTNAME$' --state_id $HOSTSTATEID$ --output '$HOSTOUTPUT$' --monitoring_hostname '$HOSTNAME$' --primary_url '$USER6$' --secondary_url '$USER7$' command_name send_host_http_post } define command { command_line $USER1$/check_rest_get_api.py --url $USER2$ --warning_response_seconds 5 --critical_response_seconds 10 command_name check-prometheus-host-alive } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname '$ARG1$' --labels_csv '$ARG2$' --msg_format '$ARG3$' --ok_message '$ARG4$' command_name check_prom_alert_with_labels } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname '$ARG1$' --msg_format '$ARG2$' --ok_message '$ARG3$' command_name check_prom_alert } define service { check_interval 60 contact_groups snmp_and_http_notifying_contact_group flap_detection_enabled 0 name notifying_service notification_interval 120 process_perf_data 0 register 0 retry_interval 30 use generic-service } kubernetes: template: | define service { check_command check_prom_alert!prom_exporter_calico_unavailable!CRITICAL- Calico exporter is not collecting metrics for alerting!OK- Calico exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_Calico use generic-service } define service { check_command check_prom_alert!prom_exporter_kube_state_metrics_unavailable!CRITICAL- kube-state-metrics exporter is not collecting metrics for alerting!OK- kube-state-metrics exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_Kube-state-metrics use generic-service } define service { check_command check_prom_alert!K8SNodesNotReady!CRITICAL- One or more nodes are not ready. check_interval 60 hostgroup_name prometheus-hosts service_description Nodes_health use generic-service } define service { check_command check_prom_alert_with_labels!kube_statefulset_replicas_unavailable!statefulset="prometheus"!statefulset {statefulset} has lesser than configured replicas check_interval 60 hostgroup_name prometheus-hosts service_description Prometheus_replica-count use notifying_service } define service { check_command check_prom_alert_with_labels!kube_statefulset_replicas_unavailable!statefulset="alertmanager"!statefulset {statefulset} has lesser than configured replicas check_interval 60 hostgroup_name prometheus-hosts service_description PrometheusAlertmanager_replica-count use notifying_service } define service { check_command check_prom_alert!kube_statefulset_replicas_unavailable!CRITICAL- statefulset {statefulset} has lesser than configured replicas!OK- All statefulsets have configured amount of replicas check_interval 60 hostgroup_name prometheus-hosts service_description Statefulset_replica-count use notifying_service } define service { check_command check_prom_alert!daemonsets_misscheduled!CRITICAL- Daemonset {daemonset} is incorrectly scheudled!OK- No daemonset misscheduling detected check_interval 60 hostgroup_name prometheus-hosts service_description Daemonset_misscheduled use notifying_service } define service { check_command check_prom_alert!daemonsets_not_scheduled!CRITICAL- Daemonset {daemonset} is missing to be scheduled in some nodes!OK- All daemonset scheduling is as desired check_interval 60 hostgroup_name prometheus-hosts service_description Daemonset_not-scheduled use notifying_service } define service { check_command check_prom_alert!daemonset_pods_unavailable!CRITICAL- Daemonset {daemonset} has pods unavailable!OK- All daemonset pods available check_interval 60 hostgroup_name prometheus-hosts service_description Daemonset_pods-unavailable use notifying_service } define service { check_command check_prom_alert!deployment_replicas_unavailable!CRITICAL- Deployment {deployment} has less than desired replicas!OK- All deployments have desired replicas check_interval 60 hostgroup_name prometheus-hosts service_description Deployment_replicas-unavailable use notifying_service } define service { check_command check_prom_alert!volume_claim_capacity_high_utilization!CRITICAL- Volume claim {persistentvolumeclaim} has exceed 80% utilization!OK- All volume claims less than 80% utilization check_interval 60 hostgroup_name prometheus-hosts service_description Volume_claim_high_utilization use notifying_service } define service { check_command check_prom_alert!rollingupdate_deployment_replica_less_than_spec_max_unavailable!CRITICAL- Deployment {deployment} has less than desired replicas during a rolling update!OK- All deployments have desired replicas check_interval 60 hostgroup_name prometheus-hosts service_description RollingUpdate_Deployment-replicas-unavailable use notifying_service } define service { check_command check_prom_alert!job_status_failed!CRITICAL- Job {exported_job} has failed!OK- No Job failures check_interval 60 hostgroup_name prometheus-hosts service_description Job_status-failed use notifying_service } define service { check_command check_prom_alert!pod_status_pending!CRITICAL- Pod {pod} in namespace {namespace} has been in pending status for more than 10 minutes!OK- No pods in pending status check_interval 60 hostgroup_name prometheus-hosts service_description Pod_status-pending use notifying_service } define service { check_command check_prom_alert!pod_status_error_image_pull!CRITICAL- Pod {pod} in namespace {namespace} has been in errpr status of ErrImagePull for more than 10 minutes!OK- No pods in error status check_interval 60 hostgroup_name prometheus-hosts service_description Pod_status-error-image-pull use notifying_service } define service { check_command check_prom_alert! pod_status_error_image_pull_backoff!CRITICAL- Pod {pod} in namespace {namespace} has been in errpr status of ImagePullBackOff for more than 10 minutes!OK- No pods in error status check_interval 60 hostgroup_name prometheus-hosts service_description Pod_status-error-image-pull use notifying_service } define service { check_command check_prom_alert! pod_error_config_error!CRITICAL- Pod {pod} in namespace {namespace} has been in errpr status of CreateContainerConfigError for more than 10 minutes!OK- No pods in error status check_interval 60 hostgroup_name prometheus-hosts service_description Pod_status-error-image-pull use notifying_service } define service { check_command check_prom_alert!pod_error_crash_loop_back_off!CRITICAL- Pod {pod} in namespace {namespace} has been in error status of CrashLoopBackOff for more than 10 minutes!OK- No pods in crashLoopBackOff status check_interval 60 hostgroup_name prometheus-hosts service_description Pod_status-crashLoopBackOff use notifying_service } define service { check_command check_prom_alert!replicaset_missing_replicas!CRITICAL- Replicaset {replicaset} is missing replicas!OK- No replicas missing from replicaset check_interval 60 hostgroup_name prometheus-hosts service_description Replicaset_missing-replicas use notifying_service } define service { check_command check_prom_alert!pod_container_terminated!CRITICAL- pod {pod} in namespace {namespace} has a container in terminated state!OK- pod container status looks good check_interval 60 hostgroup_name prometheus-hosts service_description Pod_status-container-terminated use notifying_service } define service { check_command check_prom_alert_with_labels!etcd_HighNumberOfFailedHTTPRequests!method="DELETE"!CRITICAL- ETCD {instance} has a high HTTP DELETE operations failure!OK- ETCD at {instance} has low or no failures for HTTP DELETE check_interval 60 hostgroup_name prometheus-hosts service_description ETCD_high-http-delete-failures use notifying_service } define service { check_command check_prom_alert_with_labels!etcd_HighNumberOfFailedHTTPRequests!method=~"GET|QGET"!CRITICAL- ETCD {instance} has a high HTTP GET operations failure!OK- ETCD at {instance} has low or no failures for HTTP GET check_interval 60 hostgroup_name prometheus-hosts service_description ETCD_high-http-get-failures use notifying_service } define service { check_command check_prom_alert_with_labels!etcd_HighNumberOfFailedHTTPRequests!method="PUT"!CRITICAL- ETCD {instance} has a high HTTP PUT operations failure!OK- ETCD at {instance} has low or no failures for HTTP PUT check_interval 60 hostgroup_name prometheus-hosts service_description ETCD_high-http-update-failures use notifying_service } define service { check_command check_prom_alert!calico_iptable_save_errors_high_1h!CRITICAL- Felix instance {instance} has seen high iptable save errors within the last hour!OK- iptables save errors are none or low hostgroup_name prometheus-hosts service_description Calico_iptables-save-errors use notifying_service } define service { check_command check_prom_alert!calico_ipset_errors_high_1h!CRITICAL- Felix instance {instance} has seen high ipset errors within the last hour!OK- ipset errors are none or low hostgroup_name prometheus-hosts service_description Calico_ipset-errors use notifying_service } define service { check_command check_prom_alert!calico_datapane_iface_msg_batch_size_high_5m!CRITICAL- Felix instance {instance} has seen a high value of dataplane interface message batch size!OK- dataplane interface message batch size are low hostgroup_name prometheus-hosts service_description Calico_interface-message-batch-size use notifying_service } define service { check_command check_prom_alert!calico_datapane_address_msg_batch_size_high_5m!CRITICAL- Felix instance {instance} has seen a high value of dataplane address message batch size!OK- dataplane address message batch size are low hostgroup_name prometheus-hosts service_description Calico_address-message-batch-size use notifying_service } define service { check_command check_prom_alert!calico_datapane_failures_high_1h!CRITICAL- Felix instance {instance} has seen high dataplane failures within the last hour!OK- datapane failures are none or low hostgroup_name prometheus-hosts service_description Calico_datapane_failures_high use notifying_service } node: template: | define service { check_command check_prom_alert!prom_exporter_node_unavailable!CRITICAL- Node exporter is not collecting metrics for alerting!OK- Node exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_Node use generic-service } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_filesystem_full_in_4h' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Mountpoint {mountpoint} will be full in four hours' --ok_message 'OK- All mountpoints usage rate is normal' command_name check_filespace_mounts-usage-rate-fullin4hrs } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_filesystem_full_80percent' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Mountpoint {mountpoint} is more than 80 pecent full' --ok_message 'OK- All mountpoints usage is normal' command_name check_filespace_mounts-usage } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_load1_90percent' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Node load average has been more than 90% for the pash hour' --ok_message 'OK- Node load average is normal' command_name check_node_loadavg } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_cpu_util_90percent' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Node CPU utilization has been more than 90% for the pash hour' --ok_message 'OK- Node cpu utilization is normal' command_name check_node_cpu_util } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_network_conntrack_usage_80percent' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Node network connections are more than 90% in use' --ok_message 'OK- Network connection utilization is normal' command_name check_network_connections } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_high_memory_load' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Node memory usage is more than 85%' --ok_message 'OK- Node memory usage is less than 85%' command_name check_memory_usage } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_disk_write_latency' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Disk write latency is high' --ok_message 'OK- Node disk write latency is normal' command_name check_disk_write_latency } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_disk_read_latency' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Disk read latency is high' --ok_message 'OK- Node disk read latency is normal' command_name check_disk_read_latency } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_entropy_available_low' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- System has low entropy availability' --ok_message 'OK- System entropy availability is sufficient' command_name check_entropy_availability } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_filedescriptors_full_in_3h' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- at current consumption rate no free file descriptors will be available in 3hrs.' --ok_message 'OK- System file descriptor consumption is ok.' command_name check_filedescriptor_usage_rate } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_hwmon_high_cpu_temp' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- CPU temperature is 90 percent of critical temperature.' --ok_message 'OK- CPU temperatures are normal.' command_name check_hwmon_high_cpu_temp } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_high_network_drop_rcv' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Host system has an unusally high drop in network reception.' --ok_message 'OK- network packet receive drops not high.' command_name check_network_receive_drop_high } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_high_network_drop_send' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Host system has an unusally high drop in network transmission.' --ok_message 'OK- network packet tramsmit drops not high.' command_name check_network_transmit_drop_high } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_high_network_errs_rcv' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Host system has an unusally high error rate in network reception.' --ok_message 'OK- network reception errors not high.' command_name check_network_receive_errors_high } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_high_network_errs_send' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Host system has an unusally high error rate in network transmission.' --ok_message 'OK- network transmission errors not high.' command_name check_network_transmit_errors_high } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_vmstat_paging_rate_high' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- Memory paging rate over 5 minutes is high.' --ok_message 'OK- Memory paging rate over 5 minutes is ok.' command_name check_vmstat_paging_rate } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_xfs_block_allocation_high' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- XFS block allocation is more than 80 percent of available.' --ok_message 'OK- XFS block allocation is less than 80 percent of available.' command_name check_xfs_block_allocation } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_network_bond_slaves_down' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- {master} is missing slave interfaces.' --ok_message 'OK- Network bonds have slave interfaces functional.' command_name check_network_bond_status } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_numa_memory_used' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- NUMA memory usage is more than 80 percent of available.' --ok_message 'OK- NUMA memory usage is normal.' command_name check_numa_memory_usage } define command { command_line $USER1$/query_prometheus_alerts.py --prometheus_api $USER2$ --alertname 'node_ntp_clock_skew_high' --labels_csv 'instance=~"$HOSTADDRESS$.*"' --msg_format 'CRITICAL- NTP clock skew is more than 2 seconds.' --ok_message 'OK- NTP clock skew is less than 2 seconds.' command_name check_ntp_sync } define service { check_command check_filespace_mounts-usage-rate-fullin4hrs check_interval 60 hostgroup_name base-os service_description Filespace_mounts-usage-rate-fullin4hrs use notifying_service } define service { check_command check_filespace_mounts-usage check_interval 60 hostgroup_name base-os service_description Filespace_mounts-usage use notifying_service } define service { check_command check_node_loadavg hostgroup_name base-os service_description CPU_Load-average use notifying_service } define service { check_command check_node_cpu_util hostgroup_name base-os service_description CPU_utilization use notifying_service } define service { check_command check_network_connections hostgroup_name base-os service_description Network_connections use notifying_service } define service { check_command check_memory_usage hostgroup_name base-os service_description Memory_usage use notifying_service } define service { check_command check_disk_write_latency hostgroup_name base-os service_description Disk_write-latency use notifying_service } define service { check_command check_disk_read_latency hostgroup_name base-os service_description Disk_read-latency use notifying_service } define service { check_command check_entropy_availability hostgroup_name base-os service_description Entropy_availability use notifying_service } define service { check_command check_filedescriptor_usage_rate hostgroup_name base-os service_description FileDescriptors_usage-rate-high use notifying_service } define service { check_command check_hwmon_high_cpu_temp hostgroup_name base-os service_description HW_cpu-temp-high use notifying_service } define service { check_command check_network_receive_drop_high hostgroup_name base-os service_description Network_receive-drop-high use notifying_service } define service { check_command check_network_transmit_drop_high hostgroup_name base-os service_description Network_transmit-drop-high use notifying_service } define service { check_command check_network_receive_errors_high hostgroup_name base-os service_description Network_receive-errors-high use notifying_service } define service { check_command check_network_transmit_errors_high hostgroup_name base-os service_description Network_transmit-errors-high use notifying_service } define service { check_command check_vmstat_paging_rate hostgroup_name base-os service_description Memory_vmstat-paging-rate use notifying_service } define service { check_command check_xfs_block_allocation hostgroup_name base-os service_description XFS_block-allocation use notifying_service } define service { check_command check_network_bond_status hostgroup_name base-os service_description Network_bondstatus use notifying_service } define service { check_command check_numa_memory_usage hostgroup_name base-os service_description Memory_NUMA-usage use notifying_service } define service { check_command check_ntp_sync hostgroup_name base-os service_description NTP_sync use notifying_service } ceph: template: | define service { check_command check_prom_alert!prom_exporter_ceph_unavailable!CRITICAL- CEPH exporter is not collecting metrics for alerting!OK- CEPH exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_CEPH use generic-service } define command { command_line $USER1$/check_exporter_health_metric.py --exporter_api $USER10$ --health_metric ceph_health_status --critical 2 --warning 1 command_name check_ceph_health } define service { check_command check_ceph_health check_interval 300 hostgroup_name base-os service_description CEPH_health use notifying_service } define service { check_command check_prom_alert!ceph_monitor_quorum_low!CRITICAL- ceph monitor quorum does not exist!OK- ceph monitor quorum exists check_interval 60 hostgroup_name prometheus-hosts service_description CEPH_quorum use notifying_service } define service { check_command check_prom_alert!ceph_monitor_quorum_absent!CRITICAL- ceph monitor quorum does not exist!OK- ceph monitor quorum exists check_interval 60 hostgroup_name prometheus-hosts service_description CEPH_quorum use notifying_service } define service { check_command check_prom_alert!ceph_cluster_usage_high!CRITICAL- ceph cluster storage is more than 80 percent!OK- ceph storage is less than 80 percent check_interval 60 hostgroup_name prometheus-hosts service_description CEPH_storage-usage use notifying_service } define service { check_command check_prom_alert!ceph_placement_group_degrade_pct_high!CRITICAL- ceph cluster PGs down are more than 80 percent!OK- ceph PG degradation is less than 80 percent check_interval 60 hostgroup_name prometheus-hosts service_description CEPH_PGs-degradation use notifying_service } define service { check_command check_prom_alert!ceph_osd_down!CRITICAL- One or more CEPH OSDs are down for more than 5 minutes!OK- All the CEPH OSDs are up check_interval 60 hostgroup_name prometheus-hosts service_description CEPH_OSDs-down use notifying_service } define service { check_command check_prom_alert_with_labels!node_ntp_clock_skew_high!ceph-mon="enabled"!CRITICAL- CEPH clock skew is more than 2 seconds!OK- CEPH clock skew is less than 2 seconds check_interval 60 hostgroup_name prometheus-hosts service_description CEPH_Clock-skew use notifying_service } nagios: template: | accept_passive_host_checks=1 accept_passive_service_checks=1 additional_freshness_latency=15 allow_empty_hostgroup_assignment=1 auto_reschedule_checks=0 auto_rescheduling_interval=30 auto_rescheduling_window=180 bare_update_check=0 cached_host_check_horizon=15 cached_service_check_horizon=15 {{- $objectKeys := keys .Values.conf.nagios.objects -}} {{- range $object := $objectKeys }} cfg_file=/opt/nagios/etc/{{$object}}.cfg {{- end }} cfg_file=/opt/nagios/etc/objects/commands.cfg cfg_file=/opt/nagios/etc/objects/contacts.cfg cfg_file=/opt/nagios/etc/objects/timeperiods.cfg cfg_file=/opt/nagios/etc/objects/templates.cfg cfg_file=/opt/nagios/etc/conf.d/nagios-hosts.cfg check_external_commands=1 check_for_orphaned_hosts=1 check_for_orphaned_services=1 check_for_updates=1 check_host_freshness=0 check_result_path=/opt/nagios/var/spool/checkresults check_result_reaper_frequency=10 check_service_freshness=1 check_workers=4 command_file=/opt/nagios/var/rw/nagios.cmd daemon_dumps_core=0 date_format=us debug_file=/opt/nagios/var/nagios.debug debug_level=0 debug_verbosity=1 enable_environment_macros=0 enable_event_handlers=1 enable_flap_detection=1 enable_notifications=1 enable_predictive_host_dependency_checks=1 enable_predictive_service_dependency_checks=1 event_broker_options=-1 event_handler_timeout=60 execute_host_checks=1 execute_service_checks=1 high_host_flap_threshold=20 high_service_flap_threshold=20 host_check_timeout=60 host_freshness_check_interval=60 host_inter_check_delay_method=s illegal_macro_output_chars=`~$&|'<>" interval_length=1 lock_file=/var/run/nagios.lock log_archive_path=/opt/nagios/var/log/archives log_current_states=1 log_event_handlers=1 log_external_commands=1 log_file=/opt/nagios/var/log/nagios.log log_host_retries=1 log_initial_states=0 log_notifications=0 log_passive_checks=1 log_rotation_method=d log_service_retries=1 low_host_flap_threshold=5 low_service_flap_threshold=5 max_check_result_file_age=3600 max_check_result_reaper_time=30 max_concurrent_checks=10 max_debug_file_size=1e+06 max_host_check_spread=30 max_service_check_spread=30 nagios_group=nagios nagios_user=nagios notification_timeout=60 object_cache_file=/opt/nagios/var/objects.cache obsess_over_hosts=0 obsess_over_services=0 ocsp_timeout=5 passive_host_checks_are_soft=0 perfdata_timeout=5 precached_object_file=/opt/nagios/var/objects.precache process_performance_data=0 resource_file=/opt/nagios/etc/resource.cfg retain_state_information=1 retained_contact_host_attribute_mask=0 retained_contact_service_attribute_mask=0 retained_host_attribute_mask=0 retained_process_host_attribute_mask=0 retained_process_service_attribute_mask=0 retained_service_attribute_mask=0 retention_update_interval=60 service_check_timeout=60 service_freshness_check_interval=60 service_inter_check_delay_method=s service_interleave_factor=s soft_state_dependencies=0 state_retention_file=/opt/nagios/var/retention.dat status_file=/opt/nagios/var/status.dat status_update_interval=10 temp_file=/opt/nagios/var/nagios.tmp temp_path=/tmp translate_passive_host_checks=0 use_aggressive_host_checking=0 use_large_installation_tweaks=0 use_regexp_matching=1 use_retained_program_state=1 use_retained_scheduling_info=1 use_syslog=0 use_true_regexp_matching=0 cgi: template: | action_url_target=_blank authorized_for_all_host_commands=* authorized_for_all_hosts=* authorized_for_all_service_commands=* authorized_for_all_services=* authorized_for_configuration_information=* authorized_for_system_commands=nagiosadmin authorized_for_system_information=* default_statuswrl_layout=4 enable_page_tour=0 escape_html_tags=1 lock_author_names=1 main_config_file=/opt/nagios/etc/nagios.cfg navbar_search_for_addresses=1 navbar_search_for_aliases=1 notes_url_target=_blank physical_html_path=/opt/nagios/share ping_syntax=/bin/ping -n -U -c 5 $HOSTADDRESS$ refresh_rate=90 result_limit=100 show_context_help=0 url_html_path=/nagios use_authentication=0 use_pending_states=1 use_ssl_authentication=0 query_es_clauses: null additionalPlugins: [] # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: namespace-config/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Namespace Config name: namespace-config version: 2025.2.0 home: https://kubernetes.io/docs/concepts/policy/limit-range/ ... ================================================ FILE: namespace-config/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: namespace-config/templates/limit-range.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} apiVersion: v1 kind: LimitRange metadata: name: {{ printf "%s-%s" .Release.Name "limit-range" }} spec: {{ toYaml (dict "limits" .Values.limits) | indent 2 }} ================================================ FILE: namespace-config/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for memcached. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- limits: - type: Container default: cpu: 8 memory: 8192Mi defaultRequest: cpu: 0.1 memory: 64Mi # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: neutron/.helmignore ================================================ values_overrides ================================================ FILE: neutron/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Neutron name: neutron version: 2025.2.0 home: https://docs.openstack.org/neutron/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Neutron/OpenStack_Project_Neutron_vertical.png sources: - https://opendev.org/openstack/neutron - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: neutron/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: neutron/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex neutron-db-manage \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ --config-dir /etc/neutron/neutron.conf.d \ upgrade head {{- if .Values.conf.plugins.taas.taas.enabled }} neutron-db-manage \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ --config-dir /etc/neutron/neutron.conf.d \ --subproject tap-as-a-service \ upgrade head {{- end }} ================================================ FILE: neutron/templates/bin/_health-probe.py.tpl ================================================ #!/usr/bin/env python {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} """ Health probe script for OpenStack agents that uses RPC/unix domain socket for communication. Sends message to agent through rpc call method and expects a reply. It is expected to receive a failure from the agent's RPC server as the method does not exist. Script returns failure to Kubernetes only when a. agent is not reachable or b. agent times out sending a reply. sys.stderr.write() writes to pod's events on failures. Usage example for Neutron L3 agent: # python health-probe.py --config-file /etc/neutron/neutron.conf \ # --config-file /etc/neutron/l3_agent.ini --agent-queue-name l3_agent Usage example for Neutron metadata agent: # python health-probe.py --config-file /etc/neutron/neutron.conf \ # --config-file /etc/neutron/metadata_agent.ini """ import httplib2 from http import client as httplib import json import os import psutil import signal import socket import sys from oslo_config import cfg from oslo_context import context from oslo_log import log import oslo_messaging rpc_timeout = int(os.getenv('RPC_PROBE_TIMEOUT', '60')) rpc_retries = int(os.getenv('RPC_PROBE_RETRIES', '2')) rabbit_port = 5672 tcp_established = "ESTABLISHED" log.logging.basicConfig(level=log.{{ .Values.health_probe.logging.level }}) def _get_hostname(use_fqdn): if use_fqdn: return socket.getfqdn() return socket.gethostname() def check_agent_status(transport): """Verify agent status. Return success if agent consumes message""" try: use_fqdn = cfg.CONF.use_fqdn target = oslo_messaging.Target( topic=cfg.CONF.agent_queue_name, server=_get_hostname(use_fqdn)) if hasattr(oslo_messaging, 'get_rpc_client'): client = oslo_messaging.get_rpc_client(transport, target, timeout=rpc_timeout, retry=rpc_retries) else: client = oslo_messaging.RPCClient(transport, target, timeout=rpc_timeout, retry=rpc_retries) client.call(context.RequestContext(), 'pod_health_probe_method_ignore_errors') except oslo_messaging.exceptions.MessageDeliveryFailure: # Log to pod events sys.stderr.write("Health probe unable to reach message bus") sys.exit(0) # return success except oslo_messaging.rpc.client.RemoteError as re: message = getattr(re, "message", str(re)) if ("Endpoint does not support RPC method" in message) or \ ("Endpoint does not support RPC version" in message): sys.exit(0) # Call reached the agent else: sys.stderr.write("Health probe unable to reach agent") sys.exit(1) # return failure except oslo_messaging.exceptions.MessagingTimeout: sys.stderr.write("Health probe timed out. Agent is down or response " "timed out") sys.exit(1) # return failure except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Health probe caught exception sending message to " "agent: %s" % message) sys.exit(0) except: sys.stderr.write("Health probe caught exception sending message to" " agent") sys.exit(0) finally: if transport: transport.cleanup() def sriov_readiness_check(): """Checks the sriov configuration on the sriov nic's""" return_status = 1 with open('/etc/neutron/plugins/ml2/sriov_agent.ini') as nic: for phy in nic: if "physical_device_mappings" in phy: phy_dev = phy.split('=', 1)[1] phy_dev1 = phy_dev.rstrip().split(',') if not phy_dev1: sys.stderr.write("No Physical devices" " configured as SRIOV NICs") sys.exit(1) for intf in phy_dev1: phy, dev = intf.split(':') try: with open('/sys/class/net/%s/device/' 'sriov_numvfs' % dev) as f: for line in f: numvfs = line.rstrip('\n') if numvfs: return_status = 0 except IOError: sys.stderr.write("IOError:No sriov_numvfs config file") sys.exit(return_status) def get_rabbitmq_ports(): "Get RabbitMQ ports" rabbitmq_ports = set() try: transport_url = oslo_messaging.TransportURL.parse(cfg.CONF) for host in transport_url.hosts: rabbitmq_ports.add(host.port) except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Health probe caught exception reading " "RabbitMQ ports: %s" % message) sys.exit(0) # return success return rabbitmq_ports def tcp_socket_state_check(agentq): """Check if the tcp socket to rabbitmq is in Established state""" rabbit_sock_count = 0 if agentq == "l3_agent": proc = "neutron-l3-agen" elif agentq == "dhcp_agent": proc = "neutron-dhcp-ag" elif agentq == "q-agent-notifier-tunnel-update": proc = "neutron-openvsw" else: proc = "neutron-metadat" rabbitmq_ports = get_rabbitmq_ports() for p in psutil.process_iter(): try: with p.oneshot(): if proc in " ".join(p.cmdline()): pcon = getattr(p, "net_connections", p.connections)() for con in pcon: try: port = con.raddr[1] status = con.status except IndexError: continue if port in rabbitmq_ports and\ status == tcp_established: rabbit_sock_count = rabbit_sock_count + 1 except psutil.Error: continue if rabbit_sock_count == 0: sys.stderr.write("RabbitMQ sockets not Established") # Do not kill the pod if RabbitMQ is not reachable/down if not cfg.CONF.liveness_probe: sys.exit(1) class UnixDomainHTTPConnection(httplib.HTTPConnection): """Connection class for HTTP over UNIX domain socket.""" def __init__(self, host, port=None, strict=None, timeout=None, proxy_info=None): httplib.HTTPConnection.__init__(self, host, port, strict) self.timeout = timeout self.socket_path = cfg.CONF.metadata_proxy_socket def connect(self): self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) if self.timeout: self.sock.settimeout(self.timeout) self.sock.connect(self.socket_path) def test_socket_liveness(): """Test if agent can respond to message over the socket""" cfg.CONF.register_cli_opt(cfg.BoolOpt('liveness-probe', default=False, required=False)) cfg.CONF.register_cli_opt(cfg.BoolOpt('use-fqdn', default=False, required=False)) cfg.CONF(sys.argv[1:]) try: metadata_proxy_socket = cfg.CONF.metadata_proxy_socket except cfg.NoSuchOptError: cfg.CONF.register_opt(cfg.StrOpt( 'metadata_proxy_socket', default='/var/lib/neutron/openstack-helm/metadata_proxy')) headers = {'X-Forwarded-For': '169.254.169.254', 'X-Neutron-Router-ID': 'pod-health-probe-check-ignore-errors'} h = httplib2.Http(timeout=30) try: resp, content = h.request( 'http://169.254.169.254', method='GET', headers=headers, connection_type=UnixDomainHTTPConnection) except socket.error as se: msg = "Socket error: Health probe failed to connect to " \ "Neutron Metadata agent: " if se.strerror: sys.stderr.write(msg + se.strerror) else: sys.stderr.write(msg + getattr(se, "message")) sys.exit(1) # return failure except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Health probe caught exception sending message to " "Neutron Metadata agent: %s" % message) sys.exit(0) # return success if resp.status >= 500: # Probe expects HTTP error code 404 msg = "Health probe failed: Neutron Metadata agent failed to" \ " process request: " sys.stderr.write(msg + str(resp.__dict__)) sys.exit(1) # return failure def test_rpc_liveness(): """Test if agent can consume message from queue""" oslo_messaging.set_transport_defaults(control_exchange='neutron') rabbit_group = cfg.OptGroup(name='oslo_messaging_rabbit', title='RabbitMQ options') cfg.CONF.register_group(rabbit_group) cfg.CONF.register_cli_opt(cfg.StrOpt('agent-queue-name')) cfg.CONF.register_cli_opt(cfg.BoolOpt('liveness-probe', default=False, required=False)) cfg.CONF.register_cli_opt(cfg.BoolOpt('use-fqdn', default=False, required=False)) cfg.CONF(sys.argv[1:]) try: transport = oslo_messaging.get_rpc_transport(cfg.CONF) except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Message bus driver load error: %s" % message) sys.exit(0) # return success if not cfg.CONF.transport_url or \ not cfg.CONF.agent_queue_name: sys.stderr.write("Both message bus URL and agent queue name are " "required for Health probe to work") sys.exit(0) # return success try: cfg.CONF.set_override('rabbit_max_retries', 2, group=rabbit_group) # 3 attempts except cfg.NoSuchOptError as ex: cfg.CONF.register_opt(cfg.IntOpt('rabbit_max_retries', default=2), group=rabbit_group) agentq = cfg.CONF.agent_queue_name tcp_socket_state_check(agentq) check_agent_status(transport) def check_pid_running(pid): if psutil.pid_exists(int(pid)): return True else: return False if __name__ == "__main__": if "liveness-probe" in ','.join(sys.argv): pidfile = "/tmp/liveness.pid" #nosec else: pidfile = "/tmp/readiness.pid" #nosec data = {} if os.path.isfile(pidfile): with open(pidfile,'r') as f: file_content = f.read().strip() if file_content: data = json.loads(file_content) if 'pid' in data and check_pid_running(data['pid']): if 'exit_count' in data and data['exit_count'] > 1: # Third time in, kill the previous process os.kill(int(data['pid']), signal.SIGTERM) else: data['exit_count'] = data.get('exit_count', 0) + 1 with open(pidfile, 'w') as f: json.dump(data, f) sys.exit(0) data['pid'] = os.getpid() data['exit_count'] = 0 with open(pidfile, 'w') as f: json.dump(data, f) if "sriov_agent.ini" in ','.join(sys.argv): sriov_readiness_check() elif "metadata_agent.ini" not in ','.join(sys.argv): test_rpc_liveness() else: test_socket_liveness() sys.exit(0) # return success ================================================ FILE: neutron/templates/bin/_neutron-bagpipe-bgp-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- if (has "openvswitch" .Values.network.backend) }} chown neutron: /run/openvswitch/db.sock {{- end }} # handle any bridge mappings for bmap in `sed 's/[{}"]//g' /tmp/auto_bridge_add | tr "," "\n"`; do bridge=${bmap%:*} iface=${bmap#*:} {{- if (has "openvswitch" .Values.network.backend) }} ovs-vsctl --no-wait --may-exist add-br $bridge if [ -n "$iface" -a "$iface" != "null" ]; then ovs-vsctl --no-wait --may-exist add-port $bridge $iface ip link set dev $iface up fi {{- else if (has "linuxbridge" .Values.network.backend) }} set +e; ip link add name $bridge type bridge; set -e ip link set dev $bridge up [ -n "$iface" -a "$iface" != "null" ] && ip link set dev $iface master $bridge {{- end }} done ================================================ FILE: neutron/templates/bin/_neutron-bagpipe-bgp.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec bagpipe-bgp ================================================ FILE: neutron/templates/bin/_neutron-bgp-dragent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec neutron-bgp-dragent \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/bgp_dragent.ini \ --config-dir /etc/neutron/neutron.conf.d \ --debug ================================================ FILE: neutron/templates/bin/_neutron-dhcp-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-dhcp-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec neutron-dhcp-agent \ --config-file /etc/neutron/neutron.conf \ {{- if ( has "ovn" .Values.network.backend ) }} --config-file /tmp/pod-shared/ovn.ini \ {{- end }} {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} {{- if ( has "openvswitch" .Values.network.backend ) }} --config-file /etc/neutron/plugins/ml2/openvswitch_agent.ini \ {{- end }} --config-file /etc/neutron/dhcp_agent.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-ironic-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-ironic-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec ironic-neutron-agent \ --config-file /etc/neutron/neutron.conf \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ --config-dir /etc/neutron/neutron.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: neutron/templates/bin/_neutron-l2gw-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec neutron-l2gateway-agent \ --config-file=/etc/neutron/neutron.conf \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} --config-file=/etc/neutron/l2gw_agent.ini \ --config-dir=/etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-l3-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-l3-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec neutron-l3-agent \ --config-file /etc/neutron/neutron.conf \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} --config-file /etc/neutron/l3_agent.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-linuxbridge-agent-init-modules.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex chroot /mnt/host-rootfs modprobe bridge chroot /mnt/host-rootfs modprobe ip6_tables chroot /mnt/host-rootfs modprobe ebtables ================================================ FILE: neutron/templates/bin/_neutron-linuxbridge-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # configure all bridge mappings defined in config # /tmp/auto_bridge_add is one line json file: {"br-ex1":"eth1","br-ex2":"eth2"} for bmap in `sed 's/[{}"]//g' /tmp/auto_bridge_add | tr "," "\n"` do bridge=${bmap%:*} iface=${bmap#*:} # adding existing bridge would break out the script when -e is set set +e ip link add name $bridge type bridge set -e ip link set dev $bridge up if [ -n "$iface" ] && [ "$iface" != "null" ] then ip link set dev $iface master $bridge fi done tunnel_interface="{{- .Values.network.interface.tunnel -}}" if [ -z "${tunnel_interface}" ] ; then # search for interface with tunnel network routing tunnel_network_cidr="{{- .Values.network.interface.tunnel_network_cidr -}}" if [ -z "${tunnel_network_cidr}" ] ; then tunnel_network_cidr="0/0" fi # If there is not tunnel network gateway, exit tunnel_interface=$(ip -4 route list ${tunnel_network_cidr} | awk -F 'dev' '{ print $2; exit }' \ | awk '{ print $1 }') || exit 1 fi # determine local-ip dynamically based on interface provided but only if tunnel_types is not null LOCAL_IP=$(ip a s $tunnel_interface | grep 'inet ' | awk '{print $2}' | awk -F "/" 'NR==1 {print $1}') if [ -z "${LOCAL_IP}" ] ; then echo "Var LOCAL_IP is empty" exit 1 fi tee > /tmp/pod-shared/ml2-local-ip.ini << EOF [vxlan] local_ip = "${LOCAL_IP}" EOF {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-linuxbridge-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec neutron-linuxbridge-agent \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ --config-file /tmp/pod-shared/ml2-local-ip.ini \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} --config-file /etc/neutron/plugins/ml2/linuxbridge_agent.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-metadata-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex chown ${NEUTRON_USER_UID} /var/lib/neutron/openstack-helm {{- if (has "ovn" .Values.network.backend) }} chown ${NEUTRON_USER_UID} /run/openvswitch/db.sock {{- end }} {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-metadata-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec neutron-metadata-agent \ --config-file /etc/neutron/neutron.conf \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} --config-file /etc/neutron/metadata_agent.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-netns-cleanup-cron.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -xe # Run "neutron-netns-cleanup" every 5 minutes while sleep 300; do neutron-netns-cleanup \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/dhcp_agent.ini \ --config-file /etc/neutron/l3_agent.ini \ --config-dir /etc/neutron/neutron.conf.d done ================================================ FILE: neutron/templates/bin/_neutron-openvswitch-agent-init-modules.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex chroot /mnt/host-rootfs modprobe ip6_tables {{- if .Values.conf.ovs_dpdk.enabled }} chroot /mnt/host-rootfs modprobe {{ .Values.conf.ovs_dpdk.driver | quote }} {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-openvswitch-agent-init-netoffload.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # ASAP2 for cfg in $(cat /tmp/netoffload | jq -r '(.asap2 // [])[] | @base64'); do _jq() { echo ${cfg} | base64 --decode | jq -r ${1} } DEVICE=$(_jq '.dev') VFS=$(_jq '.vfs') offloadctl enable asap2 ${DEVICE} --vfs ${VFS} done ================================================ FILE: neutron/templates/bin/_neutron-openvswitch-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex OVS_SOCKET=/run/openvswitch/db.sock chown neutron: ${OVS_SOCKET} # This enables the usage of 'ovs-appctl' from neutron pod. OVS_PID=$(cat /run/openvswitch/ovs-vswitchd.pid) OVS_CTL=/run/openvswitch/ovs-vswitchd.${OVS_PID}.ctl chown neutron: ${OVS_CTL} function get_dpdk_config_value { values=${@:1:$#-1} filter=${!#} value=$(echo ${values} | jq -r ${filter}) if [[ "${value}" == "null" ]]; then echo "" else echo "${value}" fi } DPDK_CONFIG_FILE=/tmp/dpdk.conf DPDK_CONFIG="" DPDK_ENABLED=false if [ -f ${DPDK_CONFIG_FILE} ]; then DPDK_CONFIG=$(cat ${DPDK_CONFIG_FILE}) if [[ $(get_dpdk_config_value ${DPDK_CONFIG} '.enabled') == "true" ]]; then DPDK_ENABLED=true fi fi function bind_nic { echo $2 > /sys/bus/pci/devices/$1/driver_override echo $1 > /sys/bus/pci/drivers/$2/bind } function unbind_nic { echo $1 > /sys/bus/pci/drivers/$2/unbind echo > /sys/bus/pci/devices/$1/driver_override } function get_name_by_pci_id { path=$(find /sys/bus/pci/devices/$1/ -name net) if [ -n "${path}" ] ; then echo $(ls -1 $path/) fi } function get_ip_address_from_interface { local interface=$1 local ip=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' 'NR==1 {print $1}') if [ -z "${ip}" ] ; then exit 1 fi echo ${ip} } function get_ip_prefix_from_interface { local interface=$1 local prefix=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' 'NR==1 {print $2}') if [ -z "${prefix}" ] ; then exit 1 fi echo ${prefix} } function migrate_ip { pci_id=$1 bridge_name=$2 local src_nic=$(get_name_by_pci_id ${pci_id}) if [ -n "${src_nic}" ] ; then bridge_exists=$(ip a s "${bridge_name}" | grep "${bridge_name}" | cut -f2 -d':' 2> /dev/null) if [ -z "${bridge_exists}" ] ; then echo "Bridge "${bridge_name}" does not exist. Creating it on demand." init_ovs_dpdk_bridge "${bridge_name}" fi migrate_ip_from_nic ${src_nic} ${bridge_name} fi } function migrate_ip_from_nic { src_nic=$1 bridge_name=$2 # Enabling explicit error handling: We must avoid to lose the IP # address in the migration process. Hence, on every error, we # attempt to assign the IP back to the original NIC and exit. set +e ip=$(get_ip_address_from_interface ${src_nic}) prefix=$(get_ip_prefix_from_interface ${src_nic}) bridge_ip=$(get_ip_address_from_interface "${bridge_name}") bridge_prefix=$(get_ip_prefix_from_interface "${bridge_name}") ip link set ${bridge_name} up if [[ -n "${ip}" && -n "${prefix}" ]]; then ip addr flush dev ${src_nic} if [ $? -ne 0 ] ; then ip addr replace ${ip}/${prefix} dev ${src_nic} echo "Error while flushing IP from ${src_nic}." exit 1 fi ip addr replace ${ip}/${prefix} dev "${bridge_name}" if [ $? -ne 0 ] ; then echo "Error assigning IP to bridge "${bridge_name}"." ip addr replace ${ip}/${prefix} dev ${src_nic} exit 1 fi elif [[ -n "${bridge_ip}" && -n "${bridge_prefix}" ]]; then echo "Bridge '${bridge_name}' already has IP assigned. Keeping the same:: IP:[${bridge_ip}]; Prefix:[${bridge_prefix}]..." elif [[ -z "${bridge_ip}" && -z "${ip}" ]]; then echo "Interface and bridge have no ips configured. Leaving as is." else echo "Interface ${name} has invalid IP address. IP:[${ip}]; Prefix:[${prefix}]..." exit 1 fi set -e } function get_pf_or_vf_pci { dpdk_pci_id=${1} vf_index=${2} if [ -n "$vf_index" ] then iface=$(get_name_by_pci_id "${dpdk_pci_id}") sysfs_numvfs_path="/sys/class/net/${iface}/device/sriov_numvfs" if [[ -f /sys/class/net/${iface}/device/sriov_numvfs && "$(cat /sys/class/net/${iface}/device/sriov_numvfs)" -ne "0" && -e /sys/class/net/${iface}/device/virtfn${vf_index} ]] then dpdk_pci_id=$(ls -la /sys/class/net/${iface}/device/virtfn${vf_index}) dpdk_pci_id=${dpdk_pci_id#*"../"} else echo "Error fetching the VF PCI for PF: ["${iface}", "${dpdk_pci_id}"] and VF-Index: ${vf_index}." exit 1 fi fi } function bind_dpdk_nic { target_driver=${1} pci_id=${2} current_driver="$(get_driver_by_address "${pci_id}" )" if [ "$current_driver" != "$target_driver" ]; then if [ "$current_driver" != "" ]; then unbind_nic "${pci_id}" ${current_driver} fi bind_nic "${pci_id}" ${target_driver} fi } function ensure_vf_state { iface=${1} vf_string=${2} check_string=${3} expected=${4} # wait for the vf really get the needed state for i in 0 1 2 4 8 16 32; do sleep ${i}; if [ "$(ip link show ${iface} | grep "${vf_string} " | grep -Eo "${check_string}")" == "${expected}" ]; then break; fi; done } function process_dpdk_nics { target_driver=$(get_dpdk_config_value ${DPDK_CONFIG} '.driver') # loop over all nics echo $DPDK_CONFIG | jq -r -c '.nics[]' | \ while IFS= read -r nic; do local port_name=$(get_dpdk_config_value ${nic} '.name') local pci_id=$(get_dpdk_config_value ${nic} '.pci_id') local iface=$(get_dpdk_config_value ${nic} '.iface') if [ -n ${iface} ] && [ -z ${pci_id} ]; then local pci_id=$(get_address_by_nicname ${iface}) else iface=$(get_name_by_pci_id "${pci_id}") fi local bridge=$(get_dpdk_config_value ${nic} '.bridge') local vf_index=$(get_dpdk_config_value ${nic} '.vf_index') if [[ $(get_dpdk_config_value ${nic} '.migrate_ip') == true ]] ; then migrate_ip "${pci_id}" "${bridge}" fi if [ -n "${iface}" ]; then ip link set ${iface} promisc on if [ -n "${vf_index}" ]; then vf_string="vf ${vf_index}" ip link set ${iface} ${vf_string} trust on ensure_vf_state "${iface}" "${vf_string}" "trust o(n|ff)" "trust on" # NOTE: To ensure proper toggle of spoofchk, # turn it on then off. ip link set ${iface} ${vf_string} spoofchk on ensure_vf_state "${iface}" "${vf_string}" "spoof checking o(n|ff)" "spoof checking on" ip link set ${iface} ${vf_string} spoofchk off ensure_vf_state "${iface}" "${vf_string}" "spoof checking o(n|ff)" "spoof checking off" fi fi # Fetch the PCI to be bound to DPDK driver. # In case VF Index is configured then PCI of that particular VF # is bound to DPDK, otherwise PF PCI is bound to DPDK. get_pf_or_vf_pci "${pci_id}" "${vf_index}" bind_dpdk_nic ${target_driver} "${dpdk_pci_id}" dpdk_options="" ofport_request=$(get_dpdk_config_value ${nic} '.ofport_request') if [ -n "${ofport_request}" ]; then dpdk_options+='ofport_request=${ofport_request} ' fi n_rxq=$(get_dpdk_config_value ${nic} '.n_rxq') if [ -n "${n_rxq}" ]; then dpdk_options+='options:n_rxq=${n_rxq} ' fi n_txq=$(get_dpdk_config_value ${nic} '.n_txq') if [ -n "${n_txq}" ]; then dpdk_options+='options:n_txq=${n_txq} ' fi pmd_rxq_affinity=$(get_dpdk_config_value ${nic} '.pmd_rxq_affinity') if [ -n "${pmd_rxq_affinity}" ]; then dpdk_options+='other_config:pmd-rxq-affinity=${pmd_rxq_affinity} ' fi mtu=$(get_dpdk_config_value ${nic} '.mtu') if [ -n "${mtu}" ]; then dpdk_options+='mtu_request=${mtu} ' fi n_rxq_size=$(get_dpdk_config_value ${nic} '.n_rxq_size') if [ -n "${n_rxq_size}" ]; then dpdk_options+='options:n_rxq_desc=${n_rxq_size} ' fi n_txq_size=$(get_dpdk_config_value ${nic} '.n_txq_size') if [ -n "${n_txq_size}" ]; then dpdk_options+='options:n_txq_desc=${n_txq_size} ' fi vhost_iommu_support=$(get_dpdk_config_value ${nic} '.vhost-iommu-support') if [ -n "${vhost_iommu_support}" ]; then dpdk_options+='options:vhost-iommu-support=${vhost_iommu_support} ' fi ovs-vsctl --db=unix:${OVS_SOCKET} --may-exist add-port ${bridge} ${port_name} \ -- set Interface ${port_name} type=dpdk options:dpdk-devargs=${pci_id} ${dpdk_options} done } function process_dpdk_bonds { target_driver=$(get_dpdk_config_value ${DPDK_CONFIG} '.driver') # loop over all bonds echo $DPDK_CONFIG | jq -r -c '.bonds[]' > /tmp/bonds_array while IFS= read -r bond; do local bond_name=$(get_dpdk_config_value ${bond} '.name') local dpdk_bridge=$(get_dpdk_config_value ${bond} '.bridge') local migrate_ip=$(get_dpdk_config_value ${bond} '.migrate_ip') local mtu=$(get_dpdk_config_value ${bond} '.mtu') local n_rxq=$(get_dpdk_config_value ${bond} '.n_rxq') local n_txq=$(get_dpdk_config_value ${bond} '.n_txq') local ofport_request=$(get_dpdk_config_value ${bond} '.ofport_request') local n_rxq_size=$(get_dpdk_config_value ${bond} '.n_rxq_size') local n_txq_size=$(get_dpdk_config_value ${bond} '.n_txq_size') local vhost_iommu_support=$(get_dpdk_config_value ${bond} '.vhost-iommu-support') local ovs_options=$(get_dpdk_config_value ${bond} '.ovs_options') local nic_name_str="" local dev_args_str="" local ip_migrated=false echo $bond | jq -r -c '.nics[]' > /tmp/nics_array while IFS= read -r nic; do local pci_id=$(get_dpdk_config_value ${nic} '.pci_id') local iface=$(get_dpdk_config_value ${nic} '.iface') if [ -n ${iface} ] && [ -z ${pci_id} ]; then local pci_id=$(get_address_by_nicname ${iface}) else iface=$(get_name_by_pci_id "${pci_id}") fi local nic_name=$(get_dpdk_config_value ${nic} '.name') local pmd_rxq_affinity=$(get_dpdk_config_value ${nic} '.pmd_rxq_affinity') local vf_index=$(get_dpdk_config_value ${nic} '.vf_index') local vf_string="" if [[ ${migrate_ip} = "true" && ${ip_migrated} = "false" ]]; then migrate_ip "${pci_id}" "${dpdk_bridge}" ip_migrated=true fi if [ -n "${iface}" ]; then ip link set ${iface} promisc on if [ -n "${vf_index}" ]; then vf_string="vf ${vf_index}" ip link set ${iface} ${vf_string} trust on ensure_vf_state "${iface}" "${vf_string}" "trust o(n|ff)" "trust on" # NOTE: To ensure proper toggle of spoofchk, # turn it on then off. ip link set ${iface} ${vf_string} spoofchk on ensure_vf_state "${iface}" "${vf_string}" "spoof checking o(n|ff)" "spoof checking on" ip link set ${iface} ${vf_string} spoofchk off ensure_vf_state "${iface}" "${vf_string}" "spoof checking o(n|ff)" "spoof checking off" fi fi # Fetch the PCI to be bound to DPDK driver. # In case VF Index is configured then PCI of that particular VF # is bound to DPDK, otherwise PF PCI is bound to DPDK. get_pf_or_vf_pci "${pci_id}" "${vf_index}" bind_dpdk_nic ${target_driver} "${dpdk_pci_id}" nic_name_str+=" "${nic_name}"" dev_args_str+=" -- set Interface "${nic_name}" type=dpdk options:dpdk-devargs=""${dpdk_pci_id}" if [[ -n ${mtu} ]]; then dev_args_str+=" -- set Interface "${nic_name}" mtu_request=${mtu}" fi if [[ -n ${n_rxq} ]]; then dev_args_str+=" -- set Interface "${nic_name}" options:n_rxq=${n_rxq}" fi if [[ -n ${n_txq} ]]; then dev_args_str+=" -- set Interface "${nic_name}" options:n_txq=${n_txq}" fi if [[ -n ${ofport_request} ]]; then dev_args_str+=" -- set Interface "${nic_name}" ofport_request=${ofport_request}" fi if [[ -n ${pmd_rxq_affinity} ]]; then dev_args_str+=" -- set Interface "${nic_name}" other_config:pmd-rxq-affinity=${pmd_rxq_affinity}" fi if [[ -n ${n_rxq_size} ]]; then dev_args_str+=" -- set Interface "${nic_name}" options:n_rxq_desc=${n_rxq_size}" fi if [[ -n ${n_txq_size} ]]; then dev_args_str+=" -- set Interface "${nic_name}" options:n_txq_desc=${n_txq_size}" fi if [[ -n ${vhost_iommu_support} ]]; then dev_args_str+=" -- set Interface "${nic_name}" options:vhost-iommu-support=${vhost_iommu_support}" fi done < /tmp/nics_array if [ "${UPDATE_DPDK_BOND_CONFIG}" == "true" ]; then echo -e "NOTE: UPDATE_DPDK_BOND_CONFIG is set to true.\ \nThis might cause disruptions in ovs traffic.\ \nTo avoid this disruption set UPDATE_DPDK_BOND_CONFIG to false." ovs-vsctl --db=unix:${OVS_SOCKET} set Bridge "${dpdk_bridge}" other_config:update_config=true ovs_update_config=true else ovs_update_config=$(ovs-vsctl --columns=other_config --no-heading -d json list bridge "${dpdk_bridge}" \ | jq -r '.[1][] as $list | if $list[0] == "update_config" then $list[1] else empty end') fi if [ "${ovs_update_config}" == "true" ] || [ "${ovs_update_config}" == "" ]; then ovs-vsctl --db=unix:${OVS_SOCKET} --if-exists del-port "${bond_name}" ovs-vsctl --db=unix:${OVS_SOCKET} set Bridge "${dpdk_bridge}" other_config:update_config=false ovs-vsctl --db=unix:${OVS_SOCKET} --may-exist add-bond "${dpdk_bridge}" "${bond_name}" \ ${nic_name_str} \ ${ovs_options} ${dev_args_str} fi done < "/tmp/bonds_array" } function set_dpdk_module_log_level { # loop over all target modules if [ -n "$(get_dpdk_config_value ${DPDK_CONFIG} '.modules')" ]; then echo $DPDK_CONFIG | jq -r -c '.modules[]' > /tmp/modules_array while IFS= read -r module; do local mod_name=$(get_dpdk_config_value ${module} '.name') local mod_level=$(get_dpdk_config_value ${module} '.log_level') ovs-appctl -t ${OVS_CTL} vlog/set ${mod_name}:${mod_level} ovs-appctl -t ${OVS_CTL} vlog/list|grep ${mod_name} done < /tmp/modules_array fi } function get_driver_by_address { if [[ -e /sys/bus/pci/devices/$1/driver ]]; then echo $(ls /sys/bus/pci/devices/$1/driver -al | awk '{n=split($NF,a,"/"); print a[n]}') fi } function get_address_by_nicname { if [[ -e /sys/class/net/$1 ]]; then local pci_address=$(readlink -f /sys/class/net/$1/device | xargs basename) if [[ -e /sys/bus/pci/devices/${pci_address} ]]; then echo ${pci_address} else echo "PCI id for interface $1 cannot be found" >&2 fi else echo "Interface name $1 cannot be found" >&2 fi } function init_ovs_dpdk_bridge { bridge=$1 ovs-vsctl --db=unix:${OVS_SOCKET} --may-exist add-br ${bridge} \ -- set Bridge ${bridge} datapath_type=netdev ip link set ${bridge} up } # create all additional bridges defined in the DPDK section function init_ovs_dpdk_bridges { for br in $(get_dpdk_config_value ${DPDK_CONFIG} '.bridges[].name'); do init_ovs_dpdk_bridge ${br} done } # handle any bridge mappings # /tmp/auto_bridge_add is one line json file: {"br-ex1":"eth1","br-ex2":"eth2"} for bmap in `sed 's/[{}"]//g' /tmp/auto_bridge_add | tr "," "\n"` do bridge=${bmap%:*} iface=${bmap#*:} if [[ "${DPDK_ENABLED}" == "true" ]]; then ovs-vsctl --db=unix:${OVS_SOCKET} --may-exist add-br $bridge -- set bridge $bridge datapath_type=netdev else ovs-vsctl --db=unix:${OVS_SOCKET} --may-exist add-br $bridge fi if [ -n "$iface" ] && [ "$iface" != "null" ] && ( ip link show $iface 1>/dev/null 2>&1 ); then ovs-vsctl --db=unix:${OVS_SOCKET} --may-exist add-port $bridge $iface migrate_ip_from_nic $iface $bridge if [[ "${DPDK_ENABLED}" != "true" ]]; then ip link set dev $iface up fi fi done tunnel_types="{{- .Values.conf.plugins.openvswitch_agent.agent.tunnel_types -}}" if [[ -n "${tunnel_types}" ]] ; then tunnel_interface="{{- .Values.network.interface.tunnel -}}" if [ -z "${tunnel_interface}" ] ; then # search for interface with tunnel network routing tunnel_network_cidr="{{- .Values.network.interface.tunnel_network_cidr -}}" if [ -z "${tunnel_network_cidr}" ] ; then tunnel_network_cidr="0/0" fi # If there is not tunnel network gateway, exit tunnel_interface=$(ip -4 route list ${tunnel_network_cidr} | awk -F 'dev' '{ print $2; exit }' \ | awk '{ print $1 }') || exit 1 fi fi if [[ "${DPDK_ENABLED}" == "true" ]]; then init_ovs_dpdk_bridges process_dpdk_nics process_dpdk_bonds set_dpdk_module_log_level fi # determine local-ip dynamically based on interface provided but only if tunnel_types is not null if [[ -n "${tunnel_types}" ]] ; then LOCAL_IP=$(get_ip_address_from_interface ${tunnel_interface}) if [ -z "${LOCAL_IP}" ] ; then echo "Var LOCAL_IP is empty" exit 1 fi tee > /tmp/pod-shared/ml2-local-ip.ini << EOF [ovs] local_ip = "${LOCAL_IP}" EOF if [[ "${DPDK_ENABLED}" == "true" ]]; then PREFIX=$(get_ip_prefix_from_interface "${tunnel_interface}") # loop over all nics echo $DPDK_CONFIG | jq -r -c '.bridges[]' | \ while IFS= read -r br; do bridge_name=$(get_dpdk_config_value ${br} '.name') tunnel_underlay_vlan=$(get_dpdk_config_value ${br} '.tunnel_underlay_vlan') if [[ "${bridge_name}" == "${tunnel_interface}" ]]; then # Route the tunnel traffic via the physical bridge if [[ -n "${LOCAL_IP}" && -n "${PREFIX}" ]]; then if [[ -n $(ovs-appctl -t ${OVS_CTL} ovs/route/show | grep "${LOCAL_IP}" | grep -v '^Cached:') ]]; then ovs-appctl -t ${OVS_CTL} ovs/route/del "${LOCAL_IP}"/"${PREFIX}" fi ovs-appctl -t ${OVS_CTL} ovs/route/add "${LOCAL_IP}"/"${PREFIX}" "${tunnel_interface}" if [[ -n "${tunnel_underlay_vlan}" ]]; then # If there is not tunnel network gateway, exit IFS=. read -r i1 i2 i3 i4 <<< "${LOCAL_IP}" IFS=. read -r xx m1 m2 m3 m4 <<< $(for a in $(seq 1 32); do if [ $(((a - 1) % 8)) -eq 0 ]; then echo -n .; fi; if [ $a -le ${PREFIX} ]; then echo -n 1; else echo -n 0; fi; done) tunnel_network_cidr=$(printf "%d.%d.%d.%d\n" "$((i1 & (2#$m1)))" "$((i2 & (2#$m2)))" "$((i3 & (2#$m3)))" "$((i4 & (2#$m4)))") || exit 1 # Put a new flow to tag all the tunnel traffic with configured vlan-id if [[ -n $(ovs-ofctl dump-flows "${tunnel_interface}" | grep "nw_dst=${tunnel_network_cidr}") ]]; then ovs-ofctl del-flows "${tunnel_interface}" "cookie=0x9999/-1, table=0, ip,nw_dst=${tunnel_network_cidr}" fi ovs-ofctl add-flow "${tunnel_interface}" "cookie=0x9999, table=0, priority=8, ip,nw_dst=${tunnel_network_cidr}, actions=mod_vlan_vid:${tunnel_underlay_vlan},NORMAL" fi fi break fi done fi fi {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-openvswitch-agent-liveness.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e /tmp/neutron-openvswitch-agent-readiness.sh python \ /tmp/health-probe.py \ --config-file \ /etc/neutron/neutron.conf \ --config-file \ /etc/neutron/plugins/ml2/openvswitch_agent.ini \ --agent-queue-name \ q-agent-notifier-tunnel-update \ {{- if .Values.pod.use_fqdn.neutron_agent }} --use-fqdn \ {{- end }} --liveness-probe ================================================ FILE: neutron/templates/bin/_neutron-openvswitch-agent-readiness.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e OVS_PID=$(cat /run/openvswitch/ovs-vswitchd.pid) OVS_CTL=/run/openvswitch/ovs-vswitchd.${OVS_PID}.ctl ovs-vsctl list-br | grep -q br-int [ -z "$(/usr/bin/ovs-vsctl show | grep error:)" ] {{ if .Values.conf.ovs_dpdk.enabled }} {{- if hasKey .Values.conf.ovs_dpdk "nics"}} # Check if port(s) and bridge(s) are configured. {{- range .Values.conf.ovs_dpdk.nics }} ovs-vsctl list-br | grep -q {{ .bridge }} ovs-vsctl list-ports {{ .bridge }} | grep -q {{ .name }} {{- end }} {{- end }} {{- if hasKey .Values.conf.ovs_dpdk "bonds"}} # Check if bond(s) and slave(s) are configured. {{- range .Values.conf.ovs_dpdk.bonds }} bond={{ .name }} ovs-appctl -t ${OVS_CTL} bond/list | grep -q ${bond} {{- range .nics }} ovs-appctl -t ${OVS_CTL} bond/show ${bond} | grep -q "slave {{ .name }}\|member {{ .name }}" {{- end }} {{- end }} {{- end }} {{ end }} ================================================ FILE: neutron/templates/bin/_neutron-openvswitch-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec neutron-openvswitch-agent \ --config-file /etc/neutron/neutron.conf \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} {{- if .Values.conf.plugins.openvswitch_agent.agent.tunnel_types }} --config-file /tmp/pod-shared/ml2-local-ip.ini \ {{- end }} {{- if .Values.conf.plugins.taas.taas.enabled }} --config-file /etc/neutron/plugins/ml2/taas.ini \ {{- end }} --config-file /etc/neutron/plugins/ml2/openvswitch_agent.ini \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-ovn-db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex neutron-ovn-db-sync-util \ --config-file /etc/neutron/neutron.conf \ {{- if ( has "ovn" .Values.network.backend ) }} --config-file /tmp/pod-shared/ovn.ini \ {{- end }} {{- if .Values.conf.plugins.taas.taas.enabled }} --config-file /etc/neutron/taas_plugin.ini \ {{- end }} {{- if ( has "sriov" .Values.network.backend ) }} --config-file /etc/neutron/plugins/ml2/sriov_agent.ini \ {{- end }} {{- if .Values.conf.plugins.l2gateway }} --config-file /etc/neutron/l2gw_plugin.ini \ {{- end }} --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ --config-dir /etc/neutron/neutron.conf.d \ --ovn-neutron_sync_mode "$1" ================================================ FILE: neutron/templates/bin/_neutron-ovn-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # See: https://bugs.launchpad.net/neutron/+bug/2028442 mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/ovn.ini << EOF [ovn] ovn_nb_connection={{ coalesce .Values.conf.plugins.ml2_conf.ovn.ovn_nb_connection "tcp:$OVN_OVSDB_NB_SERVICE_HOST:$OVN_OVSDB_NB_SERVICE_PORT_OVSDB" }} ovn_sb_connection={{ coalesce .Values.conf.plugins.ml2_conf.ovn.ovn_sb_connection "tcp:$OVN_OVSDB_SB_SERVICE_HOST:$OVN_OVSDB_SB_SERVICE_PORT_OVSDB" }} EOF ================================================ FILE: neutron/templates/bin/_neutron-ovn-metadata-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec neutron-ovn-metadata-agent \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/ovn_metadata_agent.ini \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} --config-file /tmp/pod-shared/ovn.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-ovn-vpn-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex chown ${NEUTRON_USER_UID} /var/lib/neutron/openstack-helm {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: neutron/templates/bin/_neutron-ovn-vpn-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec neutron-ovn-vpn-agent \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/neutron_vpnaas.conf \ --config-file /etc/neutron/neutron_ovn_vpn_agent.ini \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} --config-file /tmp/pod-shared/ovn.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-rpc-server.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec neutron-rpc-server \ --config-file /etc/neutron/neutron.conf \ {{- if ( has "ovn" .Values.network.backend ) }} --config-file /tmp/pod-shared/ovn.ini \ {{- end }} {{- if .Values.conf.plugins.taas.taas.enabled }} --config-file /etc/neutron/taas_plugin.ini \ {{- end }} {{- if ( has "sriov" .Values.network.backend ) }} --config-file /etc/neutron/plugins/ml2/sriov_agent.ini \ {{- end }} {{- if .Values.conf.plugins.l2gateway }} --config-file /etc/neutron/l2gw_plugin.ini \ {{- end }} --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ --config-dir /etc/neutron/neutron.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: neutron/templates/bin/_neutron-server.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { confs="--config-file /etc/neutron/neutron.conf" {{- if ( has "ovn" .Values.network.backend ) }} confs+=" --config-file /tmp/pod-shared/ovn.ini" {{- end }} {{- if contains "vpnaas" .Values.conf.neutron.DEFAULT.service_plugins }} confs+=" --config-file /etc/neutron/neutron_vpnaas.conf" {{- end }} {{- if contains "ovn-vpnaas" .Values.conf.neutron.DEFAULT.service_plugins }} confs+=" --config-file /etc/neutron/neutron_ovn_vpn_agent.ini" {{- end }} {{- if .Values.conf.plugins.taas.taas.enabled }} confs+=" --config-file /etc/neutron/taas_plugin.ini" {{- end }} {{- if ( has "sriov" .Values.network.backend ) }} confs+=" --config-file /etc/neutron/plugins/ml2/sriov_agent.ini" {{- end }} {{- if .Values.conf.plugins.l2gateway }} confs+=" --config-file /etc/neutron/l2gw_plugin.ini" {{- end }} confs+=" --config-file /etc/neutron/plugins/ml2/ml2_conf.ini" confs+=" --config-dir /etc/neutron/neutron.conf.d" exec uwsgi --ini /etc/neutron/neutron-api-uwsgi.ini --pyargv " $confs " } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: neutron/templates/bin/_neutron-sriov-agent-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} #NOTE: Please limit "besteffort" to dev env with mixed hardware computes only # For prod env, the target nic should be there, if not, script should error out. set -ex BESTEFFORT=false {{- if ( has "besteffort" .Values.conf.sriov_init ) }} set +e BESTEFFORT=true {{- end }} {{- range $k, $sriov := .Values.network.interface.sriov }} if [ "x{{ $sriov.num_vfs }}" != "x" ]; then echo "{{ $sriov.num_vfs }}" > /sys/class/net/{{ $sriov.device }}/device/sriov_numvfs else #NOTE(portdirect): Many NICs have difficulty creating more than n-1 over their # claimed limit, by default err on the side of caution and account for this # limitation. TOT_NUM_VFS=$(cat /sys/class/net/{{ $sriov.device }}/device/sriov_totalvfs) if [[ "$TOT_NUM_VFS" -le "0" ]]; then NUM_VFS="$TOT_NUM_VFS" else if [[ "$((TOT_NUM_VFS - 1 ))" -le "1" ]]; then NUM_VFS=1 else NUM_VFS="$((TOT_NUM_VFS - 1 ))" fi fi echo "${NUM_VFS}" > /sys/class/net/{{ $sriov.device }}/device/sriov_numvfs fi {{- if hasKey $sriov "qos" -}} {{- range $v, $qos := $sriov.qos }} echo "{{ $qos.share }}" > /sys/class/net/{{ $sriov.device }}/device/sriov/{{ $qos.vf_num }}/qos/share {{- end}} echo "1" > /sys/class/net/{{ $sriov.device }}/device/sriov/qos/apply {{- end }} # Set number of queues is best effort in case where VF is already binded, # NIC will not allow to set, in such case, a node reboot will allow all # VF to set properly. {{- if hasKey $sriov "queues_per_vf" }} set +e {{- range $v, $qvf := $sriov.queues_per_vf }} SMOKE=',' MIRROR=' ' SKIPLIST={{ $qvf.exclude_vf }} SKIPLIST=${SKIPLIST//$SMOKE/$MIRROR} NUMVF={{ $sriov.num_vfs }} for vf in `seq 0 $[$NUMVF - 1]` do if ! ( echo ${SKIPLIST[@]} | grep -q -w "$vf" ); then echo "{{ $qvf.num_queues }}" > /sys/class/net/{{ $sriov.device }}/device/sriov/$vf/num_queues fi done {{- end }} if ! $BESTEFFORT; then set -e fi {{- end }} {{- if $sriov.mtu }} ip link set dev {{ $sriov.device }} mtu {{ $sriov.mtu }} {{- end }} ip link set {{ $sriov.device }} up ip link show {{ $sriov.device }} {{- if $sriov.promisc }} promisc_mode="on" {{- else }} promisc_mode="off" {{- end }} ip link set {{ $sriov.device }} promisc ${promisc_mode} #NOTE(portdirect): get the bus that the port is on NIC_BUS=$(lshw -c network -businfo | awk '/{{ $sriov.device }}/ {print $1}') #NOTE(portdirect): get first port on the nic NIC_FIRST_PORT=$(lshw -c network -businfo | awk "/${NIC_BUS%%.*}/ { print \$2; exit }") #NOTE(portdirect): Enable promisc mode on the nic, by setting it for the 1st port ethtool --set-priv-flags ${NIC_FIRST_PORT} vf-true-promisc-support ${promisc_mode} {{- end }} {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} mkdir -p /tmp/pod-shared tee > /tmp/pod-shared/neutron-agent.ini << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} if $BESTEFFORT; then exit 0 fi ================================================ FILE: neutron/templates/bin/_neutron-sriov-agent.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec neutron-sriov-nic-agent \ --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini \ {{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }} --config-file /tmp/pod-shared/neutron-agent.ini \ {{- end }} {{- if .Values.conf.plugins.taas.taas.enabled }} --config-file /etc/neutron/plugins/ml2/taas.ini \ {{- end }} --config-file /etc/neutron/plugins/ml2/sriov_agent.ini \ --config-dir /etc/neutron/neutron.conf.d ================================================ FILE: neutron/templates/bin/_neutron-test-force-cleanup.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -ex if openstack project show "${OS_TEST_PROJECT_NAME}" --domain="${OS_TEST_PROJECT_DOMAIN_NAME}" ; then OS_TEST_PROJECT_ID=$(openstack project show "${OS_TEST_PROJECT_NAME}" -f value -c id --domain="${OS_TEST_PROJECT_DOMAIN_NAME}") ospurge --purge-project "${OS_TEST_PROJECT_ID}" openstack quota set "${OS_TEST_PROJECT_ID}" --networks "${NETWORK_QUOTA}" --ports "${PORT_QUOTA}" --routers "${ROUTER_QUOTA}" --subnets "${SUBNET_QUOTA}" --secgroups "${SEC_GROUP_QUOTA}" fi ================================================ FILE: neutron/templates/bin/_nginx.sh.tpl ================================================ #!/bin/sh set -xe COMMAND="${@:-start}" start () { envsubst < /etc/nginx/nginx.conf > /tmp/nginx.conf cat /tmp/nginx.conf nginx -t -c /tmp/nginx.conf exec nginx -c /tmp/nginx.conf } stop () { nginx -s stop } $COMMAND ================================================ FILE: neutron/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "network" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: neutron/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: neutron-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} health-probe.py: | {{ tuple "bin/_health-probe.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-dhcp-agent.sh: | {{ tuple "bin/_neutron-dhcp-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-dhcp-agent-init.sh: | {{ tuple "bin/_neutron-dhcp-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-l3-agent.sh: | {{ tuple "bin/_neutron-l3-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-l3-agent-init.sh: | {{ tuple "bin/_neutron-l3-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-linuxbridge-agent.sh: | {{ tuple "bin/_neutron-linuxbridge-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-linuxbridge-agent-init.sh: | {{ tuple "bin/_neutron-linuxbridge-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-linuxbridge-agent-init-modules.sh: | {{ tuple "bin/_neutron-linuxbridge-agent-init-modules.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-openvswitch-agent.sh: | {{ tuple "bin/_neutron-openvswitch-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-openvswitch-agent-init.sh: | {{ tuple "bin/_neutron-openvswitch-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-openvswitch-agent-init-modules.sh: | {{ tuple "bin/_neutron-openvswitch-agent-init-modules.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- if .Values.conf.netoffload.enabled }} neutron-openvswitch-agent-init-netoffload.sh: | {{ tuple "bin/_neutron-openvswitch-agent-init-netoffload.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} neutron-openvswitch-agent-readiness.sh: | {{ tuple "bin/_neutron-openvswitch-agent-readiness.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-openvswitch-agent-liveness.sh: | {{ tuple "bin/_neutron-openvswitch-agent-liveness.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-sriov-agent.sh: | {{ tuple "bin/_neutron-sriov-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-sriov-agent-init.sh: | {{ tuple "bin/_neutron-sriov-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-l2gw-agent.sh: | {{ tuple "bin/_neutron-l2gw-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-bagpipe-bgp.sh: | {{ tuple "bin/_neutron-bagpipe-bgp.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-bagpipe-bgp-init.sh: | {{ tuple "bin/_neutron-bagpipe-bgp-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-bgp-dragent.sh: | {{ tuple "bin/_neutron-bgp-dragent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- if .Values.manifests.certificates }} nginx.sh: | {{ tuple "bin/_nginx.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} neutron-server.sh: | {{ tuple "bin/_neutron-server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-rpc-server.sh: | {{ tuple "bin/_neutron-rpc-server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-ironic-agent-init.sh: | {{ tuple "bin/_neutron-ironic-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-ironic-agent.sh: | {{ tuple "bin/_neutron-ironic-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-netns-cleanup-cron.sh: | {{ tuple "bin/_neutron-netns-cleanup-cron.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} neutron-test-force-cleanup.sh: | {{ tuple "bin/_neutron-test-force-cleanup.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-metadata-agent-init.sh: | {{ tuple "bin/_neutron-metadata-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- if ( has "ovn" .Values.network.backend ) }} neutron-ovn-db-sync.sh: | {{ tuple "bin/_neutron-ovn-db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-ovn-metadata-agent.sh: | {{ tuple "bin/_neutron-ovn-metadata-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-ovn-init.sh: | {{ tuple "bin/_neutron-ovn-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-ovn-vpn-agent-init.sh: | {{ tuple "bin/_neutron-ovn-vpn-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-ovn-vpn-agent.sh: | {{ tuple "bin/_neutron-ovn-vpn-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- else }} neutron-metadata-agent.sh: | {{ tuple "bin/_neutron-metadata-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- end }} ================================================ FILE: neutron/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- define "neutron.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty $envAll.Values.conf.neutron.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set $envAll.Values.conf.neutron.keystone_authtoken "auth_uri" -}} {{- end }} {{- if empty $envAll.Values.conf.neutron.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set $envAll.Values.conf.neutron.keystone_authtoken "auth_url" -}} {{- end }} {{- if empty $envAll.Values.conf.neutron.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set $envAll.Values.conf.neutron.keystone_authtoken "memcached_servers" -}} {{- end }} {{- if empty .Values.conf.neutron.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.neutron.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" $envAll.Values.conf.neutron.database.connection)) (empty $envAll.Values.conf.neutron.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "neutron" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.neutron.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.neutron.database "connection" $connection -}} {{- end -}} {{- end }} {{- if empty $envAll.Values.conf.neutron.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "neutron" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set $envAll.Values.conf.neutron.DEFAULT "transport_url" -}} {{- end }} {{- if empty $envAll.Values.conf.neutron.nova.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set $envAll.Values.conf.neutron.nova "auth_url" -}} {{- end }} {{- if empty $envAll.Values.conf.neutron.placement.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set $envAll.Values.conf.neutron.placement "auth_url" -}} {{- end }} {{- if empty $envAll.Values.conf.neutron.octavia.base_url -}} {{- $_ := tuple "load_balancer" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set $envAll.Values.conf.neutron.octavia "base_url" -}} {{- end }} {{- if empty $envAll.Values.conf.metadata_agent.DEFAULT.nova_metadata_host -}} {{- $_ := tuple "compute_metadata" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" | set $envAll.Values.conf.metadata_agent.DEFAULT "nova_metadata_host" -}} {{- end -}} {{- if empty $envAll.Values.conf.metadata_agent.DEFAULT.nova_metadata_port -}} {{- $_ := tuple "compute_metadata" "internal" "metadata" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $envAll.Values.conf.metadata_agent.DEFAULT "nova_metadata_port" }} {{- end -}} {{- if empty $envAll.Values.conf.metadata_agent.cache.memcache_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set $envAll.Values.conf.metadata_agent.cache "memcache_servers" -}} {{- end -}} {{- if empty $envAll.Values.conf.ovn_metadata_agent.DEFAULT.nova_metadata_host -}} {{- $_ := tuple "compute_metadata" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" | set $envAll.Values.conf.ovn_metadata_agent.DEFAULT "nova_metadata_host" -}} {{- end -}} {{- if empty $envAll.Values.conf.ovn_metadata_agent.cache.memcache_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set $envAll.Values.conf.ovn_metadata_agent.cache "memcache_servers" -}} {{- end -}} {{- if empty $envAll.Values.conf.ovn_metadata_agent.DEFAULT.nova_metadata_port -}} {{- $_ := tuple "compute_metadata" "internal" "metadata" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $envAll.Values.conf.ovn_metadata_agent.DEFAULT "nova_metadata_port" }} {{- end -}} {{- if empty $envAll.Values.conf.neutron.DEFAULT.interface_driver -}} {{- $_ := set $envAll.Values "__interface_driver" ( list ) }} {{- if ( has "openvswitch" $envAll.Values.network.backend ) -}} {{ $__interface_driver := append $envAll.Values.__interface_driver "openvswitch" }} {{- $_ := set $envAll.Values "__interface_driver" $__interface_driver }} {{- end -}} {{- if ( has "linuxbridge" $envAll.Values.network.backend ) -}} {{ $__interface_driver := append $envAll.Values.__interface_driver "linuxbridge" }} {{- $_ := set $envAll.Values "__interface_driver" $__interface_driver }} {{- end -}} {{- $_ := set $envAll.Values.conf.neutron.DEFAULT "interface_driver" $envAll.Values.__interface_driver -}} {{- end -}} {{- if empty $envAll.Values.conf.dhcp_agent.DEFAULT.interface_driver -}} {{- $_ := set $envAll.Values "__interface_driver" ( list ) }} {{- if or ( has "openvswitch" $envAll.Values.network.backend ) ( has "ovn" $envAll.Values.network.backend ) -}} {{ $__interface_driver := append $envAll.Values.__interface_driver "openvswitch" }} {{- $_ := set $envAll.Values "__interface_driver" $__interface_driver }} {{- end -}} {{- if ( has "linuxbridge" $envAll.Values.network.backend ) -}} {{ $__interface_driver := append $envAll.Values.__interface_driver "linuxbridge" }} {{- $_ := set $envAll.Values "__interface_driver" $__interface_driver }} {{- end -}} {{- $_ := set $envAll.Values.conf.dhcp_agent.DEFAULT "interface_driver" $envAll.Values.__interface_driver -}} {{- end -}} {{- if and (has "ovn" $envAll.Values.network.backend) (empty $envAll.Values.conf.dhcp_agent.ovs.ovsdb_connection) -}} {{- $_ := set $envAll.Values.conf.dhcp_agent.ovs "ovsdb_connection" "unix:/run/openvswitch/db.sock" -}} {{- end -}} {{- if empty $envAll.Values.conf.l3_agent.DEFAULT.interface_driver -}} {{- $_ := set $envAll.Values "__interface_driver" ( list ) }} {{- if ( has "openvswitch" $envAll.Values.network.backend ) -}} {{ $__interface_driver := append $envAll.Values.__interface_driver "openvswitch" }} {{- $_ := set $envAll.Values "__interface_driver" $__interface_driver }} {{- end -}} {{- if ( has "linuxbridge" $envAll.Values.network.backend ) -}} {{ $__interface_driver := append $envAll.Values.__interface_driver "linuxbridge" }} {{- $_ := set $envAll.Values "__interface_driver" $__interface_driver }} {{- end -}} {{- $_ := set $envAll.Values.conf.l3_agent.DEFAULT "interface_driver" $envAll.Values.__interface_driver -}} {{- end -}} {{- if empty $envAll.Values.conf.plugins.ml2_conf.ml2.mechanism_drivers -}} {{- if (contains "vxlan" $envAll.Values.conf.plugins.ml2_conf.ml2.tenant_network_types) -}} {{- $_ := set $envAll.Values "__mechanism_drivers" (append $envAll.Values.network.backend "l2population") -}} {{- end -}} {{- $_ := set $envAll.Values.conf.plugins.ml2_conf.ml2 "mechanism_drivers" ($envAll.Values.__mechanism_drivers | default $envAll.Values.network.backend | uniq) -}} {{- end -}} {{- if empty .Values.conf.neutron.DEFAULT.bind_port -}} {{- $_ := tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.neutron.DEFAULT "bind_port" -}} {{- end -}} {{- if empty .Values.conf.neutron_api_uwsgi.uwsgi.processes -}} {{- $_ := set .Values.conf.neutron_api_uwsgi.uwsgi "processes" .Values.conf.neutron.DEFAULT.api_workers -}} {{- end -}} {{- if empty (index .Values.conf.neutron_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.neutron_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .deployment_name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} {{- if .Values.conf.ovs_dpdk.enabled -}} {{- $_ := set $envAll.Values.conf.plugins.openvswitch_agent.ovs "datapath_type" "netdev" -}} {{- if empty $envAll.Values.conf.plugins.openvswitch_agent.ovs.vhostuser_socket_dir -}} {{- $_ := set $envAll.Values.conf.plugins.openvswitch_agent.ovs "vhostuser_socket_dir" "/run/openvswitch/vhostuser" -}} {{- end -}} {{- end -}} {{/* Designate DNS driver */}} {{- if eq (.Values.conf.neutron.DEFAULT.external_dns_driver | default "") "designate" -}} {{- if empty .Values.conf.neutron.designate.auth_url -}} {{- $_ := tuple "dns" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.neutron.designate "auth_url" -}} {{- end -}} {{- end }} {{- if (has "baremetal" .Values.network.backend) -}} {{- if empty $envAll.Values.conf.neutron.ironic.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set $envAll.Values.conf.neutron.ironic "auth_url" -}} {{- end }} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: rally_tests.yaml: {{ toYaml $envAll.Values.conf.rally_tests.tests | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" $envAll.Values.conf.paste | b64enc }} policy.yaml: {{ toYaml $envAll.Values.conf.policy | b64enc }} neutron-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.neutron_api_uwsgi | b64enc }} neutron.conf: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.neutron | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api_audit_map.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.api_audit_map | b64enc }} dhcp_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.dhcp_agent | b64enc }} l3_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.l3_agent | b64enc }} metering_agent.ini: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.metering_agent | b64enc) }} taas_plugin.ini: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.taas_plugin | b64enc) }} ml2_conf.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.plugins.ml2_conf | b64enc }} ml2_conf_sriov.ini: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.plugins.ml2_conf_sriov | b64enc) }} taas.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.plugins.taas | b64enc }} l2gw_plugin.ini: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" .Values.conf.plugins.l2gateway | b64enc) }} macvtap_agent.ini: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.plugins.macvtap_agent | b64enc) }} linuxbridge_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.plugins.linuxbridge_agent | b64enc }} openvswitch_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.plugins.openvswitch_agent | b64enc }} sriov_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.plugins.sriov_agent | b64enc }} l2gw_agent.ini: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" .Values.conf.l2gateway_agent | b64enc) }} bagpipe_bgp.conf: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" .Values.conf.bagpipe_bgp | b64enc) }} bgp_dragent.ini: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" .Values.conf.bgp_dragent | b64enc) }} dnsmasq.conf: "{{ $envAll.Values.conf.dnsmasq | b64enc }}" neutron_sudoers: {{ $envAll.Values.conf.neutron_sudoers | b64enc }} rootwrap.conf: {{ $envAll.Values.conf.rootwrap | b64enc }} auto_bridge_add: {{ toJson $envAll.Values.conf.auto_bridge_add | b64enc }} neutron_vpnaas.conf: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.neutron_vpnaas | b64enc) }} {{- if .Values.conf.netoffload.enabled }} netoffload: {{ toJson $envAll.Values.conf.netoffload | b64enc }} {{- end }} dpdk.conf: {{ toJson $envAll.Values.conf.ovs_dpdk | b64enc }} update_dpdk_bond_config: {{ $envAll.Values.conf.ovs_dpdk.update_dpdk_bond_config | toString | b64enc }} {{- if ( has "ovn" .Values.network.backend ) }} neutron_ovn_vpn_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.ovn_vpn_agent | b64enc }} ovn_metadata_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.ovn_metadata_agent | b64enc }} {{- else }} metadata_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.metadata_agent | b64enc }} {{- end }} {{- if .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.values_template_renderer" ( dict "envAll" $envAll "template" .Values.conf.nginx "key" "nginx.conf" "format" "Secret" ) | indent 2 }} {{- end }} {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- $filePrefix := replace "_" "-" $key }} {{ printf "%s.filters" $filePrefix }}: {{ $value.content | b64enc }} {{- end }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "neutron-etc" . | include "neutron.configmap.etc" }} {{- end }} ================================================ FILE: neutron/templates/cron-job-ovn-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_ovn_db_sync }} {{- $envAll := . }} {{- $mounts_neutron_ovn_db_sync := .Values.pod.mounts.neutron_ovn_db_sync.neutron_ovn_db_sync }} {{- $mounts_neutron_ovn_db_sync_init := .Values.pod.mounts.neutron_ovn_db_sync.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_ovn_db_sync }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} {{- $serviceAccountName := "neutron-ovn-db-sync" }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: neutron-ovn-db-sync annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.ovn_db_sync.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.ovn_db_sync.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.ovn_db_sync.history.failed }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "neutron" "ovn-db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "neutron-ovn-db-sync" "containerNames" (list "init" "neutron-ovn-db-sync" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "neutron" "ovn-db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 12 }} {{ dict "envAll" $envAll "podName" "neutron-ovn-db-sync" "containerNames" (list "init" "neutron-ovn-db-sync" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "neutron_ovn_db_sync" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_ovn_db_sync" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "ovn_db_sync" $mounts_neutron_ovn_db_sync_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} - name: ovn-neutron-init {{ tuple $envAll "neutron_ovn_db_sync" | include "helm-toolkit.snippets.image" | indent 14 }} command: - /tmp/neutron-ovn-init.sh volumeMounts: - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-bin mountPath: /tmp/neutron-ovn-init.sh subPath: neutron-ovn-init.sh readOnly: true containers: - name: neutron-ovn-db-sync {{ tuple $envAll "neutron_ovn_db_sync" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ovn_db_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/neutron/certs/ca.crt" {{- end }} command: - /tmp/neutron-ovn-db-sync.sh - {{ quote .Values.jobs.ovn_db_sync.sync_mode }} volumeMounts: - name: neutron-bin mountPath: /tmp/neutron-ovn-db-sync.sh subPath: neutron-ovn-db-sync.sh readOnly: true - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{ if ( has "sriov" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/sriov_agent.ini subPath: sriov_agent.ini readOnly: true {{ end }} {{- if .Values.conf.plugins.taas.taas.enabled }} - name: neutron-etc mountPath: /etc/neutron/taas_plugin.ini subPath: taas_plugin.ini readOnly: true {{ end }} {{- if .Values.conf.plugins.l2gateway }} - name: neutron-etc mountPath: /etc/neutron/l2gw_plugin.ini subPath: l2gw_plugin.ini readOnly: true {{ end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.network.server.internal "path" "/etc/neutron/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} {{ if $mounts_neutron_ovn_db_sync.volumeMounts }}{{ toYaml $mounts_neutron_ovn_db_sync.volumeMounts | indent 14 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: pod-shared emptyDir: {} {{- if .Values.manifests.certificates }} - name: wsgi-neutron emptyDir: {} {{- end }} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: neutron-etc defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{ if $mounts_neutron_ovn_db_sync.volumes }}{{ toYaml $mounts_neutron_ovn_db_sync.volumes | indent 12 }}{{ end }} {{- end }} ================================================ FILE: neutron/templates/daemonset-bagpipe-bgp.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "bagpipeBgpLivenessProbeTemplate" }} tcpSocket: port: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "bagpipeBgpReadinessProbeTemplate" }} tcpSocket: port: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "neutron.bagpipe_bgp.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_bagpipe_bgp := .Values.pod.mounts.bagpipe_bgp.bagpipe_bgp }} {{- $mounts_neutron_bagpipe_bgp_init := .Values.pod.mounts.bagpipe_bgp.init_container }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: bagpipe-bgp annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "bagpipe-bgp" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "bagpipe-bgp" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "bagpipe_bgp" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "bagpipe-bgp" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_bagpipe_bgp" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_bagpipe_bgp" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "bagpipe_bgp" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "bagpipe_bgp" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.bagpipe_bgp.node_selector_key }}: {{ .Values.labels.bagpipe_bgp.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_bagpipe_bgp_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-bagpipe-bgp-init {{ tuple $envAll "neutron_bagpipe_bgp" | include "helm-toolkit.snippets.image" | indent 10 }} securityContext: privileged: true runAsUser: 0 command: - /tmp/neutron-bagpipe-bgp-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-bagpipe-bgp-init.sh subPath: neutron-bagpipe-bgp-init.sh readOnly: true - name: run mountPath: /run containers: - name: neutron-bagpipe-bgp {{ tuple $envAll "neutron_bagpipe_bgp" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.bagpipe_bgp | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_bagpipe_bgp" "container" "neutron_bagpipe_bgp" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "bagpipe_bgp" "container" "bagpipe_bgp" "type" "liveness" "probeTemplate" (include "bagpipeBgpLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "bagpipe_bgp" "container" "bagpipe_bgp" "type" "readiness" "probeTemplate" (include "bagpipeBgpReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-bagpipe-bgp.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-bagpipe-bgp.sh subPath: neutron-bagpipe-bgp.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /tmp/auto_bridge_add subPath: auto_bridge_add readOnly: true - name: neutron-etc mountPath: /etc/bagpipe-bgp/bgp.conf subPath: bagpipe_bgp.conf readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "bagpipe_bgp" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: libmodules mountPath: /lib/modules readOnly: true - name: run mountPath: /run {{ if $mounts_neutron_bagpipe_bgp.volumeMounts }}{{ toYaml $mounts_neutron_bagpipe_bgp.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: libmodules hostPath: path: /lib/modules - name: run hostPath: path: /run {{ if $mounts_neutron_bagpipe_bgp.volumes }}{{ toYaml $mounts_neutron_bagpipe_bgp.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_bagpipe_bgp }} {{- $envAll := . }} {{- $daemonset := "bagpipe-bgp" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-bagpipe-bgp" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "bagpipe_bgp" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.bagpipe_bgp.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-bgp-dragent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "bgp_dragentLivenessProbeTemplate" }} exec: command: - bash - -c - pidof -x /var/lib/openstack/bin/neutron-bgp-dragent {{- end }} {{- define "neutron.bgp_dragent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_bgp_dragent := .Values.pod.mounts.bgp_dragent.bgp_dragent }} {{- $mounts_neutron_bgp_dragent_init := .Values.pod.mounts.bgp_dragent.init_container }} {{- $etcSources := .Values.pod.etcSources.bgp_dragent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: bgp-dragent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "bgp-dragent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "bgp-dragent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "bgp_dragent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "bgp-dragent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_bgp_dragent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_bgp_dragent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "bgp_dragent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "bgp_dragent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.bgp_dragent.node_selector_key }}: {{ .Values.labels.bgp_dragent.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} containers: - name: neutron-bgp-dragent {{ tuple $envAll "neutron_bgp_dragent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.bgp_dragent | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_bgp_dragent" "container" "neutron_bgp_dragent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "bgp_dragent" "container" "bgp_dragent" "type" "liveness" "probeTemplate" (include "bgp_dragentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-bgp-dragent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-bgp-dragent.sh subPath: neutron-bgp-dragent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/bgp_dragent.ini subPath: bgp_dragent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "bgp_dragent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: libmodules mountPath: /lib/modules readOnly: true - name: run mountPath: /run {{ if $mounts_neutron_bgp_dragent.volumeMounts }}{{ toYaml $mounts_neutron_bgp_dragent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: libmodules hostPath: path: /lib/modules - name: run hostPath: path: /run {{ if $mounts_neutron_bgp_dragent.volumes }}{{ toYaml $mounts_neutron_bgp_dragent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_bgp_dragent }} {{- $envAll := . }} {{- $daemonset := "bgp-dragent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-bgp-dragent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "bgp_dragent" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.bgp_dragent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-dhcp-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "dhcpAgentReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/dhcp_agent.ini - --agent-queue-name - dhcp_agent {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "dhcpAgentLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/dhcp_agent.ini - --agent-queue-name - dhcp_agent {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "neutron.dhcp_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_dhcp_agent := .Values.pod.mounts.neutron_dhcp_agent.neutron_dhcp_agent }} {{- $mounts_neutron_dhcp_agent_init := .Values.pod.mounts.neutron_dhcp_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_dhcp_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-dhcp-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "dhcp-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "dhcp-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "dhcp_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "dhcp-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_dhcp_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "neutron-dhcp-agent-default" "containerNames" (list "neutron-dhcp-agent" "neutron-dhcp-agent-init" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_dhcp_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_dhcp_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_dhcp_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.agent.dhcp.node_selector_key }}: {{ .Values.labels.agent.dhcp.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_dhcp_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if ( has "ovn" .Values.network.backend ) }} - name: ovn-neutron-init {{ tuple $envAll "neutron_dhcp" | include "helm-toolkit.snippets.image" | indent 10 }} command: - /tmp/neutron-ovn-init.sh volumeMounts: - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-bin mountPath: /tmp/neutron-ovn-init.sh subPath: neutron-ovn-init.sh readOnly: true {{- end }} - name: neutron-dhcp-agent-init {{ tuple $envAll "neutron_dhcp" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.dhcp | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_dhcp_agent" "container" "neutron_dhcp_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-dhcp-agent-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-bin mountPath: /tmp/neutron-dhcp-agent-init.sh subPath: neutron-dhcp-agent-init.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/dhcp_agent.ini subPath: dhcp_agent.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/metadata_agent.ini subPath: metadata_agent.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /tmp/auto_bridge_add subPath: auto_bridge_add readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "dhcp_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} containers: - name: neutron-dhcp-agent {{ tuple $envAll "neutron_dhcp" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.dhcp | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_dhcp_agent" "container" "neutron_dhcp_agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "dhcp_agent" "container" "dhcp_agent" "type" "readiness" "probeTemplate" (include "dhcpAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "dhcp_agent" "container" "dhcp_agent" "type" "liveness" "probeTemplate" (include "dhcpAgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-dhcp-agent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-dhcp-agent.sh subPath: neutron-dhcp-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{- if ( has "openvswitch" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/dhcp_agent.ini subPath: dhcp_agent.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/dnsmasq.conf subPath: dnsmasq.conf readOnly: true - name: neutron-etc mountPath: /etc/neutron/metadata_agent.ini subPath: metadata_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "dhcp_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: iptables-lockfile mountPath: /run/xtables.lock - name: socket mountPath: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns mountPath: /run/netns mountPropagation: Bidirectional {{- end }} {{- if ( has "ovn" .Values.network.backend ) }} - name: run-openvswitch mountPath: /run/openvswitch {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_dhcp_agent.volumeMounts }}{{ toYaml $mounts_neutron_dhcp_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: iptables-lockfile hostPath: path: /run/xtables.lock type: FileOrCreate - name: socket hostPath: path: /var/lib/neutron/openstack-helm - name: pod-shared emptyDir: {} {{- if .Values.network.share_namespaces }} - name: host-run-netns hostPath: path: /run/netns {{- end }} {{- if ( has "ovn" .Values.network.backend ) }} - name: run-openvswitch hostPath: path: /run/openvswitch {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_dhcp_agent.volumes }}{{ toYaml $mounts_neutron_dhcp_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_dhcp_agent }} {{- $envAll := . }} {{- $daemonset := "dhcp-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-dhcp-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "dhcp" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.dhcp_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-l2gw-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "l2gwAgentLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/l2gw_agent.ini - --agent-queue-name - l2gateway_agent - --liveness-probe {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "l2gwAgentReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/l2gw_agent.ini - --agent-queue-name - l2gateway_agent {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "neutron.l2gw_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_l2gw_agent := .Values.pod.mounts.neutron_l2gw_agent.neutron_l2gw_agent }} {{- $mounts_neutron_l2gw_agent_init := .Values.pod.mounts.neutron_l2gw_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_l2gw_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-l2gw-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "l2gw-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "l2gw-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "l2gw_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "l2gw-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_l2gw_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_l2gw_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_l2gw_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_l2gw_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.agent.l2gw.node_selector_key }}: {{ .Values.labels.agent.l2gw.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_l2gw_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: neutron-l2gw-agent {{ tuple $envAll "neutron_l2gw" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.l2gw | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_l2gw_agent" "container" "neutron_l2gw_agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "l2gw_agent" "container" "l2gw_agent" "type" "liveness" "probeTemplate" (include "l2gwAgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "l2gw_agent" "container" "l2gw_agent" "type" "readiness" "probeTemplate" (include "l2gwAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-l2gw-agent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-l2gw-agent.sh subPath: neutron-l2gw-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/l2gw_agent.ini subPath: l2gw_agent.ini readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_l2gw_agent.volumeMounts }}{{ toYaml $mounts_neutron_l2gw_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_l2gw_agent.volumes }}{{ toYaml $mounts_neutron_l2gw_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_l2gw_agent }} {{- $envAll := . }} {{- $daemonset := "l2gw-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-l2gw-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "l2gateway" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.l2gw_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-l3-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "l3AgentReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/l3_agent.ini - --agent-queue-name - l3_agent {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "l3AgentLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/l3_agent.ini - --agent-queue-name - l3_agent - --liveness-probe {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "neutron.l3_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_l3_agent := .Values.pod.mounts.neutron_l3_agent.neutron_l3_agent }} {{- $mounts_neutron_l3_agent_init := .Values.pod.mounts.neutron_l3_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_l3_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-l3-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "l3-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "l3-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "l3_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "l3-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_l3_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "neutron-l3-agent-default" "containerNames" (list "neutron-l3-agent" "init" "neutron-l3-agent-init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_l3_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_l3_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_l3_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.agent.l3.node_selector_key }}: {{ .Values.labels.agent.l3.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_l3_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-l3-agent-init {{ tuple $envAll "neutron_l3" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.l3 | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_l3_agent" "container" "neutron_l3_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-l3-agent-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-l3-agent-init.sh subPath: neutron-l3-agent-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-etc mountPath: /etc/neutron/l3_agent.ini subPath: l3_agent.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/metadata_agent.ini subPath: metadata_agent.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /tmp/auto_bridge_add subPath: auto_bridge_add readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "l3_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} containers: - name: neutron-l3-agent {{ tuple $envAll "neutron_l3" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.l3 | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_l3_agent" "container" "neutron_l3_agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "l3_agent" "container" "l3_agent" "type" "readiness" "probeTemplate" (include "l3AgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "l3_agent" "container" "l3_agent" "type" "liveness" "probeTemplate" (include "l3AgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-l3-agent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-l3-agent.sh subPath: neutron-l3-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{- if ( has "openvswitch" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/l3_agent.ini subPath: l3_agent.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/metadata_agent.ini subPath: metadata_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "l3_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: libmodules mountPath: /lib/modules readOnly: true - name: iptables-lockfile mountPath: /run/xtables.lock - name: socket mountPath: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns mountPath: /run/netns mountPropagation: Bidirectional {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_l3_agent.volumeMounts }}{{ toYaml $mounts_neutron_l3_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: libmodules hostPath: path: /lib/modules - name: iptables-lockfile hostPath: path: /run/xtables.lock type: FileOrCreate - name: pod-shared emptyDir: {} - name: socket hostPath: path: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns hostPath: path: /run/netns {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_l3_agent.volumes }}{{ toYaml $mounts_neutron_l3_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_l3_agent }} {{- $envAll := . }} {{- $daemonset := "l3-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-l3-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "l3" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.l3_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-lb-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "lbAgentReadinessProbeTemplate" }} exec: command: - bash - -c - 'brctl show' {{- end }} {{- define "neutron.lb_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_lb_agent := .Values.pod.mounts.neutron_lb_agent.neutron_lb_agent }} {{- $mounts_neutron_lb_agent_init := .Values.pod.mounts.neutron_lb_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_lb_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-lb-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "neutron-lb-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "neutron-lb-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "lb_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "neutron-lb-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_lb_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_lb_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_lb_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_lb_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.lb.node_selector_key }}: {{ .Values.labels.lb.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_lb_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-lb-agent-kernel-modules {{ tuple $envAll "neutron_linuxbridge_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_lb_agent" "container" "neutron_lb_agent_kernel_modules" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-linuxbridge-agent-init-modules.sh volumeMounts: - name: neutron-bin mountPath: /tmp/neutron-linuxbridge-agent-init-modules.sh subPath: neutron-linuxbridge-agent-init-modules.sh readOnly: true - name: host-rootfs mountPath: /mnt/host-rootfs mountPropagation: HostToContainer readOnly: true - name: neutron-lb-agent-init {{ tuple $envAll "neutron_linuxbridge_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.lb | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_lb_agent" "container" "neutron_lb_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-linuxbridge-agent-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-linuxbridge-agent-init.sh subPath: neutron-linuxbridge-agent-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/linuxbridge_agent.ini subPath: linuxbridge_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /tmp/auto_bridge_add subPath: auto_bridge_add readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "lb_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: run mountPath: /run {{ if $mounts_neutron_lb_agent.volumeMounts }}{{ toYaml $mounts_neutron_lb_agent.volumeMounts | indent 12 }}{{ end }} containers: - name: neutron-lb-agent {{ tuple $envAll "neutron_linuxbridge_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.lb | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_lb_agent" "container" "neutron_lb_agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "lb_agent" "container" "lb_agent" "type" "readiness" "probeTemplate" (include "lbAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-linuxbridge-agent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-linuxbridge-agent.sh subPath: neutron-linuxbridge-agent.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/linuxbridge_agent.ini subPath: linuxbridge_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "lb_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: run mountPath: /run {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_lb_agent.volumeMounts }}{{ toYaml $mounts_neutron_lb_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: pod-shared emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: run hostPath: path: /run - name: host-rootfs hostPath: path: / {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_lb_agent.volumes }}{{ toYaml $mounts_neutron_lb_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if and .Values.manifests.daemonset_lb_agent ( has "linuxbridge" .Values.network.backend ) }} {{- $envAll := . }} {{- $daemonset := "lb-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-lb-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "lb_agent" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.lb_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-metadata-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadataAgentReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/metadata_agent.ini {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "metadataAgentLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/metadata_agent.ini - --liveness-probe {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "neutron.metadata_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_metadata_agent := .Values.pod.mounts.neutron_metadata_agent.neutron_metadata_agent }} {{- $mounts_neutron_metadata_agent_init := .Values.pod.mounts.neutron_metadata_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_metadata_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-metadata-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "metadata-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "metadata-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "metadata_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "metadata-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_metadata_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "neutron-metadata-agent-default" "containerNames" (list "neutron-metadata-agent" "neutron-metadata-agent-init" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_metadata_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_metadata_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_metadata_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.agent.metadata.node_selector_key }}: {{ .Values.labels.agent.metadata.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_metadata_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-metadata-agent-init {{ tuple $envAll "neutron_metadata" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_metadata_agent" "container" "neutron_metadata_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: NEUTRON_USER_UID value: "{{ .Values.pod.security_context.neutron_metadata_agent.pod.runAsUser }}" command: - /tmp/neutron-metadata-agent-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-metadata-agent-init.sh subPath: neutron-metadata-agent-init.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: socket mountPath: /var/lib/neutron/openstack-helm containers: - name: neutron-metadata-agent {{ tuple $envAll "neutron_metadata" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "metadata_agent" "container" "metadata_agent" "type" "readiness" "probeTemplate" (include "metadataAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "metadata_agent" "container" "metadata_agent" "type" "liveness" "probeTemplate" (include "metadataAgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} securityContext: privileged: true command: - /tmp/neutron-metadata-agent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-metadata-agent.sh subPath: neutron-metadata-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{- if ( has "openvswitch" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/metadata_agent.ini subPath: metadata_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "metadata_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: socket mountPath: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns mountPath: /run/netns mountPropagation: Bidirectional {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_metadata_agent.volumeMounts }}{{ toYaml $mounts_neutron_metadata_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: socket hostPath: path: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns hostPath: path: /run/netns {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_metadata_agent.volumes }}{{ toYaml $mounts_neutron_metadata_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_metadata_agent }} {{- $envAll := . }} {{- $daemonset := "metadata-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-metadata-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "metadata" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.metadata_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-netns-cleanup-cron.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "neutron.netns_cleanup_cron.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_netns_cleanup_cron := .Values.pod.mounts.neutron_netns_cleanup_cron.neutron_netns_cleanup_cron }} {{- $mounts_neutron_netns_cleanup_cron_init := .Values.pod.mounts.neutron_netns_cleanup_cron.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_netns_cleanup_cron }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-netns-cleanup-cron annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "netns-cleanup-cron" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "netns-cleanup-cron" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "netns_cleanup_cron" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "netns-cleanup-cron" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_netns_cleanup_cron" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "neutron-netns-cleanup-cron-default" "containerNames" (list "neutron-netns-cleanup-cron" "init" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_netns_cleanup_cron" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_netns_cleanup_cron" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_netns_cleanup_cron" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.netns_cleanup_cron.node_selector_key }}: {{ .Values.labels.netns_cleanup_cron.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_netns_cleanup_cron_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: neutron-netns-cleanup-cron {{ tuple $envAll "neutron_netns_cleanup_cron" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.netns_cleanup_cron | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_netns_cleanup_cron" "container" "neutron_netns_cleanup_cron" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-netns-cleanup-cron.sh env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" false }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: neutron-bin mountPath: /tmp/neutron-netns-cleanup-cron.sh subPath: neutron-netns-cleanup-cron.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/dhcp_agent.ini subPath: dhcp_agent.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/l3_agent.ini subPath: l3_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "netns_cleanup_cron" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: libmodules mountPath: /lib/modules readOnly: true - name: iptables-lockfile mountPath: /run/xtables.lock - name: socket mountPath: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns mountPath: /run/netns mountPropagation: Bidirectional {{- end }} {{ if $mounts_neutron_netns_cleanup_cron.volumeMounts }}{{ toYaml $mounts_neutron_netns_cleanup_cron.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: libmodules hostPath: path: /lib/modules - name: iptables-lockfile hostPath: path: /run/xtables.lock type: FileOrCreate - name: socket hostPath: path: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns hostPath: path: /run/netns {{- end }} #{{ if $mounts_neutron_netns_cleanup_cron.volumes }}{{ toYaml $mounts_neutron_netns_cleanup_cron.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_netns_cleanup_cron}} {{- $envAll := . }} {{- $daemonset := "netns-cleanup-cron" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-netns-cleanup-cron" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "netns_cleanup_cron" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.netns_cleanup_cron.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-neutron-ovn-vpn-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovnVPNAgentReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/neutron_vpnaas.conf - --config-file - /etc/neutron/neutron_ovn_vpn_agent.ini {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "ovnVPNAgentLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/neutron_vpnaas.conf - --config-file - /etc/neutron/neutron_ovn_vpn_agent.ini - --liveness-probe {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "neutron.ovn_vpn_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_ovn_vpn_agent := .Values.pod.mounts.ovn_vpn_agent.ovn_vpn_agent }} {{- $mounts_ovn_vpn_agent_init := .Values.pod.mounts.ovn_vpn_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.ovn_vpn_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-ovn-vpn-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "ovn-vpn-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "ovn-vpn-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "ovn_vpn_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "ovn-vpn-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: {{ dict "envAll" $envAll "application" "ovn_vpn_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "ovn_vpn_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "ovn_vpn_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.agent.ovn_vpn.node_selector_key }}: {{ .Values.labels.agent.ovn_vpn.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_ovn_vpn_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: ovn-vpn-agent-init {{ tuple $envAll "neutron_ovn_vpn" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_vpn | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ovn_vpn_agent" "container" "ovn_vpn_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: NEUTRON_USER_UID value: "{{ .Values.pod.security_context.ovn_vpn_agent.pod.runAsUser }}" command: - /tmp/neutron-ovn-vpn-agent-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-ovn-vpn-agent-init.sh subPath: neutron-ovn-vpn-agent-init.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: socket mountPath: /var/lib/neutron/openstack-helm - name: ovn-neutron-init {{ tuple $envAll "neutron_ovn_vpn" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_vpn | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ovn_vpn_agent" "container" "ovn_vpn_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-ovn-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-ovn-init.sh subPath: neutron-ovn-init.sh readOnly: true containers: - name: neutron-ovn-vpn-agent {{ tuple $envAll "neutron_ovn_vpn" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_vpn | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "ovn_vpn_agent" "container" "ovn_vpn_agent" "type" "readiness" "probeTemplate" (include "ovnVPNAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "ovn_vpn_agent" "container" "ovn_vpn_agent" "type" "liveness" "probeTemplate" (include "ovnVPNAgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} securityContext: privileged: true command: - /tmp/neutron-ovn-vpn-agent.sh volumeMounts: - name: run mountPath: /run - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-ovn-vpn-agent.sh subPath: neutron-ovn-vpn-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{- if ( has "openvswitch" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/neutron_vpnaas.conf subPath: neutron_vpnaas.conf readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron_ovn_vpn_agent.ini subPath: neutron_ovn_vpn_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "ovn_vpn_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: socket mountPath: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns mountPath: /run/netns mountPropagation: Bidirectional {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_ovn_vpn_agent.volumeMounts }}{{ toYaml $mounts_ovn_vpn_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: run hostPath: path: /run - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: socket hostPath: path: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns hostPath: path: /run/netns {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_ovn_vpn_agent.volumes }}{{ toYaml $mounts_ovn_vpn_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_ovn_vpn_agent }} {{- $envAll := . }} {{- $daemonset := "ovn-vpn-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-ovn-vpn-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "ovn_vpn_agent" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.ovn_vpn_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-ovn-metadata-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovnMetadataAgentReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/ovn_metadata_agent.ini {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "ovnMetadataAgentLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/ovn_metadata_agent.ini - --liveness-probe {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "neutron.ovn_metadata_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_ovn_metadata_agent := .Values.pod.mounts.neutron_ovn_metadata_agent.neutron_ovn_metadata_agent }} {{- $mounts_neutron_ovn_metadata_agent_init := .Values.pod.mounts.neutron_ovn_metadata_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_ovn_metadata_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-ovn-metadata-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "ovn-metadata-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "ovn-metadata-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "ovn_metadata_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "ovn-metadata-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_ovn_metadata_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "neutron-ovn-metadata-agent-default" "containerNames" (list "neutron-ovn-metadata-agent" "neutron-ovn-metadata-agent-init" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_ovn_metadata_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_ovn_metadata_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_ovn_metadata_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.ovs.node_selector_key }}: {{ .Values.labels.ovs.node_selector_value }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_ovn_metadata_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-metadata-agent-init {{ tuple $envAll "neutron_metadata" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_metadata_agent" "container" "neutron_metadata_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: NEUTRON_USER_UID value: "{{ .Values.pod.security_context.neutron_metadata_agent.pod.runAsUser }}" command: - /tmp/neutron-metadata-agent-init.sh volumeMounts: - name: run-openvswitch mountPath: /run/openvswitch - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-metadata-agent-init.sh subPath: neutron-metadata-agent-init.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: socket mountPath: /var/lib/neutron/openstack-helm - name: ovn-neutron-init {{ tuple $envAll "neutron_metadata" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_metadata_agent" "container" "neutron_metadata_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-ovn-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-ovn-init.sh subPath: neutron-ovn-init.sh readOnly: true containers: - name: neutron-ovn-metadata-agent {{ tuple $envAll "neutron_metadata" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "ovn_metadata_agent" "container" "ovn_metadata_agent" "type" "readiness" "probeTemplate" (include "ovnMetadataAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "ovn_metadata_agent" "container" "ovn_metadata_agent" "type" "liveness" "probeTemplate" (include "ovnMetadataAgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} securityContext: privileged: true command: - /tmp/neutron-ovn-metadata-agent.sh volumeMounts: - name: run-openvswitch mountPath: /run/openvswitch - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-ovn-metadata-agent.sh subPath: neutron-ovn-metadata-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{- if ( has "openvswitch" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/ovn_metadata_agent.ini subPath: ovn_metadata_agent.ini readOnly: true - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "ovn_metadata_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: socket mountPath: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns mountPath: /run/netns mountPropagation: Bidirectional {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_ovn_metadata_agent.volumeMounts }}{{ toYaml $mounts_neutron_ovn_metadata_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: run-openvswitch hostPath: path: /run/openvswitch - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: socket hostPath: path: /var/lib/neutron/openstack-helm {{- if .Values.network.share_namespaces }} - name: host-run-netns hostPath: path: /run/netns {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_ovn_metadata_agent.volumes }}{{ toYaml $mounts_neutron_ovn_metadata_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_ovn_metadata_agent }} {{- $envAll := . }} {{- $daemonset := "ovn-metadata-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-ovn-metadata-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "ovn_metadata" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.ovn_metadata_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-ovs-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovsAgentReadinessProbeTemplate" }} exec: command: - /tmp/neutron-openvswitch-agent-readiness.sh {{- end }} {{- define "ovsAgentLivenessProbeTemplate" }} exec: command: - /tmp/neutron-openvswitch-agent-liveness.sh {{- end }} {{- define "neutron.ovs_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_ovs_agent := .Values.pod.mounts.neutron_ovs_agent.neutron_ovs_agent }} {{- $mounts_neutron_ovs_agent_init := .Values.pod.mounts.neutron_ovs_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_ovs_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-ovs-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "neutron-ovs-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "neutron-ovs-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "ovs_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "neutron-ovs-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_ovs_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "$configMapName" "containerNames" (list "neutron-ovs-agent" "init" "neutron-openvswitch-agent-kernel-modules" "neutron-ovs-agent-init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_ovs_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_ovs_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_ovs_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.ovs.node_selector_key }}: {{ .Values.labels.ovs.node_selector_value }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_ovs_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-openvswitch-agent-kernel-modules {{ tuple $envAll "neutron_openvswitch_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_ovs_agent" "container" "neutron_openvswitch_agent_kernel_modules" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-openvswitch-agent-init-modules.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-openvswitch-agent-init-modules.sh subPath: neutron-openvswitch-agent-init-modules.sh readOnly: true - name: host-rootfs mountPath: /mnt/host-rootfs mountPropagation: HostToContainer readOnly: true {{- if .Values.conf.ovs_dpdk.enabled }} - name: pci-devices mountPath: /sys/bus/pci/devices {{- end }} {{- if .Values.conf.netoffload.enabled }} - name: netoffload {{ tuple $envAll "netoffload" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_ovs_agent" "container" "netoffload" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-openvswitch-agent-init-netoffload.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-openvswitch-agent-init-netoffload.sh subPath: neutron-openvswitch-agent-init-netoffload.sh readOnly: true - name: neutron-etc mountPath: /tmp/netoffload subPath: netoffload readOnly: true - name: run mountPath: /run {{- end }} - name: neutron-ovs-agent-init {{ tuple $envAll "neutron_openvswitch_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovs | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_ovs_agent" "container" "neutron_ovs_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if .Values.conf.ovs_dpdk.enabled }} env: - name: UPDATE_DPDK_BOND_CONFIG valueFrom: secretKeyRef: name: {{ $configMapName }} key: update_dpdk_bond_config {{- end }} command: - /tmp/neutron-openvswitch-agent-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-openvswitch-agent-init.sh subPath: neutron-openvswitch-agent-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} {{- if .Values.conf.plugins.taas.taas.enabled }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/taas.ini subPath: taas.ini readOnly: true {{- end }} - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /tmp/auto_bridge_add subPath: auto_bridge_add readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- if .Values.conf.ovs_dpdk.enabled }} - name: neutron-etc mountPath: /tmp/dpdk.conf subPath: dpdk.conf readOnly: true {{- end }} {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "ovs_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: run mountPath: /run {{ if $mounts_neutron_ovs_agent.volumeMounts }}{{ toYaml $mounts_neutron_ovs_agent.volumeMounts | indent 12 }}{{ end }} containers: - name: neutron-ovs-agent {{ tuple $envAll "neutron_openvswitch_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.ovs | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "ovs_agent" "container" "ovs_agent" "type" "readiness" "probeTemplate" (include "ovsAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "ovs_agent" "container" "ovs_agent" "type" "liveness" "probeTemplate" (include "ovsAgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_ovs_agent" "container" "neutron_ovs_agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-openvswitch-agent.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-openvswitch-agent.sh subPath: neutron-openvswitch-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/neutron-openvswitch-agent-readiness.sh subPath: neutron-openvswitch-agent-readiness.sh readOnly: true - name: neutron-bin mountPath: /tmp/neutron-openvswitch-agent-liveness.sh subPath: neutron-openvswitch-agent-liveness.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini subPath: openvswitch_agent.ini readOnly: true {{- if .Values.conf.plugins.taas.taas.enabled }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/taas.ini subPath: taas.ini readOnly: true {{- end }} - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "ovs_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: run mountPath: /run {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_ovs_agent.volumeMounts }}{{ toYaml $mounts_neutron_ovs_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: varlibopenvswitch emptyDir: {} - name: pod-shared emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: run hostPath: path: /run - name: host-rootfs hostPath: path: / {{- if .Values.conf.ovs_dpdk.enabled }} - name: pci-devices hostPath: path: /sys/bus/pci/devices type: Directory {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_ovs_agent.volumes }}{{ toYaml $mounts_neutron_ovs_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if and .Values.manifests.daemonset_ovs_agent ( has "openvswitch" .Values.network.backend ) }} {{- $envAll := . }} {{- $daemonset := "ovs-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-ovs-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "ovs_agent" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.ovs_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/daemonset-sriov-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "sriovAgentReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/neutron/neutron.conf - --config-file - /etc/neutron/sriov_agent.ini {{- if .Values.pod.use_fqdn.neutron_agent }} - --use-fqdn {{- end }} {{- end }} {{- define "neutron.sriov_agent.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_neutron_sriov_agent := .Values.pod.mounts.neutron_sriov_agent.neutron_sriov_agent }} {{- $mounts_neutron_sriov_agent_init := .Values.pod.mounts.neutron_sriov_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_sriov_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: neutron-sriov-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "neutron-sriov-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "neutron" "neutron-sriov-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "sriov_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "neutron-sriov-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_sriov_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "neutron-sriov-agent-default" "containerNames" (list "neutron-sriov-agent-init" "init" "neutron-sriov-agent") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_sriov_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_sriov_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_sriov_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.sriov.node_selector_key }}: {{ .Values.labels.sriov.node_selector_value }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} dnsPolicy: ClusterFirstWithHostNet hostNetwork: true {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} shareProcessNamespace: true {{- else }} hostPID: true {{- end }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_sriov_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-sriov-agent-init {{ tuple $envAll "neutron_sriov_agent_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.sriov | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_sriov_agent" "container" "neutron_sriov_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-sriov-agent-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/neutron-sriov-agent-init.sh subPath: neutron-sriov-agent-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/sriov_agent.ini subPath: sriov_agent.ini readOnly: true {{- if .Values.conf.plugins.taas.taas.enabled }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/taas.ini subPath: taas.ini readOnly: true {{- end }} - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "sriov_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: run mountPath: /run {{ if $mounts_neutron_sriov_agent.volumeMounts }}{{ toYaml $mounts_neutron_sriov_agent.volumeMounts | indent 12 }}{{ end }} containers: - name: neutron-sriov-agent {{ tuple $envAll "neutron_sriov_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.agent.sriov | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_sriov_agent" "container" "neutron_sriov_agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{ dict "envAll" $envAll "component" "sriov_agent" "container" "sriov_agent" "type" "readiness" "probeTemplate" (include "sriovAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-sriov-agent.sh volumeMounts: - mountPath: /sys/class/net name: host-sys-class-net - mountPath: /sys/devices name: host-sys-devices - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-sriov-agent.sh subPath: neutron-sriov-agent.sh readOnly: true - name: neutron-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/sriov_agent.ini subPath: sriov_agent.ini readOnly: true {{- if .Values.conf.plugins.taas.taas.enabled }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/taas.ini subPath: taas.ini readOnly: true {{- end }} - name: neutron-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_neutron_sudoers subPath: neutron_sudoers readOnly: true - name: neutron-etc mountPath: /etc/neutron/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "sriov_agent" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }} - name: neutron-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: run mountPath: /run {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_sriov_agent.volumeMounts }}{{ toYaml $mounts_neutron_sriov_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: host-sys-class-net hostPath: path: /sys/class/net - name: host-sys-devices hostPath: path: /sys/devices - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: pod-shared emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: run hostPath: path: /run {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_sriov_agent.volumes }}{{ toYaml $mounts_neutron_sriov_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if and .Values.manifests.daemonset_sriov_agent ( has "sriov" .Values.network.backend ) }} {{- $envAll := . }} {{- $daemonset := "sriov-agent" }} {{- $configMapName := "neutron-etc" }} {{- $serviceAccountName := "neutron-sriov-agent" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "sriov_agent" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.sriov_agent.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "neutron.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: neutron/templates/deployment-ironic-agent.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_ironic_agent }} {{- $envAll := . }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "ironic_agent" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{- $mounts_neutron_ironic_agent := .Values.pod.mounts.neutron_ironic_agent.neutron_ironic_agent }} {{- $mounts_neutron_ironic_agent_init := .Values.pod.mounts.neutron_ironic_agent.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_ironic_agent }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} {{- $serviceAccountName := "neutron-ironic-agent" }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: neutron-ironic-agent annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "ironic-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.ironic_agent }} selector: matchLabels: {{ tuple $envAll "neutron" "ironic-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "ironic-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_ironic_agent" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_ironic_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_ironic_agent" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_ironic_agent" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "neutron" "ironic_agent" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.ironic_agent.node_selector_key }}: {{ .Values.labels.ironic_agent.node_selector_value }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 8 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.ironic_agent.timeout | default "30" }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_ironic_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: neutron-ironic-agent-init {{ tuple $envAll "neutron_ironic_agent_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ironic_agent | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_ironic_agent" "container" "neutron_ironic_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-ironic-agent-init.sh volumeMounts: - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-bin mountPath: /tmp/neutron-ironic-agent-init.sh subPath: neutron-ironic-agent-init.sh readOnly: true containers: - name: neutron-ironic-agent {{ tuple $envAll "neutron_ironic_agent" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ironic_agent | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_ironic_agent" "container" "neutron_ironic_agent" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-ironic-agent.sh - start lifecycle: preStop: exec: command: - /tmp/neutron-ironic-agent.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-bin mountPath: /tmp/neutron-ironic-agent.sh subPath: neutron-ironic-agent.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_ironic_agent.volumeMounts }}{{ toYaml $mounts_neutron_ironic_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-neutron emptyDir: {} - name: pod-shared emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: neutron-etc defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_ironic_agent.volumes }}{{ toYaml $mounts_neutron_ironic_agent.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: neutron/templates/deployment-rpc_server.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_rpc_server }} {{- $envAll := . }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "server" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{- $mounts_neutron_rpc_server := .Values.pod.mounts.neutron_rpc_server.neutron_rpc_server }} {{- $mounts_neutron_rpc_server_init := .Values.pod.mounts.neutron_rpc_server.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_rpc_server }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} {{- $serviceAccountName := "neutron-rpc-server" }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: neutron-rpc-server annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "rpc_server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.rpc_server }} selector: matchLabels: {{ tuple $envAll "neutron" "rpc_server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "rpc_server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "neutron-rpc-server" "containerNames" (list "neutron-rpc-server" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_rpc_server" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_rpc_server" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_rpc_server" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "neutron" "rpc_server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.rpc_server.node_selector_key }}: {{ .Values.labels.rpc_server.node_selector_value }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.rpc_server.timeout | default "30" }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_rpc_server_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if ( has "ovn" .Values.network.backend ) }} - name: ovn-neutron-init {{ tuple $envAll "neutron_rpc_server" | include "helm-toolkit.snippets.image" | indent 10 }} command: - /tmp/neutron-ovn-init.sh volumeMounts: - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-bin mountPath: /tmp/neutron-ovn-init.sh subPath: neutron-ovn-init.sh readOnly: true {{- end }} containers: - name: neutron-rpc-server {{ tuple $envAll "neutron_rpc_server" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.rpc_server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_rpc_server" "container" "neutron_rpc_server" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/neutron-rpc-server.sh - start {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/neutron/certs/ca.crt" {{- end }} lifecycle: preStop: exec: command: - /tmp/neutron-rpc-server.sh - stop ports: - name: q-api containerPort: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: pod-shared mountPath: /tmp/pod-shared - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-rpc-server.sh subPath: neutron-rpc-server.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron-api-uwsgi.ini subPath: neutron-api-uwsgi.ini readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/api_audit_map.conf subPath: api_audit_map.conf readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{ if ( has "sriov" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/sriov_agent.ini subPath: sriov_agent.ini readOnly: true {{ end }} {{- if .Values.conf.plugins.taas.taas.enabled }} - name: neutron-etc mountPath: /etc/neutron/taas_plugin.ini subPath: taas_plugin.ini readOnly: true {{ end }} {{- if .Values.conf.plugins.l2gateway }} - name: neutron-etc mountPath: /etc/neutron/l2gw_plugin.ini subPath: l2gw_plugin.ini readOnly: true {{ end }} - name: neutron-etc mountPath: /etc/neutron/api-paste.ini subPath: api-paste.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.network.server.internal "path" "/etc/neutron/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_rpc_server.volumeMounts }}{{ toYaml $mounts_neutron_rpc_server.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-shared emptyDir: {} {{- if .Values.manifests.certificates }} - name: wsgi-neutron emptyDir: {} {{- end }} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: neutron-etc defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_rpc_server.volumes }}{{ toYaml $mounts_neutron_rpc_server.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: neutron/templates/deployment-server.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "serverReadinessProbeTemplate" }} {{- if .Values.manifests.certificates }} exec: command: - python - -c - "import requests; r = requests.get('http://127.0.0.1:{{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}'); r.raise_for_status()" initialDelaySeconds: 30 {{- else }} httpGet: scheme: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- end }} {{- define "serverLivenessProbeTemplate" }} {{- if .Values.manifests.certificates }} exec: command: - python - -c - "import requests; r = requests.get('http://127.0.0.1:{{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}'); r.raise_for_status()" initialDelaySeconds: 30 {{- else }} httpGet: scheme: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / {{- if .Values.pod.probes.server.server.liveness.port }} port: {{ .Values.pod.probes.server.server.liveness.port }} {{ else }} port: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end}} {{- end }} {{- end }} {{- if .Values.manifests.deployment_server }} {{- $envAll := . }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "server" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{- $mounts_neutron_server := .Values.pod.mounts.neutron_server.neutron_server }} {{- $mounts_neutron_server_init := .Values.pod.mounts.neutron_server.init_container }} {{- $etcSources := .Values.pod.etcSources.neutron_server }} {{- if .Values.manifests.secret_ks_etc }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "neutron-ks-etc")) }} {{- end }} {{- $serviceAccountName := "neutron-server" }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: neutron-server annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.server }} selector: matchLabels: {{ tuple $envAll "neutron" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "neutron" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "neutron_server" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "neutron-server" "containerNames" (list "neutron-server" "init" "nginx") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "neutron_server" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} {{ tuple "neutron_server" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "neutron_server" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "neutron" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.server.timeout | default "30" }} initContainers: {{ tuple $envAll "pod_dependency" $mounts_neutron_server_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if ( has "ovn" .Values.network.backend ) }} - name: ovn-neutron-init {{ tuple $envAll "neutron_server" | include "helm-toolkit.snippets.image" | indent 10 }} command: - /tmp/neutron-ovn-init.sh volumeMounts: - name: pod-shared mountPath: /tmp/pod-shared - name: neutron-bin mountPath: /tmp/neutron-ovn-init.sh subPath: neutron-ovn-init.sh readOnly: true {{- end }} containers: {{- if $envAll.Values.manifests.certificates }} - name: nginx {{ tuple $envAll "nginx" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.nginx | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_server" "container" "nginx" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} ports: - name: q-api containerPort: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: PORT value: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: SHORTNAME value: {{ tuple "network" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" | quote }} readinessProbe: httpGet: scheme: HTTPS path: / port: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} command: - /tmp/nginx.sh - start lifecycle: preStop: exec: command: - /tmp/nginx.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.neutron.oslo_concurrency.lock_path }} - name: neutron-bin mountPath: /tmp/nginx.sh subPath: nginx.sh readOnly: true - name: neutron-etc mountPath: /etc/nginx/nginx.conf subPath: nginx.conf readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal "path" "/etc/nginx/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- end }} - name: neutron-server {{ tuple $envAll "neutron_server" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "neutron_server" "container" "neutron_server" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "server" "container" "server" "type" "readiness" "probeTemplate" (include "serverReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "server" "container" "server" "type" "liveness" "probeTemplate" (include "serverLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/neutron-server.sh - start {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/neutron/certs/ca.crt" {{- end }} lifecycle: preStop: exec: command: - /tmp/neutron-server.sh - stop {{- if not $envAll.Values.manifests.certificates }} ports: - name: q-api containerPort: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: pod-shared mountPath: /tmp/pod-shared - name: pod-var-neutron mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }} - name: neutron-bin mountPath: /tmp/neutron-server.sh subPath: neutron-server.sh readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: neutron-etc-snippets mountPath: /etc/neutron/neutron.conf.d/ readOnly: true - name: neutron-etc mountPath: /etc/neutron/neutron-api-uwsgi.ini subPath: neutron-api-uwsgi.ini readOnly: true {{- if .Values.conf.neutron.DEFAULT.log_config_append }} - name: neutron-etc mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: neutron-etc mountPath: /etc/neutron/api_audit_map.conf subPath: api_audit_map.conf readOnly: true - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true {{ if ( has "sriov" .Values.network.backend ) }} - name: neutron-etc mountPath: /etc/neutron/plugins/ml2/sriov_agent.ini subPath: sriov_agent.ini readOnly: true {{ end }} {{- if .Values.conf.plugins.taas.taas.enabled }} - name: neutron-etc mountPath: /etc/neutron/taas_plugin.ini subPath: taas_plugin.ini readOnly: true {{ end }} {{- if .Values.conf.plugins.l2gateway }} - name: neutron-etc mountPath: /etc/neutron/l2gw_plugin.ini subPath: l2gw_plugin.ini readOnly: true {{ end }} - name: neutron-etc mountPath: /etc/neutron/api-paste.ini subPath: api-paste.ini readOnly: true - name: neutron-etc mountPath: /etc/neutron/policy.yaml subPath: policy.yaml readOnly: true {{- if contains "vpnaas" .Values.conf.neutron.DEFAULT.service_plugins }} - name: neutron-etc mountPath: /etc/neutron/neutron_vpnaas.conf subPath: neutron_vpnaas.conf readOnly: true {{- end }} {{- if contains "ovn-vpnaas" .Values.conf.neutron.DEFAULT.service_plugins }} - name: neutron-etc mountPath: /etc/neutron/neutron_ovn_vpn_agent.ini subPath: neutron_ovn_vpn_agent.ini readOnly: true {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.network.server.internal "path" "/etc/neutron/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_server.volumeMounts }}{{ toYaml $mounts_neutron_server.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-shared emptyDir: {} {{- if .Values.manifests.certificates }} - name: wsgi-neutron emptyDir: {} {{- end }} - name: pod-var-neutron emptyDir: {} - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: neutron-etc secret: secretName: neutron-etc defaultMode: 0444 - name: neutron-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_server.volumes }}{{ toYaml $mounts_neutron_server.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: neutron/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: neutron/templates/ingress-server.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_server .Values.network.server.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "server" "backendServiceType" "network" "backendPort" "q-api" -}} {{- $secretName := $envAll.Values.secrets.tls.network.server.internal -}} {{- if and .Values.manifests.certificates $secretName }} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.network.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: neutron/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.bootstrap" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "5" {{- end }} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "neutron" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.neutron.DEFAULT.log_config_append -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} {{- end -}} {{- $_ := set $bootstrapJob "jobAnnotations" (include "metadata.annotations.job.bootstrap" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: neutron/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "neutron" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: neutron/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "neutron" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: neutron/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "neutron" "podVolMounts" .Values.pod.mounts.neutron_db_sync.neutron_db_sync.volumeMounts "podVols" .Values.pod.mounts.neutron_db_sync.neutron_db_sync.volumes -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: neutron/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "neutron" -}} {{- $_ := set $imageRepoSyncJob "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: neutron/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksEndpointsJob := dict "envAll" . "serviceName" "neutron" "serviceTypes" ( tuple "network" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksEndpointsJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} {{- end -}} {{- $_ := set $ksEndpointsJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $ksEndpointsJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksEndpointsJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: neutron/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "neutron" "serviceTypes" ( tuple "network" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: neutron/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $serviceUsers := (tuple "neutron" "nova" "placement") -}} {{- if eq (.Values.conf.neutron.DEFAULT.external_dns_driver | default "") "designate" -}} {{- $serviceUsers = append $serviceUsers "designate" -}} {{- end -}} {{- if (has "baremetal" .Values.network.backend) -}} {{- $serviceUsers = append $serviceUsers "ironic" -}} {{- end -}} {{- $ksUserJob := dict "envAll" . "serviceName" "neutron" "serviceUsers" $serviceUsers -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: neutron/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "neutron" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $rmqUserJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $rmqUserJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{- if .Values.pod.tolerations.neutron.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: neutron/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "neutron" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: neutron/templates/pdb-server.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_server }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: neutron-server spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.server.min_available }} selector: matchLabels: {{ tuple $envAll "neutron" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: neutron/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.neutron_tests.neutron_tests }} {{- $mounts_tests_init := .Values.pod.mounts.neutron_tests.init_container }} {{- $serviceAccountName := print .deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print .deployment_name "-test" }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "neutron" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ dict "envAll" $envAll "podName" "neutron-test" "containerNames" (list "init" "neutron-test" "neutron-test-ks-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.neutron.enabled }} {{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} restartPolicy: Never {{ tuple "neutron_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "neutron_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: neutron-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: neutron-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.Release.Name}} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: neutron-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: neutron-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: neutron-etc secret: secretName: neutron-etc defaultMode: 0444 - name: neutron-bin configMap: name: neutron-bin defaultMode: 0555 - name: rally-db emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: neutron/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "neutron" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: neutron/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendService" "server" "backendServiceType" "network" ) }} {{- end }} ================================================ FILE: neutron/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $userClass, $val := $envAll.Values.endpoints.identity.auth }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: neutron/templates/secret-ks-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ks_etc }} {{- $envAll := . -}} {{/* the endpoints.identity.auth sections with the oslo conf sections they get rendered to */}} {{- $ksUsers := dict "neutron" "keystone_authtoken" "nova" "nova" "placement" "placement" -}} {{- if eq (.Values.conf.neutron.DEFAULT.external_dns_driver | default "") "designate" -}} {{- $_ := set $ksUsers "designate" "designate" -}} {{- end -}} {{- if (has "baremetal" .Values.network.backend) -}} {{- $_ := set $ksUsers "ironic" "ironic" -}} {{- end -}} {{ dict "envAll" $envAll "serviceName" "neutron" "serviceUserSections" $ksUsers | include "helm-toolkit.manifests.secret_ks_etc" }} {{- end }} ================================================ FILE: neutron/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "neutron" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: neutron/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: neutron/templates/service-ingress-neutron.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_server .Values.network.server.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "network" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: neutron/templates/service-server.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_server }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "network" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: q-api port: {{ tuple "network" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.server.node_port.enabled }} nodePort: {{ .Values.network.server.node_port.port }} {{ end }} selector: {{ tuple $envAll "neutron" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.server.node_port.enabled }} type: NodePort {{ if .Values.network.server.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: neutron/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for neutron. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble test: docker.io/xrally/xrally-openstack:2.0.0 db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble neutron_db_sync: quay.io/airshipit/neutron:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble netoffload: ghcr.io/vexxhost/netoffload:v1.0.1 neutron_server: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_rpc_server: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_dhcp: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_metadata: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_ovn_metadata: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_ovn_db_sync: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_ovn_vpn: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_l3: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_l2gw: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_openvswitch_agent: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_linuxbridge_agent: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_sriov_agent: quay.io/airshipit/neutron:stein-18.04-sriov neutron_sriov_agent_init: quay.io/airshipit/neutron:stein-18.04-sriov neutron_bagpipe_bgp: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_bgp_dragent: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_ironic_agent_init: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_ironic_agent: quay.io/airshipit/neutron:2025.1-ubuntu_noble neutron_netns_cleanup_cron: quay.io/airshipit/neutron:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: agent: dhcp: node_selector_key: openstack-control-plane node_selector_value: enabled l3: node_selector_key: openstack-control-plane node_selector_value: enabled metadata: node_selector_key: openstack-control-plane node_selector_value: enabled l2gw: node_selector_key: openstack-control-plane node_selector_value: enabled ovn_vpn: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled lb: node_selector_key: linuxbridge node_selector_value: enabled # openvswitch is a special case, requiring a special # label that can apply to both control hosts # and compute hosts, until we get more sophisticated # with our daemonset scheduling ovs: node_selector_key: openvswitch node_selector_value: enabled sriov: node_selector_key: sriov node_selector_value: enabled bagpipe_bgp: node_selector_key: openstack-compute-node node_selector_value: enabled bgp_dragent: node_selector_key: openstack-compute-node node_selector_value: enabled server: node_selector_key: openstack-control-plane node_selector_value: enabled rpc_server: node_selector_key: openstack-control-plane node_selector_value: enabled ironic_agent: node_selector_key: openstack-control-plane node_selector_value: enabled netns_cleanup_cron: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled network: # provide what type of network wiring will be used backend: - openvswitch # NOTE(Portdirect): Share network namespaces with the host, # allowing agents to be restarted without packet loss and simpler # debugging. This feature requires mount propagation support. share_namespaces: true interface: # Tunnel interface will be used for VXLAN tunneling. tunnel: null # If tunnel is null there is a fallback mechanism to search # for interface with routing using tunnel network cidr. tunnel_network_cidr: "0/0" # To perform setup of network interfaces using the SR-IOV init # container you can use a section similar to: # sriov: # - device: ${DEV} # num_vfs: 8 # mtu: 9214 # promisc: false # qos: # - vf_num: 0 # share: 10 # queues_per_vf: # - num_queues: 16 # exclude_vf: 0,11,21 server: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30096 bootstrap: enabled: false ks_user: neutron script: | openstack token issue dependencies: dynamic: common: local_image_registry: jobs: - neutron-image-repo-sync services: - endpoint: node service: local_image_registry targeted: sriov: {} l2gateway: {} bagpipe_bgp: {} ovn: server: pod: null bgp_dragent: {} openvswitch: dhcp: pod: - requireSameNode: true labels: application: neutron component: neutron-ovs-agent l3: pod: - requireSameNode: true labels: application: neutron component: neutron-ovs-agent metadata: pod: - requireSameNode: true labels: application: neutron component: neutron-ovs-agent linuxbridge: dhcp: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent l3: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent metadata: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent lb_agent: pod: null static: bootstrap: services: - endpoint: internal service: network - endpoint: internal service: compute db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - neutron-db-init services: - endpoint: internal service: oslo_db dhcp: pod: null jobs: - neutron-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: network - endpoint: internal service: compute ks_endpoints: jobs: - neutron-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - service: oslo_messaging endpoint: internal l3: pod: null jobs: - neutron-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: network - endpoint: internal service: compute lb_agent: pod: null jobs: - neutron-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: network metadata: pod: null jobs: - neutron-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: network - endpoint: internal service: compute - endpoint: internal service: compute_metadata ovn_metadata: pod: - requireSameNode: true labels: application: ovn component: ovn-controller services: - endpoint: internal service: compute_metadata - endpoint: internal service: network ovn_vpn_agent: pod: - requireSameNode: true labels: application: ovn component: ovn-controller services: - endpoint: internal service: oslo_messaging - endpoint: internal service: network ovs_agent: jobs: - neutron-rabbit-init pod: - requireSameNode: true labels: application: openvswitch component: server services: - endpoint: internal service: oslo_messaging - endpoint: internal service: network server: jobs: - neutron-db-sync - neutron-ks-user - neutron-ks-endpoints - neutron-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_cache - endpoint: internal service: identity rpc_server: jobs: - neutron-db-sync - neutron-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_cache - endpoint: internal service: identity ironic_agent: jobs: - neutron-db-sync - neutron-ks-user - neutron-ks-endpoints - neutron-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_cache - endpoint: internal service: identity tests: services: - endpoint: internal service: network - endpoint: internal service: compute image_repo_sync: services: - endpoint: internal service: local_image_registry pod: use_fqdn: neutron_agent: true probes: rpc_timeout: 60 rpc_retries: 2 dhcp_agent: dhcp_agent: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 190 timeoutSeconds: 185 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 600 timeoutSeconds: 580 l3_agent: l3_agent: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 190 timeoutSeconds: 185 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 600 timeoutSeconds: 580 lb_agent: lb_agent: readiness: enabled: true metadata_agent: metadata_agent: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 190 timeoutSeconds: 185 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 600 timeoutSeconds: 580 ovn_vpn_agent: ovn_vpn_agent: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 190 timeoutSeconds: 185 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 600 timeoutSeconds: 580 ovn_metadata_agent: ovn_metadata_agent: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 190 timeoutSeconds: 185 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 600 timeoutSeconds: 580 ovs_agent: ovs_agent: readiness: enabled: true params: timeoutSeconds: 10 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 600 timeoutSeconds: 580 sriov_agent: sriov_agent: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 190 timeoutSeconds: 185 bagpipe_bgp: bagpipe_bgp: readiness: enabled: true params: liveness: enabled: true params: initialDelaySeconds: 60 bgp_dragent: bgp_dragent: readiness: enabled: false params: liveness: enabled: true params: initialDelaySeconds: 60 l2gw_agent: l2gw_agent: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 15 timeoutSeconds: 65 liveness: enabled: true params: initialDelaySeconds: 120 periodSeconds: 90 timeoutSeconds: 70 server: server: readiness: enabled: true params: periodSeconds: 15 timeoutSeconds: 10 liveness: enabled: true port: 1717 params: initialDelaySeconds: 60 periodSeconds: 15 timeoutSeconds: 10 rpc_server: rpc_server: readiness: enabled: true params: periodSeconds: 15 timeoutSeconds: 10 liveness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 15 timeoutSeconds: 10 security_context: neutron_dhcp_agent: pod: runAsUser: 42424 container: neutron_dhcp_agent: readOnlyRootFilesystem: true privileged: true neutron_l2gw_agent: pod: runAsUser: 42424 container: neutron_l2gw_agent: readOnlyRootFilesystem: true privileged: true neutron_bagpipe_bgp: pod: runAsUser: 42424 container: neutron_bagpipe_bgp: readOnlyRootFilesystem: true privileged: true neutron_bgp_dragent: pod: runAsUser: 42424 container: neutron_bgp_dragent: readOnlyRootFilesystem: true privileged: true neutron_l3_agent: pod: runAsUser: 42424 container: neutron_l3_agent: readOnlyRootFilesystem: true privileged: true neutron_lb_agent: pod: runAsUser: 42424 container: neutron_lb_agent_kernel_modules: capabilities: add: - SYS_MODULE - SYS_CHROOT runAsUser: 0 readOnlyRootFilesystem: true neutron_lb_agent_init: privileged: true runAsUser: 0 readOnlyRootFilesystem: true neutron_lb_agent: readOnlyRootFilesystem: true privileged: true neutron_metadata_agent: pod: runAsUser: 42424 container: neutron_metadata_agent_init: runAsUser: 0 readOnlyRootFilesystem: true neutron_ovn_metadata_agent: pod: runAsUser: 42424 container: neutron_ovn_metadata_agent_init: runAsUser: 0 readOnlyRootFilesystem: true ovn_vpn_agent: pod: runAsUser: 42424 container: ovn_vpn_agent_init: runAsUser: 0 readOnlyRootFilesystem: true neutron_ovs_agent: pod: runAsUser: 42424 container: neutron_openvswitch_agent_kernel_modules: capabilities: add: - SYS_MODULE - SYS_CHROOT runAsUser: 0 readOnlyRootFilesystem: true netoffload: privileged: true runAsUser: 0 readOnlyRootFilesystem: true neutron_ovs_agent_init: privileged: true runAsUser: 0 readOnlyRootFilesystem: true neutron_ovs_agent: readOnlyRootFilesystem: true privileged: true neutron_server: pod: runAsUser: 42424 container: nginx: runAsUser: 0 readOnlyRootFilesystem: false neutron_server: allowPrivilegeEscalation: false readOnlyRootFilesystem: true neutron_rpc_server: pod: runAsUser: 42424 container: neutron_rpc_server: allowPrivilegeEscalation: false readOnlyRootFilesystem: true neutron_sriov_agent: pod: runAsUser: 42424 container: neutron_sriov_agent_init: privileged: true runAsUser: 0 readOnlyRootFilesystem: false neutron_sriov_agent: readOnlyRootFilesystem: true privileged: true neutron_ironic_agent: pod: runAsUser: 42424 container: neutron_ironic_agent_init: runAsUser: 0 readOnlyRootFilesystem: true neutron_ironic_agent: allowPrivilegeEscalation: false readOnlyRootFilesystem: true neutron_netns_cleanup_cron: pod: runAsUser: 42424 container: neutron_netns_cleanup_cron: readOnlyRootFilesystem: true privileged: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: neutron: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: neutron_server: init_container: null neutron_server: volumeMounts: volumes: neutron_rpc_server: init_container: null neutron_rpc_server: volumeMounts: volumes: neutron_dhcp_agent: init_container: null neutron_dhcp_agent: volumeMounts: volumes: neutron_l3_agent: init_container: null neutron_l3_agent: volumeMounts: volumes: neutron_lb_agent: init_container: null neutron_lb_agent: volumeMounts: volumes: neutron_metadata_agent: init_container: null neutron_metadata_agent: volumeMounts: volumes: neutron_ovn_db_sync: init_container: null neutron_ovn_db_sync: volumeMounts: volumes: neutron_ovn_metadata_agent: init_container: null neutron_ovn_metadata_agent: volumeMounts: volumes: ovn_vpn_agent: init_container: null ovn_vpn_agent: volumeMounts: volumes: neutron_ovs_agent: init_container: null neutron_ovs_agent: volumeMounts: volumes: neutron_sriov_agent: init_container: null neutron_sriov_agent: volumeMounts: volumes: neutron_l2gw_agent: init_container: null neutron_l2gw_agent: volumeMounts: volumes: bagpipe_bgp: init_container: null bagpipe_bgp: volumeMounts: volumes: bgp_dragent: init_container: null bgp_dragent: volumeMounts: volumes: neutron_ironic_agent: init_container: null neutron_ironic_agent: volumeMounts: volumes: neutron_netns_cleanup_cron: init_container: null neutron_netns_cleanup_cron: volumeMounts: volumes: neutron_tests: init_container: null neutron_tests: volumeMounts: volumes: neutron_bootstrap: init_container: null neutron_bootstrap: volumeMounts: volumes: neutron_db_sync: neutron_db_sync: volumeMounts: - name: db-sync-conf mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini subPath: ml2_conf.ini readOnly: true volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/neutron/neutron.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: neutron_server: [] neutron_rpc_server: [] neutron_dhcp_agent: [] neutron_l3_agent: [] neutron_lb_agent: [] neutron_metadata_agent: [] neutron_ovn_db_sync: [] neutron_ovn_metadata_agent: [] ovn_vpn_agent: [] neutron_ovs_agent: [] neutron_sriov_agent: [] neutron_l2gw_agent: [] bagpipe_bgp: [] bgp_dragent: [] neutron_ironic_agent: [] neutron_netns_cleanup_cron: [] neutron_tests: [] neutron_bootstrap: [] neutron_db_sync: [] replicas: server: 1 rpc_server: 1 ironic_agent: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 daemonsets: pod_replacement_strategy: RollingUpdate dhcp_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 l3_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 lb_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 metadata_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 ovn_metadata_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 ovn_vpn_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 ovs_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 sriov_agent: enabled: true min_ready_seconds: 0 max_unavailable: 1 netns_cleanup_cron: enabled: true min_ready_seconds: 0 max_unavailable: 1 disruption_budget: server: min_available: 0 termination_grace_period: server: timeout: 30 rpc_server: timeout: 30 ironic_agent: timeout: 30 resources: enabled: false agent: dhcp: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" l3: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" lb: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" metadata: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ovn_metadata: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ovn_vpn: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ovs: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" sriov: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" l2gw: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" bagpipe_bgp: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" bgp_dragent: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" server: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ironic_agent: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" netns_cleanup_cron: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ovn_db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conf: rally_tests: run_tempest: false clean_up: | # NOTE: We will make the best effort to clean up rally generated networks and routers, # but should not block further automated deployment. set +e PATTERN="^[sc]_rally_" ROUTERS=$(openstack router list --format=value -c Name | grep -e $PATTERN | sort | tr -d '\r') NETWORKS=$(openstack network list --format=value -c Name | grep -e $PATTERN | sort | tr -d '\r') for ROUTER in $ROUTERS do openstack router unset --external-gateway $ROUTER openstack router set --disable --no-ha $ROUTER SUBNS=$(openstack router show $ROUTER -c interfaces_info --format=value | python -m json.tool | grep -oP '(?<="subnet_id": ")[a-f0-9\-]{36}(?=")' | sort | uniq) for SUBN in $SUBNS do openstack router remove subnet $ROUTER $SUBN done for PORT in $(openstack port list --router $ROUTER --format=value -c ID | tr -d '\r') do openstack router remove port $ROUTER $PORT done openstack router delete $ROUTER done for NETWORK in $NETWORKS do for PORT in $(openstack port list --network $NETWORK --format=value -c ID | tr -d '\r') do openstack port delete $PORT done openstack network delete $NETWORK done set -e tests: NeutronNetworks.create_and_delete_networks: - args: network_create_args: {} context: quotas: neutron: network: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_delete_ports: - args: network_create_args: {} port_create_args: {} ports_per_network: 10 context: network: {} quotas: neutron: network: -1 port: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_delete_routers: - args: network_create_args: {} router_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 router: -1 subnet: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_delete_subnets: - args: network_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 subnet: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_list_routers: - args: network_create_args: {} router_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 router: -1 subnet: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_list_subnets: - args: network_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 subnet: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_show_network: - args: network_create_args: {} context: quotas: neutron: network: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_update_networks: - args: network_create_args: {} network_update_args: admin_state_up: false context: quotas: neutron: network: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_update_ports: - args: network_create_args: {} port_create_args: {} port_update_args: admin_state_up: false device_id: dummy_id device_owner: dummy_owner ports_per_network: 5 context: network: {} quotas: neutron: network: -1 port: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_update_routers: - args: network_create_args: {} router_create_args: {} router_update_args: admin_state_up: false subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 router: -1 subnet: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_update_subnets: - args: network_create_args: {} subnet_cidr_start: 1.4.0.0/16 subnet_create_args: {} subnet_update_args: enable_dhcp: false subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 subnet: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronNetworks.list_agents: - args: agent_args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronSecurityGroup.create_and_list_security_groups: - args: security_group_create_args: {} context: quotas: neutron: security_group: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NeutronSecurityGroup.create_and_update_security_groups: - args: security_group_create_args: {} security_group_update_args: {} context: quotas: neutron: security_group: -1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 paste: composite:neutron: use: egg:Paste#urlmap /: neutronversions_composite /v2.0: neutronapi_v2_0 composite:neutronapi_v2_0: use: call:neutron.auth:pipeline_factory noauth: cors http_proxy_to_wsgi request_id catch_errors extensions neutronapiapp_v2_0 keystone: cors http_proxy_to_wsgi request_id catch_errors authtoken audit keystonecontext extensions neutronapiapp_v2_0 composite:neutronversions_composite: use: call:neutron.auth:pipeline_factory noauth: cors http_proxy_to_wsgi neutronversions keystone: cors http_proxy_to_wsgi neutronversions filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:catch_errors: paste.filter_factory: oslo_middleware:CatchErrors.factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: neutron filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory filter:keystonecontext: paste.filter_factory: neutron.auth:NeutronKeystoneContext.factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:audit: paste.filter_factory: keystonemiddleware.audit:filter_factory audit_map_file: /etc/neutron/api_audit_map.conf filter:extensions: paste.filter_factory: neutron.api.extensions:plugin_aware_extension_middleware_factory app:neutronversions: paste.app_factory: neutron.pecan_wsgi.app:versions_factory app:neutronapiapp_v2_0: paste.app_factory: neutron.api.v2.router:APIRouter.factory filter:osprofiler: paste.filter_factory: osprofiler.web:WsgiMiddleware.factory neutron_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "neutron-api:" route-user-agent: '^kube-probe.* donotlog:' # start-time provides unix time at instance startup, used by ML2/OVN # for OVN hash ring registers. See: # https://docs.openstack.org/neutron/latest/admin/config-wsgi.html start-time: "%t" thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/neutron-api stats: 0.0.0.0:1717 stats-http: true policy: {} api_audit_map: DEFAULT: target_endpoint_type: None custom_actions: add_router_interface: update/add remove_router_interface: update/remove path_keywords: floatingips: ip healthmonitors: healthmonitor health_monitors: health_monitor lb: None members: member metering-labels: label metering-label-rules: rule networks: network pools: pool ports: port routers: router quotas: quota security-groups: security-group security-group-rules: rule subnets: subnet vips: vip service_endpoints: network: service/network neutron_sudoers: | # This sudoers file supports rootwrap for both Kolla and LOCI Images. Defaults !requiretty Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin:/var/lib/kolla/venv/bin" neutron ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/neutron-rootwrap /etc/neutron/rootwrap.conf *, /var/lib/openstack/bin/neutron-rootwrap /etc/neutron/rootwrap.conf * neutron ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/neutron-rootwrap-daemon /etc/neutron/rootwrap.conf, /var/lib/openstack/bin/neutron-rootwrap-daemon /etc/neutron/rootwrap.conf rootwrap: | # Configuration for neutron-rootwrap # This file should be owned by (and only-writeable by) the root user [DEFAULT] # List of directories to load filter definitions from (separated by ','). # These directories MUST all be only writeable by root ! filters_path=/etc/neutron/rootwrap.d,/usr/share/neutron/rootwrap,/var/lib/openstack/etc/neutron/rootwrap.d # List of directories to search executables in, in case filters do not # explicitely specify a full path (separated by ',') # If not specified, defaults to system PATH environment variable. # These directories MUST all be only writeable by root ! exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin,/var/lib/openstack/bin,/var/lib/kolla/venv/bin # Enable logging to syslog # Default value is False use_syslog=False # Which syslog facility to use. # Valid values include auth, authpriv, syslog, local0, local1... # Default value is 'syslog' syslog_log_facility=syslog # Which messages to log. # INFO means log all usage # ERROR means only log unsuccessful attempts syslog_log_level=ERROR rootwrap_filters: debug: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # This is needed because we should ping # from inside a namespace which requires root # _alt variants allow to match -c and -w in any order # (used by NeutronDebugAgent.ping_all) ping: RegExpFilter, ping, root, ping, -w, \d+, -c, \d+, [0-9\.]+ ping_alt: RegExpFilter, ping, root, ping, -c, \d+, -w, \d+, [0-9\.]+ ping6: RegExpFilter, ping6, root, ping6, -w, \d+, -c, \d+, [0-9A-Fa-f:]+ ping6_alt: RegExpFilter, ping6, root, ping6, -c, \d+, -w, \d+, [0-9A-Fa-f:]+ dibbler: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # Filters for the dibbler-based reference implementation of the pluggable # Prefix Delegation driver. Other implementations using an alternative agent # should include a similar filter in this folder. # prefix_delegation_agent dibbler-client: CommandFilter, dibbler-client, root ipset_firewall: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # neutron/agent/linux/iptables_firewall.py # "ipset", "-A", ... ipset: CommandFilter, ipset, root l3: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # arping arping: CommandFilter, arping, root # l3_agent sysctl: CommandFilter, sysctl, root route: CommandFilter, route, root radvd: CommandFilter, radvd, root # haproxy haproxy: RegExpFilter, haproxy, root, haproxy, -f, .* kill_haproxy: KillFilter, root, haproxy, -15, -9, -HUP # metadata proxy metadata_proxy: CommandFilter, neutron-ns-metadata-proxy, root # RHEL invocation of the metadata proxy will report /usr/bin/python kill_metadata: KillFilter, root, python, -15, -9 kill_metadata2: KillFilter, root, python2, -15, -9 kill_metadata7: KillFilter, root, python2.7, -15, -9 kill_metadata3: KillFilter, root, python3, -15, -9 kill_metadata35: KillFilter, root, python3.5, -15, -9 kill_metadata36: KillFilter, root, python3.6, -15, -9 kill_metadata37: KillFilter, root, python3.7, -15, -9 kill_radvd_usr: KillFilter, root, /usr/sbin/radvd, -15, -9, -HUP kill_radvd: KillFilter, root, /sbin/radvd, -15, -9, -HUP # ip_lib ip: IpFilter, ip, root find: RegExpFilter, find, root, find, /sys/class/net, -maxdepth, 1, -type, l, -printf, %.* ip_exec: IpNetnsExecFilter, ip, root # l3_tc_lib l3_tc_show_qdisc: RegExpFilter, tc, root, tc, qdisc, show, dev, .+ l3_tc_add_qdisc_ingress: RegExpFilter, tc, root, tc, qdisc, add, dev, .+, ingress l3_tc_add_qdisc_egress: RegExpFilter, tc, root, tc, qdisc, add, dev, .+, root, handle, 1:, htb l3_tc_show_filters: RegExpFilter, tc, root, tc, -p, -s, -d, filter, show, dev, .+, parent, .+, prio, 1 l3_tc_delete_filters: RegExpFilter, tc, root, tc, filter, del, dev, .+, parent, .+, prio, 1, handle, .+, u32 l3_tc_add_filter_ingress: RegExpFilter, tc, root, tc, filter, add, dev, .+, parent, .+, protocol, ip, prio, 1, u32, match, ip, dst, .+, police, rate, .+, burst, .+, drop, flowid, :1 l3_tc_add_filter_egress: RegExpFilter, tc, root, tc, filter, add, dev, .+, parent, .+, protocol, ip, prio, 1, u32, match, ip, src, .+, police, rate, .+, burst, .+, drop, flowid, :1 # For ip monitor kill_ip_monitor: KillFilter, root, ip, -9 # ovs_lib (if OVSInterfaceDriver is used) ovs-vsctl: CommandFilter, ovs-vsctl, root # iptables_manager iptables-save: CommandFilter, iptables-save, root iptables-restore: CommandFilter, iptables-restore, root ip6tables-save: CommandFilter, ip6tables-save, root ip6tables-restore: CommandFilter, ip6tables-restore, root # Keepalived keepalived: CommandFilter, keepalived, root kill_keepalived: KillFilter, root, keepalived, -HUP, -15, -9 # l3 agent to delete floatingip's conntrack state conntrack: CommandFilter, conntrack, root # keepalived state change monitor keepalived_state_change: CommandFilter, neutron-keepalived-state-change, root # The following filters are used to kill the keepalived state change monitor. # Since the monitor runs as a Python script, the system reports that the # command of the process to be killed is python. # TODO(mlavalle) These kill filters will be updated once we come up with a # mechanism to kill using the name of the script being executed by Python kill_keepalived_monitor_py: KillFilter, root, python, -15 kill_keepalived_monitor_py27: KillFilter, root, python2.7, -15 kill_keepalived_monitor_py3: KillFilter, root, python3, -15 kill_keepalived_monitor_py35: KillFilter, root, python3.5, -15 kill_keepalived_monitor_py36: KillFilter, root, python3.6, -15 kill_keepalived_monitor_py37: KillFilter, root, python3.7, -15 netns_cleanup: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent - netns_cleanup_cron content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # netns-cleanup netstat: CommandFilter, netstat, root dhcp: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent - netns_cleanup_cron content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # dhcp-agent dnsmasq: CommandFilter, dnsmasq, root # dhcp-agent uses kill as well, that's handled by the generic KillFilter # it looks like these are the only signals needed, per # neutron/agent/linux/dhcp.py kill_dnsmasq: KillFilter, root, /sbin/dnsmasq, -9, -HUP, -15 kill_dnsmasq_usr: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP, -15 ovs-vsctl: CommandFilter, ovs-vsctl, root ivs-ctl: CommandFilter, ivs-ctl, root mm-ctl: CommandFilter, mm-ctl, root dhcp_release: CommandFilter, dhcp_release, root dhcp_release6: CommandFilter, dhcp_release6, root # metadata proxy metadata_proxy: CommandFilter, neutron-ns-metadata-proxy, root # RHEL invocation of the metadata proxy will report /usr/bin/python kill_metadata: KillFilter, root, python, -9 kill_metadata2: KillFilter, root, python2, -9 kill_metadata7: KillFilter, root, python2.7, -9 kill_metadata3: KillFilter, root, python3, -9 kill_metadata35: KillFilter, root, python3.5, -9 kill_metadata36: KillFilter, root, python3.6, -9 kill_metadata37: KillFilter, root, python3.7, -9 # ip_lib ip: IpFilter, ip, root find: RegExpFilter, find, root, find, /sys/class/net, -maxdepth, 1, -type, l, -printf, %.* ip_exec: IpNetnsExecFilter, ip, root ebtables: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] ebtables: CommandFilter, ebtables, root iptables_firewall: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # neutron/agent/linux/iptables_firewall.py # "iptables-save", ... iptables-save: CommandFilter, iptables-save, root iptables-restore: CommandFilter, iptables-restore, root ip6tables-save: CommandFilter, ip6tables-save, root ip6tables-restore: CommandFilter, ip6tables-restore, root # neutron/agent/linux/iptables_firewall.py # "iptables", "-A", ... iptables: CommandFilter, iptables, root ip6tables: CommandFilter, ip6tables, root # neutron/agent/linux/iptables_firewall.py sysctl: CommandFilter, sysctl, root # neutron/agent/linux/ip_conntrack.py conntrack: CommandFilter, conntrack, root linuxbridge_plugin: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # linuxbridge-agent # unclear whether both variants are necessary, but I'm transliterating # from the old mechanism brctl: CommandFilter, brctl, root bridge: CommandFilter, bridge, root # ip_lib ip: IpFilter, ip, root find: RegExpFilter, find, root, find, /sys/class/net, -maxdepth, 1, -type, l, -printf, %.* ip_exec: IpNetnsExecFilter, ip, root # tc commands needed for QoS support tc_replace_tbf: RegExpFilter, tc, root, tc, qdisc, replace, dev, .+, root, tbf, rate, .+, latency, .+, burst, .+ tc_add_ingress: RegExpFilter, tc, root, tc, qdisc, add, dev, .+, ingress, handle, .+ tc_delete: RegExpFilter, tc, root, tc, qdisc, del, dev, .+, .+ tc_show_qdisc: RegExpFilter, tc, root, tc, qdisc, show, dev, .+ tc_show_filters: RegExpFilter, tc, root, tc, filter, show, dev, .+, parent, .+ tc_add_filter: RegExpFilter, tc, root, tc, filter, add, dev, .+, parent, .+, protocol, all, prio, .+, basic, police, rate, .+, burst, .+, mtu, .+, drop openvswitch_plugin: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent content: | # neutron-rootwrap command filters for nodes on which neutron is # expected to control network # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # openvswitch-agent # unclear whether both variants are necessary, but I'm transliterating # from the old mechanism ovs-vsctl: CommandFilter, ovs-vsctl, root # NOTE(yamamoto): of_interface=native doesn't use ovs-ofctl ovs-ofctl: CommandFilter, ovs-ofctl, root ovs-appctl: CommandFilter, ovs-appctl, root kill_ovsdb_client: KillFilter, root, /usr/bin/ovsdb-client, -9 ovsdb-client: CommandFilter, ovsdb-client, root xe: CommandFilter, xe, root # ip_lib ip: IpFilter, ip, root find: RegExpFilter, find, root, find, /sys/class/net, -maxdepth, 1, -type, l, -printf, %.* ip_exec: IpNetnsExecFilter, ip, root # needed for FDB extension bridge: CommandFilter, bridge, root privsep: pods: - dhcp_agent - l3_agent - lb_agent - metadata_agent - ovn_metadata_agent - ovn_vpn_agent - ovs_agent - sriov_agent - netns_cleanup_cron content: | # Command filters to allow privsep daemon to be started via rootwrap. # # This file should be owned by (and only-writeable by) the root user [Filters] # By installing the following, the local admin is asserting that: # # 1. The python module load path used by privsep-helper # command as root (as started by sudo/rootwrap) is trusted. # 2. Any oslo.config files matching the --config-file # arguments below are trusted. # 3. Users allowed to run sudo/rootwrap with this configuration(*) are # also allowed to invoke python "entrypoint" functions from # --privsep_context with the additional (possibly root) privileges # configured for that context. # # (*) ie: the user is allowed by /etc/sudoers to run rootwrap as root # # In particular, the oslo.config and python module path must not # be writeable by the unprivileged user. # oslo.privsep default neutron context privsep: PathFilter, privsep-helper, root, --config-file, /etc, --privsep_context, neutron.privileged.default, --privsep_sock_path, / # NOTE: A second `--config-file` arg can also be added above. Since # many neutron components are installed like that (eg: by devstack). # Adjust to suit local requirements. linux_vxlan: pods: - bagpipe_bgp content: | # bagpipe-bgp-rootwrap command filters for nodes on which bagpipe-bgp is # expected to control VXLAN Linux Bridge dataplane # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # modprobe: CommandFilter, modprobe, root # brctl: CommandFilter, brctl, root bridge: CommandFilter, bridge, root # ip_lib ip: IpFilter, ip, root ip_exec: IpNetnsExecFilter, ip, root # shell (for piped commands) sh: CommandFilter, sh, root mpls_ovs_dataplane: pods: - bagpipe_bgp content: | # bagpipe-bgp-rootwrap command filters for nodes on which bagpipe-bgp is # expected to control MPLS OpenVSwitch dataplane # # This file should be owned by (and only-writeable by) the root user # format seems to be # cmd-name: filter-name, raw-command, user, args [Filters] # openvswitch ovs-vsctl: CommandFilter, ovs-vsctl, root ovs-ofctl: CommandFilter, ovs-ofctl, root # ip_lib ip: IpFilter, ip, root ip_exec: IpNetnsExecFilter, ip, root # shell (for piped commands) sh: CommandFilter, sh, root neutron: DEFAULT: metadata_proxy_socket: /var/lib/neutron/openstack-helm/metadata_proxy log_config_append: /etc/neutron/logging.conf # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. bind_port: null default_availability_zones: nova api_workers: 1 rpc_workers: 4 allow_overlapping_ips: True state_path: /var/lib/neutron # core_plugin can be: ml2, calico core_plugin: ml2 # service_plugin can be: router, empty for calico, # networking_ovn.l3.l3_ovn.OVNL3RouterPlugin for OVN service_plugins: router allow_automatic_l3agent_failover: True l3_ha: True max_l3_agents_per_router: 2 l3_ha_network_type: vxlan network_auto_schedule: True router_auto_schedule: True # (NOTE)portdirect: if unset this is populated dynamically from the value in # 'network.backend' to sane defaults. interface_driver: null oslo_concurrency: lock_path: /var/lock database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" agent: root_helper: sudo /var/lib/openstack/bin/neutron-rootwrap /etc/neutron/rootwrap.conf root_helper_daemon: sudo /var/lib/openstack/bin/neutron-rootwrap-daemon /etc/neutron/rootwrap.conf oslo_messaging_notifications: driver: messagingv2 oslo_messaging_rabbit: rabbit_ha_queues: true oslo_middleware: enable_proxy_headers_parsing: true oslo_policy: policy_file: /etc/neutron/policy.yaml ovn: ovn_metadata_enabled: true nova: auth_type: password auth_version: v3 endpoint_type: internal placement: auth_type: password auth_version: v3 endpoint_type: internal designate: auth_type: password auth_version: v3 endpoint_type: internal allow_reverse_dns_lookup: true ironic: auth_type: password auth_version: v3 endpoint_type: internal keystone_authtoken: service_token_roles: service service_token_roles_required: true memcache_security_strategy: ENCRYPT auth_type: password auth_version: v3 service_type: network octavia: request_poll_timeout: 3000 logging: loggers: keys: - root - neutron - neutron_taas handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_neutron: level: INFO handlers: - stdout qualname: neutron logger_neutron_taas: level: INFO handlers: - stdout qualname: neutron_taas logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" plugins: ml2_conf: ml2: extension_drivers: port_security # (NOTE)portdirect: if unset this is populated dyanmicly from the value # in 'network.backend' to sane defaults. mechanism_drivers: null type_drivers: flat,vlan,vxlan,local tenant_network_types: vxlan ml2_type_vxlan: vni_ranges: 1:1000 vxlan_group: 239.1.1.1 ml2_type_flat: flat_networks: "*" # If you want to use the external network as a tagged provider network, # a range should be specified including the intended VLAN target # using ml2_type_vlan.network_vlan_ranges: # ml2_type_vlan: # network_vlan_ranges: "external:1100:1110" ml2_type_geneve: vni_ranges: 1:65536 max_header_size: 38 agent: extensions: "" ovn: {} ml2_conf_sriov: null taas: taas: enabled: False openvswitch_agent: agent: tunnel_types: vxlan l2_population: True arp_responder: True ovs: bridge_mappings: "external:br-ex" securitygroup: firewall_driver: neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver linuxbridge_agent: linux_bridge: # To define Flat and VLAN connections, in LB we can assign # specific interface to the flat/vlan network name using: # physical_interface_mappings: "external:eth3" # Or we can set the mapping between the network and bridge: bridge_mappings: "external:br-ex" # The two above options are exclusive, do not use both of them at once securitygroup: firewall_driver: iptables vxlan: l2_population: True arp_responder: True macvtap_agent: null sriov_agent: securitygroup: firewall_driver: neutron.agent.firewall.NoopFirewallDriver sriov_nic: physical_device_mappings: physnet2:enp3s0f1 # NOTE: do not use null here, use an empty string exclude_devices: "" dhcp_agent: DEFAULT: # (NOTE)portdirect: if unset this is populated dyanmicly from the value in # 'network.backend' to sane defaults. interface_driver: null dnsmasq_config_file: /etc/neutron/dnsmasq.conf force_metadata: True # NOTE(mnaser): This has to be here in order for the DHCP agent to work with OVN. ovs: {} dnsmasq: | #no-hosts #port=5353 #cache-size=500 #no-negcache #dns-forward-max=100 #resolve-file= #strict-order #bind-interface #bind-dynamic #domain= #dhcp-range=10.10.10.10,10.10.10.100,24h #dhcp-lease-max=150 #dhcp-host=11:22:33:44:55:66,ignore #dhcp-option=3,10.10.10.1 #dhcp-option-force=26,1450 neutron_vpnaas: null ovn_vpn_agent: DEFAULT: interface_driver: openvswitch vpnagent: vpn_device_driver: neutron_vpnaas.services.vpn.device_drivers.ovn_ipsec.OvnStrongSwanDriver ovs: ovsdb_connection: unix:/run/openvswitch/db.sock l3_agent: DEFAULT: # (NOTE)portdirect: if unset this is populated dyanmicly from the value in # 'network.backend' to sane defaults. interface_driver: null agent_mode: legacy metering_agent: null metadata_agent: DEFAULT: log_config_append: /etc/neutron/logging.conf # we cannot change the proxy socket path as it is declared # as a hostPath volume from agent daemonsets metadata_proxy_socket: /var/lib/neutron/openstack-helm/metadata_proxy metadata_proxy_shared_secret: "password" cache: enabled: true backend: dogpile.cache.memcached bagpipe_bgp: {} ovn_metadata_agent: DEFAULT: # we cannot change the proxy socket path as it is declared # as a hostPath volume from agent daemonsets metadata_proxy_socket: /var/lib/neutron/openstack-helm/metadata_proxy metadata_proxy_shared_secret: "password" metadata_workers: 2 cache: enabled: true backend: dogpile.cache.memcached ovs: ovsdb_connection: unix:/run/openvswitch/db.sock bgp_dragent: {} rabbitmq: # NOTE(rk760n): adding rmq policy to mirror messages from notification queues and set expiration time for the ones policies: - vhost: "neutron" name: "ha_ttl_neutron" definition: # mirror messges to other nodes in rmq cluster ha-mode: "all" ha-sync-mode: "automatic" # 70s message-ttl: 70000 priority: 0 apply-to: all pattern: '^(?!(amq\.|reply_)).*' ## NOTE: "besteffort" is meant for dev env with mixed compute type only. ## This helps prevent sriov init script from failing due to mis-matched NIC ## For prod env, target NIC should match and init script should fail otherwise. ## sriov_init: ## - besteffort sriov_init: - # auto_bridge_add is a table of "bridge: interface" pairs # To automatically add a physical interfaces to a specific bridges, # for example eth3 to bridge br-physnet1, if0 to br0 and iface_two # to br1 do something like: # # auto_bridge_add: # br-physnet1: eth3 # br0: if0 # br1: iface_two # br-ex will be added by default auto_bridge_add: br-ex: null # Network off-loading configuration netoffload: enabled: false asap2: # - dev: enp97s0f0 # vfs: 16 # configuration of OVS DPDK bridges and NICs # this is a separate section and not part of the auto_bridge_add section # because additional parameters are needed ovs_dpdk: enabled: false # setting update_dpdk_bond_config to true will have default behavior, # which may cause disruptions in ovs dpdk traffic in case of neutron # ovs agent restart or when dpdk nic/bond configurations are changed. # Setting this to false will configure dpdk in the first run and # disable nic/bond config on event of restart or config update. update_dpdk_bond_config: true driver: uio_pci_generic # In case bonds are configured, the nics which are part of those bonds # must NOT be provided here. nics: - name: dpdk0 # Optionally, instead of using pci_id you can use the name of # the interface. If both are used, pci_id has presedence. # iface: eth0 pci_id: '0000:05:00.0' # Set VF Index in case some particular VF(s) need to be # used with ovs-dpdk. # vf_index: 0 bridge: br-phy migrate_ip: true n_rxq: 2 n_txq: 2 pmd_rxq_affinity: "0:3,1:27" ofport_request: 1 # optional parameters for tuning the OVS DPDK config # in alignment with the available hardware resources # mtu: 2000 # n_rxq_size: 1024 # n_txq_size: 1024 # vhost-iommu-support: true bridges: - name: br-phy # optional parameter, in case tunnel traffic needs to be transported over a vlan underlay # - tunnel_underlay_vlan: 45 # Optional parameter for configuring bonding in OVS-DPDK # - name: br-phy-bond0 # bonds: # - name: dpdkbond0 # bridge: br-phy-bond0 # # The IP from the first nic in nics list shall be used # migrate_ip: true # mtu: 2000 # # Please note that n_rxq is set for each NIC individually # # rather than denoting the total number of rx queues for # # the bond as a whole. So setting n_rxq = 2 below for ex. # # would be 4 rx queues in total for the bond. # # Same for n_txq # n_rxq: 2 # n_txq: 2 # ofport_request: 1 # n_rxq_size: 1024 # n_txq_size: 1024 # vhost-iommu-support: true # ovs_options: "bond_mode=active-backup" # nics: # - name: dpdk_b0s0 # # Optionally, instead of using pci_id you can use the name of # # the interface. If both are used, pci_id has presedence. # # iface: eth0 # pci_id: '0000:06:00.0' # pmd_rxq_affinity: "0:3,1:27" # # Set VF Index in case some particular VF(s) need to be # # used with ovs-dpdk. In which case pci_id of PF must be # # provided above. # # vf_index: 0 # - name: dpdk_b0s1 # pci_id: '0000:07:00.0' # pmd_rxq_affinity: "0:3,1:27" # # Set VF Index in case some particular VF(s) need to be # # used with ovs-dpdk. In which case pci_id of PF must be # # provided above. # # vf_index: 0 # # Set the log level for each target module (default level is always dbg) # Supported log levels are: off, emer, err, warn, info, dbg # # modules: # - name: dpdk # log_level: info # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: neutron-keystone-admin neutron: neutron-keystone-user nova: neutron-keystone-nova placement: neutron-keystone-placement designate: neutron-keystone-designate ironic: neutron-keystone-ironic test: neutron-keystone-test oslo_db: admin: neutron-db-admin neutron: neutron-db-user oslo_messaging: admin: neutron-rabbitmq-admin neutron: neutron-rabbitmq-user tls: compute_metadata: metadata: internal: metadata-tls-metadata network: server: public: neutron-tls-public internal: neutron-tls-server oci_image_registry: neutron: neutron-oci-image-registry # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false neutron: username: neutron password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct neutron: username: neutron password: password hosts: default: mariadb host_fqdn_override: default: null path: /neutron scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct neutron: username: neutron password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /neutron scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 compute: name: nova hosts: default: nova-api public: nova host_fqdn_override: default: null path: default: "/v2.1/%(tenant_id)s" scheme: default: 'http' port: api: default: 8774 public: 80 novncproxy: default: 6080 compute_metadata: name: nova hosts: default: nova-metadata public: metadata host_fqdn_override: default: null path: default: / scheme: default: 'http' port: metadata: default: 8775 public: 80 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default neutron: role: admin,service region_name: RegionOne username: neutron password: password project_name: service user_domain_name: service project_domain_name: service nova: role: admin,service region_name: RegionOne project_name: service username: neutron_nova password: password user_domain_name: service project_domain_name: service placement: role: admin,service region_name: RegionOne project_name: service username: neutron_placement password: password user_domain_name: service project_domain_name: service designate: role: admin,service region_name: RegionOne project_name: service username: neutron_designate password: password user_domain_name: service project_domain_name: service ironic: role: admin,service region_name: RegionOne project_name: service username: neutron_ironic password: password user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: neutron-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 network: name: neutron hosts: default: neutron-server public: neutron host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: 'http' service: 'http' port: api: default: 9696 public: 80 service: 9696 load_balancer: name: octavia hosts: default: octavia-api public: octavia host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 9876 public: 80 fluentd: namespace: osh-infra name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 dns: name: designate hosts: default: designate-api public: designate host_fqdn_override: default: null path: default: / scheme: default: 'http' port: api: default: 9001 public: 80 baremetal: name: ironic hosts: default: ironic-api public: ironic host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 6385 public: 80 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 network_policy: neutron: # TODO(lamt): Need to tighten this ingress for security. ingress: - {} egress: - {} health_probe: logging: level: ERROR jobs: ovn_db_sync: cron: "*/5 * * * *" sync_mode: log history: success: 3 failed: 1 tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false cron_job_ovn_db_sync: false configmap_bin: true configmap_etc: true daemonset_dhcp_agent: true daemonset_l3_agent: true daemonset_lb_agent: true daemonset_metadata_agent: true daemonset_ovs_agent: true daemonset_sriov_agent: true daemonset_l2gw_agent: false daemonset_bagpipe_bgp: false daemonset_bgp_dragent: false daemonset_netns_cleanup_cron: true daemonset_ovn_metadata_agent: false daemonset_ovn_vpn_agent: false deployment_ironic_agent: false deployment_server: true deployment_rpc_server: true ingress_server: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pdb_server: true pod_rally_test: true network_policy: false secret_db: true secret_ingress_tls: true secret_keystone: true secret_ks_etc: true secret_rabbitmq: true secret_registry: true service_ingress_server: true service_server: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: nfs-provisioner/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v2.2.1 description: OpenStack-Helm NFS name: nfs-provisioner version: 2025.2.0 home: https://github.com/kubernetes-incubator/external-storage sources: - https://github.com/kubernetes-incubator/external-storage - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: nfs-provisioner/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: nfs-bin data: image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: nfs-provisioner/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "nfs-provisioner" }} {{ tuple $envAll "nfs" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} 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: - endpoints verbs: - get - create - update - patch - apiGroups: - policy resources: - podsecuritypolicies resourceNames: - nfs-provisioner verbs: - use --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- kind: Deployment apiVersion: apps/v1 metadata: name: nfs-provisioner annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nfs" "provisioner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.server }} strategy: type: Recreate selector: matchLabels: {{ tuple $envAll "nfs" "provisioner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "nfs" "provisioner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "nfs" "provisioner" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.nfs.node_selector_key }}: {{ .Values.labels.nfs.node_selector_value | quote }} initContainers: {{ tuple $envAll "nfs" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: nfs-provisioner {{ tuple $envAll "nfs_provisioner" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: capabilities: add: - DAC_READ_SEARCH - SYS_RESOURCE ports: - name: nfs containerPort: 2049 - name: nfs-udp containerPort: 2049 protocol: UDP - name: mountd containerPort: 20048 - name: mountd-udp containerPort: 20048 protocol: UDP - name: rpcbind containerPort: 111 - name: rpcbind-udp containerPort: 111 protocol: UDP - name: port-662 containerPort: 662 - name: port-662-udp containerPort: 662 protocol: UDP - name: port-875 containerPort: 875 - name: port-875-udp containerPort: 875 protocol: UDP - name: port-32803 containerPort: 32803 - name: port-32803-udp containerPort: 32803 protocol: UDP env: - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: SERVICE_NAME value: {{ tuple "nfs" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace args: {{ if empty .Values.storageclass.provisioner -}} - "-provisioner=nfs/{{ .Release.Name }}" {{- else -}} - "-provisioner={{ .Values.storageclass.provisioner }}" {{- end }} - "-grace-period=10" volumeMounts: - name: pod-tmp mountPath: /tmp - name: export-volume mountPath: /export volumes: - name: pod-tmp emptyDir: {} - name: export-volume {{- if eq .Values.storage.type "persistentVolumeClaim" }} persistentVolumeClaim: {{ if empty .Values.storage.persistentVolumeClaim.name -}} claimName: {{ .Release.Name }} {{- else -}} claimName: {{ .Values.storage.persistentVolumeClaim.name }} {{- end }} {{- else if eq .Values.storage.type "hostPath" }} hostPath: path: {{ .Values.storage.hostPath.path }} {{- end }} {{- end }} ================================================ FILE: nfs-provisioner/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: nfs-provisioner/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "nfs-provisioner" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: nfs-provisioner/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: nfs-provisioner/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- kind: Service apiVersion: v1 metadata: name: {{ tuple "nfs" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "nfs" "provisioner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: ports: - name: nfs port: 2049 - name: nfs-udp port: 2049 protocol: UDP - name: mountd port: 20048 - name: mountd-udp port: 20048 protocol: UDP - name: rpcbind port: 111 - name: rpcbind-udp port: 111 protocol: UDP - name: port-662 port: 662 - name: port-662-udp port: 662 protocol: UDP - name: port-875 port: 875 - name: port-875-udp port: 875 protocol: UDP - name: port-32803 port: 32803 - name: port-32803-udp port: 32803 protocol: UDP selector: {{ tuple $envAll "nfs" "provisioner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: nfs-provisioner/templates/storage_class.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.storage_class }} {{- $envAll := . }} --- kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: {{ if empty .Values.storageclass.name -}} name: {{ .Release.Name }} {{- else -}} name: {{ .Values.storageclass.name }} {{- end }} {{ if empty .Values.storageclass.provisioner -}} provisioner: nfs/{{ .Release.Name }} {{- else -}} provisioner: {{ .Values.storageclass.provisioner }} {{- end }} parameters: mountOptions: vers=4.1 {{- end }} ================================================ FILE: nfs-provisioner/templates/volume_claim.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.volume_claim }} {{- if eq .Values.storage.type "persistentVolumeClaim" }} {{- $envAll := . }} --- kind: PersistentVolumeClaim apiVersion: v1 metadata: {{ if empty .Values.storage.persistentVolumeClaim.name -}} name: {{ .Release.Name }} {{- else -}} name: {{ .Values.storage.persistentVolumeClaim.name }} {{- end }} spec: accessModes: - {{ .Values.storage.persistentVolumeClaim.access_mode }} resources: requests: storage: {{ .Values.storage.persistentVolumeClaim.size }} storageClassName: {{ .Values.storage.persistentVolumeClaim.class_name }} {{- end }} {{- end }} ================================================ FILE: nfs-provisioner/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for NFS. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: # only 1 replica currently supported server: 1 resources: enabled: false server: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" images: tags: nfs_provisioner: quay.io/kubernetes_incubator/nfs-provisioner:v2.3.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync storage: type: hostPath hostPath: path: /var/lib/openstack-helm/nfs persistentVolumeClaim: access_mode: ReadWriteOnce class_name: general # NOTE(portdirect): Unless explicity set the PV name will be populated to # match "{{ .Release.Name }}". name: null size: 10Gi labels: nfs: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled storageclass: # NOTE(portdirect): Unless explicity set the provisioner name will be generated # with the format "nfs/{{ .Release.Name }}" provisioner: null # NOTE(portdirect): Unless explicity set the PV name will be populated to # match "{{ .Release.Name }}". name: null dependencies: dynamic: common: local_image_registry: jobs: - nfs-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry nfs: services: null secrets: oci_image_registry: nfs-provisioner: nfs-provisioner-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false nfs-provisioner: username: nfs-provisioner password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null nfs: hosts: default: nfs-provisioner host_fqdn_override: default: null path: null scheme: null port: nfs: default: null manifests: configmap_bin: true deployment: true job_image_repo_sync: true secret_registry: true service: true storage_class: true volume_claim: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: nova/.helmignore ================================================ values_overrides ================================================ FILE: nova/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Nova name: nova version: 2025.2.0 home: https://docs.openstack.org/nova/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Nova/OpenStack_Project_Nova_vertical.png sources: - https://opendev.org/openstack/nova - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: nova/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp {{ if .Values.bootstrap.structured.flavors.enabled }} {{- range $i, $params := .Values.bootstrap.structured.flavors.options }} { openstack flavor show {{ $params.name }} || \ openstack flavor create \ {{- range $key, $val := $params }} {{- if ne $key "name" }} {{- if eq $key "extra_specs" }} {{- if kindIs "slice" $val }} {{- range $idx, $spec := $val }} --property {{ $spec }} \ {{- end }} {{- end }} {{- else if eq $key "is_public" }} {{- if $val }} --public \ {{- else if not $val }} --private \ {{- end }} {{- else }} --{{ $key }} {{ $val }} \ {{- end }} {{- end }} {{- end }} {{ $params.name }} } & {{ end }} wait {{ end }} {{ if .Values.bootstrap.wait_for_computes.enabled }} {{ .Values.bootstrap.wait_for_computes.scripts.wait_script }} {{ else }} echo 'Wait for Computes script not enabled' {{ end }} {{ .Values.bootstrap.script | default "echo 'No other bootstrap customizations found.'" }} ================================================ FILE: nova/templates/bin/_cell-setup-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- if .Values.jobs.cell_setup.extended_wait.enabled }} iteration={{ .Values.jobs.cell_setup.extended_wait.iteration }} duration={{ .Values.jobs.cell_setup.extended_wait.duration }} extra_wait=true # Init for case wait_for_computes is not enabled. It'll have # the same effect as the original code that checks for at # least one compute is registered expected_computes=1 if [[ -f /tmp/compute_nodes.txt ]] then expected_computes=$(cat /tmp/compute_nodes.txt | wc -w) fi while [[ "$extra_wait" == true ]] do nova_computes=$(openstack compute service list --service nova-compute -f value -c State) if [[ -z "$(echo $nova_computes | grep down)" ]] then # No more down. Although all present computes are up, # the number of present computes may not be the total # expected number of computes as some of the remaining # computes may take a bit longer to register/join. actual_computes=$(echo $nova_computes | wc -w) if [[ "$actual_computes" -ge "$expected_computes" ]] then # All expected nodes are up extra_wait=false fi fi if [[ "$extra_wait" == true ]] then sleep "$duration" if [[ "$iteration" -gt 1 ]] then ((iteration=iteration-1)) else extra_wait=false # List out the info to see whether any nodes is still down openstack compute service list --service nova-compute fi fi done {{- end }} until openstack compute service list --service nova-compute -f value -c State | grep -q "^up$" ;do echo "Waiting for Nova Compute processes to register" sleep 10 done {{- if .Values.jobs.cell_setup.extra_command }} {{ .Values.jobs.cell_setup.extra_command }} {{- end }} ================================================ FILE: nova/templates/bin/_cell-setup.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex NOVA_VERSION=$(nova-manage --version 2>&1 | grep -Eo '[0-9]+[.][0-9]+[.][0-9]+') # NOTE(portdirect): check if nova fully supports cells v2, and manage # accordingly. Support was complete in ocata (V14.x.x). if [ "${NOVA_VERSION%%.*}" -gt "14" ]; then nova-manage cell_v2 discover_hosts --verbose fi ================================================ FILE: nova/templates/bin/_ceph-admin-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cat > /etc/ceph/ceph.client.admin.keyring << EOF [client.admin] {{- if .Values.conf.ceph.admin_keyring }} key = {{ .Values.conf.ceph.admin_keyring }} {{- else }} key = $(cat /tmp/client-keyring) {{- end }} EOF exit 0 ================================================ FILE: nova/templates/bin/_ceph-keyring.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export HOME=/tmp cp -vf /etc/ceph/ceph.conf.template /etc/ceph/ceph.conf KEYRING=/etc/ceph/ceph.client.${CEPH_CINDER_USER}.keyring {{- if .Values.conf.ceph.cinder.keyring }} cat > ${KEYRING} <&1 | grep -Eo '[0-9]+[.][0-9]+[.][0-9]+') function manage_cells () { # NOTE(portdirect): check if nova fully supports cells v2, and manage # accordingly. Support was complete in ocata (V14.x.x). if [ "${NOVA_VERSION%%.*}" -gt "14" ]; then nova-manage cell_v2 map_cell0 nova-manage cell_v2 list_cells | grep -q " cell1 " || \ nova-manage cell_v2 create_cell --name=cell1 --verbose CELL0_ID=$(nova-manage cell_v2 list_cells | awk -F '|' '/ cell0 / { print $3 }' | tr -d ' ') CELL1_ID=$(nova-manage cell_v2 list_cells | awk -F '|' '/ cell1 / { print $3 }' | tr -d ' ') set +x CELL0_TRANSPORT=$(nova-manage cell_v2 list_cells | awk -F '|' '/ cell0 / { print $4 }' | tr -d ' ') if [ -z "${DB_CONNECTION_CELL0}" ]; then echo "ERROR: missing DB_CONNECTION_CELL0" exit 1 fi nova-manage cell_v2 update_cell \ --cell_uuid="${CELL0_ID}" \ --name="cell0" \ --transport-url="${CELL0_TRANSPORT}" \ --database_connection="${DB_CONNECTION_CELL0}" for VAR in TRANSPORT_URL DB_CONNECTION; do if [ -z "${!VAR}" ]; then echo "ERROR: missing $VAR variable" exit 1 fi done nova-manage cell_v2 update_cell \ --cell_uuid="${CELL1_ID}" \ --name="cell1" \ --transport-url="${TRANSPORT_URL}" \ --database_connection="${DB_CONNECTION}" set -x fi } nova-manage api_db sync manage_cells nova-manage db sync nova-manage db online_data_migrations echo 'Finished DB migrations' ================================================ FILE: nova/templates/bin/_fake-iptables.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} exit 0 ================================================ FILE: nova/templates/bin/_health-probe.py.tpl ================================================ #!/usr/bin/env python # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Health probe script for OpenStack service that uses RPC/unix domain socket for communication. Check's the RPC tcp socket status on the process and send message to service through rpc call method and expects a reply. Use nova's ping method that is designed just for such simple purpose. Script returns failure to Kubernetes only when a. TCP socket for the RPC communication are not established. b. service is not reachable or c. service times out sending a reply. sys.stderr.write() writes to pod's events on failures. Usage example for Nova Compute: # python health-probe.py \ # --config-file /etc/nova/nova.conf \ # --config-dir /etc/nova/nova.conf.d \ # --service-queue-name compute """ import json import os import psutil import signal import socket import sys from oslo_config import cfg from oslo_context import context from oslo_db import options as oslo_db_options from oslo_db.sqlalchemy import utils as oslo_db_utils from oslo_log import log import oslo_messaging rpc_timeout = int(os.getenv('RPC_PROBE_TIMEOUT', '60')) rpc_retries = int(os.getenv('RPC_PROBE_RETRIES', '2')) tcp_established = "ESTABLISHED" def _get_hostname(topic, use_fqdn): configured_host = cfg.CONF.host if configured_host: return configured_host if use_fqdn and topic == "compute": return socket.getfqdn() return socket.gethostname() def check_service_status(transport): """Verify service status. Return success if service consumes message""" try: service_queue_name = cfg.CONF.service_queue_name use_fqdn = cfg.CONF.use_fqdn target = oslo_messaging.Target( topic=service_queue_name, server=_get_hostname(service_queue_name, use_fqdn), namespace='baseapi', version="1.1") if hasattr(oslo_messaging, 'get_rpc_client'): client = oslo_messaging.get_rpc_client(transport, target, timeout=rpc_timeout, retry=rpc_retries) else: client = oslo_messaging.RPCClient(transport, target, timeout=rpc_timeout, retry=rpc_retries) client.call(context.RequestContext(), 'ping', arg=None) except oslo_messaging.exceptions.MessageDeliveryFailure: # Log to pod events sys.stderr.write("Health probe unable to reach message bus") sys.exit(0) # return success except oslo_messaging.rpc.client.RemoteError as re: message = getattr(re, "message", str(re)) if ("Endpoint does not support RPC method" in message) or \ ("Endpoint does not support RPC version" in message): sys.exit(0) # Call reached the service else: sys.stderr.write("Health probe unable to reach service") sys.exit(1) # return failure except oslo_messaging.exceptions.MessagingTimeout: sys.stderr.write("Health probe timed out. Agent is down or response " "timed out") sys.exit(1) # return failure except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Health probe caught exception sending message to " "service: %s" % message) sys.exit(0) except: sys.stderr.write("Health probe caught exception sending message to" " service") sys.exit(0) finally: if transport: transport.cleanup() def tcp_socket_status(process, ports): """Check the tcp socket status on a process""" for p in psutil.process_iter(): try: with p.oneshot(): if process in " ".join(p.cmdline()): pcon = p.net_connections() for con in pcon: try: rport = con.raddr[1] status = con.status except IndexError: continue if rport in ports and status == tcp_established: return 1 except psutil.Error: continue return 0 def configured_port_in_conf(): """Get the rabbitmq/Database port configured in config file""" rabbit_ports = set() database_ports = set() try: transport_url = oslo_messaging.TransportURL.parse(cfg.CONF) for host in transport_url.hosts: rabbit_ports.add(host.port or 5672) except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Health probe caught exception reading " "RabbitMQ ports: %s" % message) sys.exit(0) # return success try: for section in ['database', 'api_database', 'cell0_database']: group = getattr(cfg.CONF, section) if not group.connection: continue connection = oslo_db_utils.make_url(group.connection) if connection.port: database_ports.add(int(connection.port)) except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Health probe caught exception reading " "database ports: %s" % message) sys.exit(0) # return success return rabbit_ports, database_ports def test_tcp_socket(service): """Check tcp socket to rabbitmq/db is in Established state""" dict_services = { "compute": "nova-compute", "conductor": "nova-conductor", "scheduler": "nova-scheduler" } r_ports, d_ports = configured_port_in_conf() if service in dict_services: proc = dict_services[service] transport = oslo_messaging.TransportURL.parse(cfg.CONF) if r_ports and tcp_socket_status(proc, r_ports) == 0: sys.stderr.write("RabbitMQ socket not established for service " "%s with transport %s" % (proc, transport)) # Do not kill the pod if RabbitMQ is not reachable/down if not cfg.CONF.liveness_probe: sys.exit(1) # let's do the db check if service != "compute": if d_ports and tcp_socket_status(proc, d_ports) == 0: sys.stderr.write("Database socket not established for service " "%s with transport %s" % (proc, transport)) # Do not kill the pod if database is not reachable/down # there could be no socket as well as typically connections # get closed after an idle timeout # Just log it to pod events if not cfg.CONF.liveness_probe: sys.exit(1) def test_rpc_liveness(): """Test if service can consume message from queue""" oslo_messaging.set_transport_defaults(control_exchange='nova') rabbit_group = cfg.OptGroup(name='oslo_messaging_rabbit', title='RabbitMQ options') cfg.CONF.register_group(rabbit_group) cfg.CONF.register_cli_opt(cfg.StrOpt('service-queue-name')) cfg.CONF.register_cli_opt(cfg.BoolOpt('liveness-probe', default=False, required=False)) cfg.CONF.register_cli_opt(cfg.BoolOpt('use-fqdn', default=False, required=False)) # Opts need to be registered to be accessible by this script. cfg.CONF.register_opt(cfg.StrOpt('host')) cfg.CONF.register_opts(oslo_db_options.database_opts, 'database') cfg.CONF.register_opts(oslo_db_options.database_opts, 'api_database') # cell0_database is an OSH specific section used by db-init and db-drop Job. # It is not an official Nova configuration section. cfg.CONF.register_opts(oslo_db_options.database_opts, 'cell0_database') cfg.CONF(sys.argv[1:], project='nova') log.logging.basicConfig(level=log.{{ .Values.health_probe.logging.level }}) try: transport = oslo_messaging.get_rpc_transport(cfg.CONF) except Exception as ex: message = getattr(ex, "message", str(ex)) sys.stderr.write("Message bus driver load error: %s" % message) sys.exit(0) # return success if not cfg.CONF.transport_url or \ not cfg.CONF.service_queue_name: sys.stderr.write("Both message bus URL and service's queue name are " "required for health probe to work") sys.exit(0) # return success try: cfg.CONF.set_override('rabbit_max_retries', 2, group=rabbit_group) # 3 attempts except cfg.NoSuchOptError as ex: cfg.CONF.register_opt(cfg.IntOpt('rabbit_max_retries', default=2), group=rabbit_group) service = cfg.CONF.service_queue_name test_tcp_socket(service) check_service_status(transport) def check_pid_running(pid): if psutil.pid_exists(int(pid)): return True else: return False if __name__ == "__main__": if "liveness-probe" in ','.join(sys.argv): pidfile = "/tmp/liveness.pid" #nosec else: pidfile = "/tmp/readiness.pid" #nosec data = {} if os.path.isfile(pidfile): with open(pidfile,'r') as f: file_content = f.read().strip() if file_content: data = json.loads(file_content) if 'pid' in data and check_pid_running(data['pid']): if 'exit_count' in data and data['exit_count'] > 1: # Third time in, kill the previous process os.kill(int(data['pid']), signal.SIGTERM) else: data['exit_count'] = data.get('exit_count', 0) + 1 with open(pidfile, 'w') as f: json.dump(data, f) sys.exit(0) data['pid'] = os.getpid() data['exit_count'] = 0 with open(pidfile, 'w') as f: json.dump(data, f) test_rpc_liveness() sys.exit(0) # return success ================================================ FILE: nova/templates/bin/_iscsiadm.tpl ================================================ #!/bin/bash {{/* Copyright 2020 The Openstack-Helm Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} chroot /mnt/host-rootfs /usr/bin/env -i PATH="/sbin:/bin:/usr/bin" \ iscsiadm "${@:1}" ================================================ FILE: nova/templates/bin/_multipath.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} chroot /mnt/host-rootfs /usr/bin/env -i PATH="/sbin:/bin:/usr/bin" \ multipath "${@:1}" ================================================ FILE: nova/templates/bin/_multipathd.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} chroot /mnt/host-rootfs /usr/bin/env -i PATH="/sbin:/bin:/usr/bin" \ multipathd "${@:1}" ================================================ FILE: nova/templates/bin/_nova-api-metadata-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex metadata_ip="{{- .Values.endpoints.compute_metadata.ip.ingress -}}" if [ -z "${metadata_ip}" ] ; then metadata_ip=$(getent hosts metadata | awk '{print $1}') fi cat </tmp/pod-shared/nova-api-metadata.ini [DEFAULT] metadata_host=$metadata_ip EOF ================================================ FILE: nova/templates/bin/_nova-api-metadata.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars mkdir -p ${APACHE_RUN_DIR} fi {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} if [ -f /var/run/apache2/apache2.pid ]; then # Remove the stale pid for debian/ubuntu images rm -f /var/run/apache2/apache2.pid fi # Starts Apache2 exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} {{- else }} exec uwsgi --ini /etc/nova/nova-metadata-uwsgi.ini {{- end }} } function stop () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then source /etc/apache2/envvars fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop {{- else }} kill -TERM 1 {{- end }} } $COMMAND ================================================ FILE: nova/templates/bin/_nova-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars mkdir -p ${APACHE_RUN_DIR} fi {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} if [ -f /var/run/apache2/apache2.pid ]; then # Remove the stale pid for debian/ubuntu images rm -f /var/run/apache2/apache2.pid fi # Starts Apache2 exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} {{- else }} exec uwsgi --ini /etc/nova/nova-api-uwsgi.ini {{- end }} } function stop () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then source /etc/apache2/envvars fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop {{- else }} kill -TERM 1 {{- end }} } $COMMAND ================================================ FILE: nova/templates/bin/_nova-compute-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{- if and .Values.hosts_uuids (not .Values.manifests.compute_uuid_self_provisioning) }} # Extract Host's uuid from helm chart and save it to the compute_id file {{- range $host := .Values.hosts_uuids }} hostname="{{- $host.name}}" if [ "$hostname" == $HOSTNAME ]; then echo "{{ $host.uuid }}" > {{ $.Values.conf.nova.DEFAULT.state_path }}/compute_id fi {{- end }} {{- end }} # Make the Nova Instances Dir as this is not autocreated. mkdir -p /var/lib/nova/instances # Set Ownership of nova dirs to the nova user chown ${NOVA_USER_UID} /var/lib/nova /var/lib/nova/instances migration_interface="{{- .Values.conf.libvirt.live_migration_interface -}}" if [[ -z $migration_interface ]]; then # search for interface with default routing # If there is not default gateway, exit migration_network_cidr="{{- .Values.conf.libvirt.live_migration_network_cidr -}}" if [ -z "${migration_network_cidr}" ] ; then migration_network_cidr="0/0" fi migration_interface=$(ip -4 route list ${migration_network_cidr} | awk -F 'dev' '{ print $2; exit }' | awk '{ print $1 }') || exit 1 fi migration_address=$(ip a s $migration_interface | grep 'inet ' | awk '{print $2}' | awk -F "/" '{print $1}' | head -1) if [ -z "${migration_address}" ] ; then echo "Var live_migration_interface is empty" exit 1 fi tee > /tmp/pod-shared/nova-libvirt.conf << EOF [libvirt] live_migration_inbound_addr = $migration_address EOF hypervisor_interface="{{- .Values.conf.hypervisor.host_interface -}}" if [[ -z $hypervisor_interface ]]; then # search for interface with default routing # If there is not default gateway, exit hypervisor_network_cidr="{{- .Values.conf.hypervisor.host_network_cidr -}}" if [ -z "${hypervisor_network_cidr}" ] ; then hypervisor_network_cidr="0/0" fi hypervisor_interface=$(ip -4 route list ${hypervisor_network_cidr} | awk -F 'dev' '{ print $2; exit }' | awk '{ print $1 }') || exit 1 fi hypervisor_address=$(ip a s $hypervisor_interface | grep 'inet ' | awk '{print $2}' | awk -F "/" '{print $1}' | head -1) if [ -z "${hypervisor_address}" ] ; then echo "Var my_ip is empty" exit 1 fi tee > /tmp/pod-shared/nova-hypervisor.conf << EOF [DEFAULT] my_ip = $hypervisor_address EOF {{- if and ( empty .Values.conf.nova.DEFAULT.host ) ( .Values.pod.use_fqdn.compute ) }} tee > /tmp/pod-shared/nova-compute-fqdn.conf << EOF [DEFAULT] host = $(hostname --fqdn) EOF {{- end }} ================================================ FILE: nova/templates/bin/_nova-compute-ironic.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec nova-compute \ --config-file /etc/nova/nova-compute.conf \ --config-file /etc/nova/nova-ironic.conf \ --config-dir /etc/nova/nova.conf.d ================================================ FILE: nova/templates/bin/_nova-compute.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec nova-compute \ --config-file /etc/nova/nova.conf \ {{- if .Values.console.address_search_enabled }} --config-file /tmp/pod-shared/nova-console.conf \ {{- end }} {{- if .Values.conf.libvirt.address_search_enabled }} --config-file /tmp/pod-shared/nova-libvirt.conf \ {{- end }} {{- if and ( empty .Values.conf.nova.DEFAULT.host ) ( .Values.pod.use_fqdn.compute ) }} --config-file /tmp/pod-shared/nova-compute-fqdn.conf \ {{- end }} {{- if .Values.conf.hypervisor.address_search_enabled }} --config-file /tmp/pod-shared/nova-hypervisor.conf \ {{- end }} --config-dir /etc/nova/nova.conf.d ================================================ FILE: nova/templates/bin/_nova-conductor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x exec nova-conductor \ --config-file /etc/nova/nova.conf \ --config-dir /etc/nova/nova.conf.d ================================================ FILE: nova/templates/bin/_nova-console-compute-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex console_kind="{{- .Values.console.console_kind -}}" if [ "${console_kind}" == "novnc" ] ; then client_address="{{- .Values.conf.nova.vnc.server_proxyclient_address -}}" client_interface="{{- .Values.console.novnc.compute.vncserver_proxyclient_interface -}}" client_network_cidr="{{- .Values.console.novnc.compute.vncserver_proxyclient_network_cidr -}}" listen_ip="{{- .Values.conf.nova.vnc.server_listen -}}" elif [ "${console_kind}" == "spice" ] ; then client_address="{{- .Values.conf.nova.spice.server_proxyclient_address -}}" client_interface="{{- .Values.console.spice.compute.server_proxyclient_interface -}}" client_network_cidr="{{- .Values.console.spice.compute.server_proxyclient_network_cidr -}}" listen_ip="{{- .Values.conf.nova.spice.server_listen -}}" elif [ "${console_kind}" == "serial" ] ; then client_address="{{- .Values.conf.nova.serial_console.proxyclient_address -}}" client_interface="{{- .Values.console.serial.compute.server_proxyclient_interface -}}" client_network_cidr="{{- .Values.console.serial.compute.server_proxyclient_network_cidr -}}" fi if [ -z "${client_address}" ] ; then if [ -z "${client_interface}" ] ; then if [ -z "${client_network_cidr}" ] ; then client_network_cidr="0/0" fi client_interface=$(ip -4 route list ${client_network_cidr} | awk -F 'dev' '{ print $2; exit }' | awk '{ print $1 }') || exit 1 fi # determine client ip dynamically based on interface provided client_address=$(ip a s $client_interface | grep 'inet ' | awk '{print $2}' | awk -F "/" '{print $1}' | head -1) fi if [ -z "${listen_ip}" ] ; then # The server component listens on all IP addresses and the proxy component # only listens on the management interface IP address of the compute node. listen_ip=0.0.0.0 fi touch /tmp/pod-shared/nova-console.conf if [ "${console_kind}" == "novnc" ] ; then cat > /tmp/pod-shared/nova-console.conf < /tmp/pod-shared/nova-console.conf < /tmp/pod-shared/nova-console.conf </tmp/pod-shared/nova-vnc.ini [vnc] server_proxyclient_address = $client_address server_listen = $listen_ip novncproxy_host = $listen_ip EOF elif [ "${console_kind}" == "spice" ] ; then cat </tmp/pod-shared/nova-spice.ini [spice] server_proxyclient_address = $client_address server_listen = $listen_ip EOF elif [ "${console_kind}" == "serial" ] ; then cat </tmp/pod-shared/nova-serial.ini [serial_console] proxyclient_address = $client_address EOF fi ================================================ FILE: nova/templates/bin/_nova-console-proxy.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x console_kind="{{- .Values.console.console_kind -}}" if [ "${console_kind}" == "novnc" ] ; then exec nova-novncproxy \ --config-file /etc/nova/nova.conf \ --config-file /tmp/pod-shared/nova-vnc.ini \ --config-dir /etc/nova/nova.conf.d elif [ "${console_kind}" == "spice" ] ; then exec nova-spicehtml5proxy\ --config-file /etc/nova/nova.conf \ --config-file /tmp/pod-shared/nova-spice.ini \ --config-dir /etc/nova/nova.conf.d elif [ "${console_kind}" == "serial" ] ; then exec nova-serialproxy\ --config-file /etc/nova/nova.conf \ --config-file /tmp/pod-shared/nova-serial.ini \ --config-dir /etc/nova/nova.conf.d fi ================================================ FILE: nova/templates/bin/_nova-scheduler.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -xe exec nova-scheduler \ --config-file /etc/nova/nova.conf \ --config-dir /etc/nova/nova.conf.d ================================================ FILE: nova/templates/bin/_nova-service-cleaner.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -xe # If any non-compute service is down, then sleep for 2 times the report_interval # to confirm service is still down. DISABLED_SVC="$(openstack compute service list -f value | grep -v 'nova-compute' | grep 'down' || true)" if [ ! -z "${DISABLED_SVC}" ]; then sleep {{ .Values.jobs.service_cleaner.sleep_time }} fi NOVA_SERVICES_TO_CLEAN="$(openstack compute service list -f value -c Binary | sort | uniq | grep -v '^nova-compute$')" for NOVA_SERVICE in ${NOVA_SERVICES_TO_CLEAN}; do DEAD_SERVICE_IDS=$(openstack compute service list --service ${NOVA_SERVICE} -f json | jq -r '.[] | select(.State == "down") | .ID') for SERVICE_ID in ${DEAD_SERVICE_IDS}; do openstack compute service delete "${SERVICE_ID}" done done {{- if .Values.jobs.service_cleaner.extra_command }} {{ .Values.jobs.service_cleaner.extra_command }} {{- end }} ================================================ FILE: nova/templates/bin/_ssh-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex export NOVA_USERNAME=$(id -u ${NOVA_USER_UID} -n) export NOVA_USER_HOME=$(eval echo ~${NOVA_USERNAME}) mkdir -p ${NOVA_USER_HOME}/.ssh cat > ${NOVA_USER_HOME}/.ssh/config < /tmp/sshd_config_extend <> /etc/ssh/sshd_config rm /tmp/sshd_config_extend mkdir -p /run/sshd exec /usr/sbin/sshd -D -e -o Port=$SSH_PORT ================================================ FILE: nova/templates/bin/_storage-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -x if [ "x$STORAGE_BACKEND" == "xrbd" ]; then SECRET=$(mktemp --suffix .yaml) KEYRING=$(mktemp --suffix .keyring) function cleanup { rm -f ${SECRET} ${KEYRING} } trap cleanup EXIT fi set -ex if [ "x$STORAGE_BACKEND" == "xrbd" ]; then ceph -s function ensure_pool () { ceph osd pool stats $1 || ceph osd pool create $1 $2 if [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -ge 12 ]]; then ceph osd pool application enable $1 $3 fi size_protection=$(ceph osd pool get $1 nosizechange | cut -f2 -d: | tr -d '[:space:]') ceph osd pool set $1 nosizechange 0 ceph osd pool set $1 size ${RBD_POOL_REPLICATION} ceph osd pool set $1 nosizechange ${size_protection} ceph osd pool set $1 crush_rule "${RBD_POOL_CRUSH_RULE}" } ensure_pool ${RBD_POOL_NAME} ${RBD_POOL_CHUNK_SIZE} ${RBD_POOL_APP_NAME} fi ================================================ FILE: nova/templates/bin/_wait-for-computes-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.wait_for_computes.scripts.init_script | default "echo 'No wait-for-compute script configured'" }} ================================================ FILE: nova/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (contains "vencrypt" .Values.conf.nova.vnc.auth_schemes) -}} {{ dict "envAll" . "service" "compute_novnc_vencrypt" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end }} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "compute" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- if .Values.manifests.deployment_novncproxy }} {{ dict "envAll" . "service" "compute_novnc_proxy" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end }} {{- if .Values.manifests.deployment_placement }} {{ dict "envAll" . "service" "placement" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end }} {{ dict "envAll" . "service" "compute_metadata" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- if .Values.manifests.deployment_spiceproxy }} {{ dict "envAll" . "service" "compute_spice_proxy" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end }} {{- if .Values.manifests.deployment_serialproxy }} {{ dict "envAll" . "service" "compute_serial_proxy" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end }} {{- end -}} ================================================ FILE: nova/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: nova-bin data: {{- if .Values.conf.enable_iscsi }} iscsiadm: | {{ tuple "bin/_iscsiadm.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} multipath: | {{ tuple "bin/_multipath.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} multipathd: | {{ tuple "bin/_multipathd.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} storage-init.sh: | {{ tuple "bin/_storage-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- if .Values.conf.ceph.enabled }} ceph-keyring.sh: | {{ tuple "bin/_ceph-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ceph-admin-keyring.sh: | {{ tuple "bin/_ceph-admin-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- if .Values.manifests.cron_job_archive_deleted_rows }} archive-deleted-rows.sh: | {{ tuple "bin/_db-archive-deleted-row.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} health-probe.py: | {{ tuple "bin/_health-probe.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-api.sh: | {{ tuple "bin/_nova-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-api-metadata.sh: | {{ tuple "bin/_nova-api-metadata.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-api-metadata-init.sh: | {{ tuple "bin/_nova-api-metadata-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-compute.sh: | {{ tuple "bin/_nova-compute.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-compute-init.sh: | {{ tuple "bin/_nova-compute-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-compute-ironic.sh: | {{ tuple "bin/_nova-compute-ironic.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-conductor.sh: | {{ tuple "bin/_nova-conductor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-scheduler.sh: | {{ tuple "bin/_nova-scheduler.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} fake-iptables.sh: | {{ tuple "bin/_fake-iptables.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-console-compute-init.sh: | {{ tuple "bin/_nova-console-compute-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-console-proxy.sh: | {{ tuple "bin/_nova-console-proxy.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-console-proxy-init.sh: | {{ tuple "bin/_nova-console-proxy-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-console-proxy-init-assets.sh: | {{ tuple "bin/_nova-console-proxy-init-assets.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ssh-init.sh: | {{ tuple "bin/_ssh-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ssh-start.sh: | {{ tuple "bin/_ssh-start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} cell-setup.sh: | {{ tuple "bin/_cell-setup.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} cell-setup-init.sh: | {{ tuple "bin/_cell-setup-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-service-cleaner.sh: | {{ tuple "bin/_nova-service-cleaner.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} wait-for-computes-init.sh: | {{ tuple "bin/_wait-for-computes-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: nova/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- define "nova.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty .Values.conf.nova.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.nova.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.nova.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.nova.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.nova.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.nova.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if .Values.conf.nova.service_user.send_service_user_token -}} {{- if empty .Values.conf.nova.service_user.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.service_user "auth_url" -}} {{- end -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.nova.database.connection)) (empty .Values.conf.nova.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "nova" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.nova.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.nova.database "connection" $connection -}} {{- end -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.nova.api_database.connection)) (empty .Values.conf.nova.api_database.connection) -}} {{- $connection := tuple "oslo_db_api" "internal" "nova" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.nova.api_database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.nova.api_database "connection" $connection -}} {{- end -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.nova.cell0_database.connection)) (empty .Values.conf.nova.cell0_database.connection) -}} {{- $connection := tuple "oslo_db_cell0" "internal" "nova" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.nova.cell0_database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.nova.cell0_database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.nova.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "nova" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.nova.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.nova.glance.api_servers -}} {{- $_ := tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.glance "api_servers" -}} {{- end -}} {{- if empty .Values.conf.nova.neutron.url -}} {{- $_ := tuple "network" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.neutron "url" -}} {{- end -}} {{- if empty .Values.conf.nova.neutron.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.neutron "auth_url" -}} {{- end -}} {{- if empty .Values.conf.nova.cache.memcache_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.nova.cache "memcache_servers" -}} {{- end -}} {{- if and (empty .Values.conf.nova.DEFAULT.metadata_host) .Values.endpoints.compute_metadata.ip.ingress -}} {{- $_ := set .Values.conf.nova.DEFAULT "metadata_host" .Values.endpoints.compute_metadata.ip.ingress -}} {{- end -}} {{- if empty .Values.conf.nova.DEFAULT.metadata_listen_port -}} {{- $_ := tuple "compute_metadata" "internal" "metadata" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.nova.DEFAULT "metadata_listen_port" -}} {{- end -}} {{- if empty .Values.conf.nova.placement.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.nova.placement "auth_url" -}} {{- end -}} {{- if eq .Values.console.console_kind "novnc"}} {{- $_ := "true" | set .Values.conf.nova.vnc "enabled" -}} {{- if empty .Values.conf.nova.vnc.novncproxy_base_url -}} {{- $_ := tuple "compute_novnc_proxy" "public" "novnc_proxy" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.vnc "novncproxy_base_url" -}} {{- end -}} {{- if empty .Values.conf.nova.vnc.novncproxy_port -}} {{- $_ := tuple "compute_novnc_proxy" "internal" "novnc_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.nova.vnc "novncproxy_port" -}} {{- end -}} {{- end -}} {{- if (contains "vencrypt" .Values.conf.nova.vnc.auth_schemes) -}} {{- if empty .Values.conf.nova.vnc.vencrypt_client_key }} {{- $_ := set $envAll.Values.conf.nova.vnc "vencrypt_client_key" "/etc/pki/nova-novncproxy/tls.key" -}} {{- end }} {{- if empty .Values.conf.nova.vnc.vencrypt_client_cert }} {{- $_ := set $envAll.Values.conf.nova.vnc "vencrypt_client_cert" "/etc/pki/nova-novncproxy/tls.crt" -}} {{- end }} {{- if empty .Values.conf.nova.vnc.vencrypt_ca_certs }} {{- $_ := set $envAll.Values.conf.nova.vnc "vencrypt_ca_certs" "/etc/pki/nova-novncproxy/ca.crt" -}} {{- end }} {{- end }} {{- if eq .Values.console.console_kind "spice"}} {{- $_ := "false" | set .Values.conf.nova.vnc "enabled" -}} {{- $_ := "true" | set .Values.conf.nova.spice "enabled" -}} {{- if empty .Values.conf.nova.spice.html5proxy_base_url -}} {{- $_ := tuple "compute_spice_proxy" "public" "spice_proxy" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.spice "html5proxy_base_url" -}} {{- end -}} {{- if empty .Values.conf.nova.spice.html5proxy_port -}} {{- $_ := tuple "compute_spice_proxy" "internal" "spice_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.nova.spice "html5proxy_port" -}} {{- end -}} {{- end -}} {{- if eq .Values.console.console_kind "serial"}} {{- $_ := "false" | set .Values.conf.nova.vnc "enabled" -}} {{- $_ := "false" | set .Values.conf.nova.spice "enabled" -}} {{- $_ := "true" | set .Values.conf.nova.serial_console "enabled" -}} {{- if empty .Values.conf.nova.serial_console.base_url -}} {{- $_ := tuple "compute_serial_proxy" "public" "serial_proxy" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.serial_console "base_url" -}} {{- end -}} {{- if empty .Values.conf.nova.serial_console.serialproxy_port -}} {{- $_ := tuple "compute_serial_proxy" "internal" "serial_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.nova.serial_console "serialproxy_port" -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.nova.ironic.api_endpoint -}} {{- $_ := tuple "baremetal" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.ironic "api_endpoint" -}} {{- end -}} {{- if empty .Values.conf.nova.ironic.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.ironic "auth_url" -}} {{- end -}} {{- if empty .Values.conf.nova.ironic.auth_type -}} {{- $_ := set .Values.conf.nova.ironic "auth_type" .Values.endpoints.identity.auth.ironic.auth_type -}} {{- end -}} {{- if empty .Values.conf.nova.ironic.auth_version -}} {{- $_ := set .Values.conf.nova.ironic "auth_version" .Values.endpoints.identity.auth.ironic.auth_version -}} {{- end -}} {{- if .Values.conf.nova.cinder.auth_type -}} {{- if eq .Values.conf.nova.cinder.auth_type "password" -}} {{- if empty .Values.conf.nova.cinder.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova.cinder "auth_url" -}} {{- end -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.nova.DEFAULT.osapi_compute_listen_port -}} {{- $_ := tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.nova.DEFAULT "osapi_compute_listen_port" -}} {{- end -}} {{- if empty .Values.conf.nova_api_uwsgi.uwsgi.processes -}} {{- $_ := set .Values.conf.nova_api_uwsgi.uwsgi "processes" .Values.conf.nova.DEFAULT.osapi_compute_workers -}} {{- end -}} {{- if empty (index .Values.conf.nova_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.nova_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} {{- if empty .Values.conf.nova_metadata_uwsgi.uwsgi.processes -}} {{- $_ := set .Values.conf.nova_metadata_uwsgi.uwsgi "processes" .Values.conf.nova.DEFAULT.metadata_workers -}} {{- end -}} {{- if empty (index .Values.conf.nova_metadata_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := .Values.network.metadata.port | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.nova_metadata_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .deployment_name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} {{ $__nova_compute := dict }} {{ $_ := set $__nova_compute "config" .Values.conf.nova }} {{ range .Values.conf.nova_compute_redactions }} {{ $_ := set $__nova_compute "config" (omit $__nova_compute.config .) }} {{ end }} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} nova_sudoers: {{ $envAll.Values.conf.nova_sudoers | b64enc }} rootwrap.conf: {{ .Values.conf.rootwrap | b64enc }} {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- $filePrefix := replace "_" "-" $key }} {{ printf "%s.filters" $filePrefix }}: {{ $value.content | b64enc }} {{- end }} nova.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.nova | b64enc }} nova-compute.conf: {{ include "helm-toolkit.utils.to_oslo_conf" $__nova_compute.config | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api_audit_map.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.api_audit_map | b64enc }} nova-ironic.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.nova_ironic | b64enc }} nova-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.nova_api_uwsgi | b64enc }} nova-metadata-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.nova_metadata_uwsgi | b64enc }} {{- if .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.mpm_event "key" "mpm_event.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_nova_api "key" "wsgi-api.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_nova_metadata "key" "wsgi-metadata.conf" "format" "Secret" ) | indent 2 }} {{- end }} {{- if .Values.conf.security }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.security "key" "security.conf" "format" "Secret" ) | indent 2 }} {{- end }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "nova-etc" . | include "nova.configmap.etc" }} {{- end }} ================================================ FILE: nova/templates/cron-job-archive-deleted-rows.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_archive_deleted_rows }} {{- $envAll := . }} {{- $serviceAccountName := "nova-archive-deleted-rows-cron" }} {{ tuple $envAll "archive_deleted_rows" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.nova_archive_deleted_rows }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} --- apiVersion: batch/v1 kind: CronJob metadata: name: nova-archive-deleted-rows annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.archive_deleted_rows.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.archive_deleted_rows.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.archive_deleted_rows.history.failed }} {{- if .Values.jobs.archive_deleted_rows.starting_deadline }} startingDeadlineSeconds: {{ .Values.jobs.archive_deleted_rows.starting_deadline }} {{- end }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "nova" "archive-deleted-rows" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "nova" "archive-deleted-rows" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ tuple "nova_archive_deleted_rows" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "nova_archive_deleted_rows" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "archive_deleted_rows" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} initContainers: {{ tuple $envAll "archive-deleted-rows" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: nova-archive-deleted-rows {{ tuple $envAll "nova_archive_deleted_rows" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.archive_deleted_rows | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "archive_deleted_rows" "container" "nova_archive_deleted_rows" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - /tmp/archive-deleted-rows.sh {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: archive-deleted-rows-conf mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true - name: archive-deleted-rows-conf mountPath: /etc/nova/logging.conf subPath: logging.conf readOnly: true - name: archive-deleted-rows mountPath: /tmp/archive-deleted-rows.sh readOnly: true subPath: archive-deleted-rows.sh {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} volumes: - name: pod-tmp emptyDir: {} - name: archive-deleted-rows configMap: name: nova-bin defaultMode: 0555 - name: archive-deleted-rows-conf secret: secretName: nova-etc - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- end }} ================================================ FILE: nova/templates/cron-job-cell-setup.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_cell_setup }} {{- $envAll := . }} {{- $etcSources := .Values.pod.etcSources.nova_cell_setup }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-cell-setup-cron" }} {{ tuple $envAll "cell_setup" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: nova-cell-setup annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.cell_setup.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.cell_setup.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.cell_setup.history.failed }} {{- if .Values.jobs.cell_setup.starting_deadline }} startingDeadlineSeconds: {{ .Values.jobs.cell_setup.starting_deadline }} {{- end }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "nova" "cell-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "nova" "cell-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ tuple "nova_cell_setup" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "nova_cell_setup" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "cell_setup" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} initContainers: {{ tuple $envAll "cell_setup" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: nova-cell-setup {{ tuple $envAll "nova_cell_setup" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.cell_setup | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "cell_setup" "container" "nova_cell_setup" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - /tmp/cell-setup.sh {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/cell-setup.sh subPath: cell-setup.sh readOnly: true - name: etcnova mountPath: /etc/nova - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} volumes: - name: pod-tmp emptyDir: {} - name: etcnova emptyDir: {} - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- end }} ================================================ FILE: nova/templates/cron-job-service-cleaner.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_service_cleaner }} {{- $envAll := . }} {{- $serviceAccountName := "nova-service-cleaner" }} {{ tuple $envAll "service_cleaner" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.nova_service_cleaner }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} --- apiVersion: batch/v1 kind: CronJob metadata: name: nova-service-cleaner annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: schedule: {{ .Values.jobs.service_cleaner.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.service_cleaner.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.service_cleaner.history.failed }} {{- if .Values.jobs.service_cleaner.starting_deadline }} startingDeadlineSeconds: {{ .Values.jobs.service_cleaner.starting_deadline }} {{- end }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "nova" "service-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "nova" "service-cleaner" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ tuple "nova_service_cleaner" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "nova_service_cleaner" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "service_cleaner" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} initContainers: {{ tuple $envAll "service_cleaner" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: nova-service-cleaner {{ tuple $envAll "nova_service_cleaner" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.service_cleaner | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "service_cleaner" "container" "nova_service_cleaner" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.nova "useCA" (or .Values.manifests.certificates .Values.tls.identity) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 14 }} {{- end }} command: - /tmp/nova-service-cleaner.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-service-cleaner.sh subPath: nova-service-cleaner.sh readOnly: true - name: etcnova mountPath: /etc/nova - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 16 }} volumes: - name: pod-tmp emptyDir: {} - name: etcnova emptyDir: {} - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 18 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 12 }} {{- end }} ================================================ FILE: nova/templates/daemonset-compute.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaComputeLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - compute - --liveness-probe {{- if .Values.pod.use_fqdn.compute }} - --use-fqdn {{- end }} {{- end }} {{- define "novaComputeReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - compute {{- if .Values.pod.use_fqdn.compute }} - --use-fqdn {{- end }} {{- end }} {{- define "novaComputeStartupProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - compute - --liveness-probe {{- if .Values.pod.use_fqdn.compute }} - --use-fqdn {{- end }} {{- end }} {{- define "nova.compute.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $mounts_nova_compute := .Values.pod.mounts.nova_compute.nova_compute }} {{- $mounts_nova_compute_init := .Values.pod.mounts.nova_compute.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_compute }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: nova-compute annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll $daemonset | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll .Chart.Name $daemonset | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_compute" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-compute-default" "containerNames" (list "nova-compute" "init" "nova-compute-init" "nova-compute-vnc-init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_compute" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_compute" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} nodeSelector: {{ .Values.labels.agent.compute.node_selector_key }}: {{ .Values.labels.agent.compute.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} hostNetwork: true hostPID: true hostIPC: true dnsPolicy: ClusterFirstWithHostNet initContainers: {{ tuple $envAll "pod_dependency" $mounts_nova_compute_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: nova-compute-init {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_compute_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: NOVA_USER_UID value: "{{ .Values.pod.security_context.nova.pod.runAsUser }}" command: - /tmp/nova-compute-init.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-compute-init.sh subPath: nova-compute-init.sh readOnly: true - name: varlibnova mountPath: /var/lib/nova - name: pod-shared mountPath: /tmp/pod-shared {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{- if .Values.conf.ceph.enabled }} - name: ceph-perms {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "ceph_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - "nova:" - /etc/ceph terminationMessagePath: /var/log/termination-log volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{- if empty .Values.conf.ceph.cinder.keyring }} - name: ceph-admin-keyring-placement {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "ceph_admin_keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ceph-admin-keyring.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph - name: nova-bin mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true {{- if empty .Values.conf.ceph.admin_keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{ end }} - name: ceph-keyring-placement {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "ceph_keyring_placement" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: CEPH_CINDER_USER value: "{{ .Values.conf.ceph.cinder.user }}" {{- if .Values.conf.ceph.cinder.keyring }} - name: CEPH_CINDER_KEYRING value: "{{ .Values.conf.ceph.cinder.keyring }}" {{ end }} - name: LIBVIRT_CEPH_SECRET_UUID value: "{{ .Values.conf.ceph.secret_uuid }}" command: - /tmp/ceph-keyring.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph - name: nova-bin mountPath: /tmp/ceph-keyring.sh subPath: ceph-keyring.sh - name: ceph-etc mountPath: /etc/ceph/ceph.conf.template subPath: ceph.conf readOnly: true {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{ end }} {{- if eq .Values.console.console_kind "novnc"}} - name: nova-compute-vnc-init {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.compute | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_compute_vnc_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-compute-init.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-compute-init.sh subPath: nova-console-compute-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{ end }} {{- if eq .Values.console.console_kind "spice"}} - name: nova-compute-spice-init {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.compute | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_compute_spice_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-compute-init.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-compute-init.sh subPath: nova-console-compute-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{ end }} {{- if eq .Values.console.console_kind "serial"}} - name: nova-compute-serial-init {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.compute | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_compute_serial_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-compute-init.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-compute-init.sh subPath: nova-console-compute-init.sh readOnly: true - name: pod-shared mountPath: /tmp/pod-shared {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{ end }} {{- if .Values.network.ssh.enabled }} - name: nova-compute-ssh-init {{ tuple $envAll "nova_compute_ssh" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ssh | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_compute_ssh_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} terminationMessagePath: /var/log/termination-log env: - name: SSH_PORT value: {{ .Values.network.ssh.port | quote }} - name: NOVA_USER_UID value: "{{ .Values.pod.security_context.nova.pod.runAsUser }}" command: - /tmp/ssh-init.sh volumeMounts: - name: varlibnova mountPath: /var/lib/nova - name: nova-ssh mountPath: /tmp/nova-ssh/authorized_keys subPath: public-key - name: nova-ssh mountPath: /tmp/nova-ssh/id_rsa subPath: private-key - name: nova-bin mountPath: /tmp/ssh-init.sh subPath: ssh-init.sh readOnly: true {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{- end }} containers: - name: nova-compute {{ tuple $envAll "nova_compute" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.compute | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_compute" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- if .Values.conf.ceph.enabled }} - name: CEPH_CINDER_USER value: "{{ .Values.conf.ceph.cinder.user }}" {{- if .Values.conf.ceph.cinder.keyring }} - name: CEPH_CINDER_KEYRING value: "{{ .Values.conf.ceph.cinder.keyring }}" {{ end }} - name: LIBVIRT_CEPH_SECRET_UUID value: "{{ .Values.conf.ceph.secret_uuid }}" {{ end }} - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} {{ dict "envAll" $envAll "component" "compute" "container" "default" "type" "liveness" "probeTemplate" (include "novaComputeLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "compute" "container" "default" "type" "readiness" "probeTemplate" (include "novaComputeReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "compute" "container" "default" "type" "startup" "probeTemplate" (include "novaComputeStartupProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/nova-compute.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: dev-pts mountPath: /dev/pts - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-compute.sh subPath: nova-compute.sh readOnly: true - name: nova-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova-compute.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/api-paste.ini subPath: api-paste.ini readOnly: true - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true - name: nova-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_nova_sudoers subPath: nova_sudoers readOnly: true - name: nova-etc mountPath: /etc/nova/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "compute" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/nova/rootwrap.d/%s.filters" $filePrefix }} - name: nova-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} {{- if .Values.conf.ceph.enabled }} - name: etcceph mountPath: /etc/ceph {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: Bidirectional {{- end }} {{- if and ( empty .Values.conf.ceph.cinder.keyring ) ( empty .Values.conf.ceph.admin_keyring )}} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} {{ end }} - mountPath: /lib/modules name: libmodules readOnly: true - name: varlibnova mountPath: /var/lib/nova {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: Bidirectional {{- end }} - name: varliblibvirt mountPath: /var/lib/libvirt {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: Bidirectional {{- end }} - name: run mountPath: /run - name: cgroup mountPath: /sys/fs/cgroup readOnly: true - name: pod-shared mountPath: /tmp/pod-shared - name: machine-id mountPath: /etc/machine-id readOnly: true {{- if .Values.conf.enable_iscsi }} - name: host-rootfs mountPath: /mnt/host-rootfs mountPropagation: HostToContainer - name: usrlocalsbin mountPath: /usr/local/sbin - name: etciscsi mountPath: /etc/iscsi {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: HostToContainer {{- end }} - name: dev mountPath: /dev {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: HostToContainer {{- end }} - name: nova-bin mountPath: /usr/local/sbin/iscsiadm subPath: iscsiadm - name: runlock mountPath: /run/lock - name: nova-bin mountPath: /usr/local/sbin/multipath subPath: multipath - name: nova-bin mountPath: /usr/local/sbin/multipathd subPath: multipathd - name: etcmultipath mountPath: /etc/multipath {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: Bidirectional {{- end }} - name: sysblock mountPath: /sys/block {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }} mountPropagation: HostToContainer {{- end }} {{- end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{- if .Values.network.ssh.enabled }} - name: nova-compute-ssh {{ tuple $envAll "nova_compute_ssh" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ssh | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_compute_ssh" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: KEY_TYPES value: {{ include "helm-toolkit.utils.joinListWithComma" .Values.network.ssh.key_types | quote }} - name: SSH_PORT value: {{ .Values.network.ssh.port | quote }} {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} ports: - containerPort: {{ .Values.network.ssh.port }} command: - /tmp/ssh-start.sh terminationMessagePath: /var/log/termination-log volumeMounts: - name: varlibnova mountPath: /var/lib/nova - name: nova-bin mountPath: /tmp/ssh-start.sh subPath: ssh-start.sh readOnly: true {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- if .Values.network.ssh.enabled }} - name: nova-ssh secret: secretName: nova-ssh defaultMode: 0644 {{ end }} {{- if .Values.conf.ceph.enabled }} - name: etcceph hostPath: path: /var/lib/openstack-helm/compute/nova - name: ceph-etc configMap: name: {{ .Values.ceph_client.configmap }} defaultMode: 0444 {{- if and ( empty .Values.conf.ceph.cinder.keyring ) ( empty .Values.conf.ceph.admin_keyring ) }} - name: ceph-keyring secret: secretName: {{ .Values.ceph_client.user_secret_name }} {{ end }} {{ end }} - name: dev-pts hostPath: path: /dev/pts - name: libmodules hostPath: path: /lib/modules - name: varlibnova hostPath: path: /var/lib/nova - name: varliblibvirt hostPath: path: /var/lib/libvirt - name: run hostPath: path: /run - name: cgroup hostPath: path: /sys/fs/cgroup - name: pod-shared emptyDir: {} - name: machine-id hostPath: path: /etc/machine-id {{- if .Values.conf.enable_iscsi }} - name: host-rootfs hostPath: path: / - name: runlock hostPath: path: /run/lock - name: etciscsi hostPath: path: /etc/iscsi - name: dev hostPath: path: /dev - name: usrlocalsbin emptyDir: {} - name: etcmultipath hostPath: path: /etc/multipath - name: sysblock hostPath: path: /sys/block {{- end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_compute.volumes }}{{ toYaml $mounts_nova_compute.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_compute }} {{- $envAll := . }} {{- $daemonset := "compute" }} {{- $configMapName := "nova-etc" }} {{- $serviceAccountName := "nova-compute" }} {{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "compute" -}} {{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }} {{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "nova.compute.daemonset" | toString | fromYaml }} {{- $configmap_yaml := "nova.configmap.etc" }} {{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }} {{- end }} ================================================ FILE: nova/templates/deployment-api-metadata.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaApiMetadataLivenessProbeTemplate" }} httpGet: scheme: {{ tuple "compute_metadata" "service" "metadata" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ .Values.network.metadata.port }} {{- end }} {{- define "novaApiMetadataReadinessProbeTemplate" }} httpGet: scheme: {{ tuple "compute_metadata" "service" "metadata" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ .Values.network.metadata.port }} {{- end }} {{- if .Values.manifests.deployment_api_metadata }} {{- $envAll := . }} {{- $mounts_nova_api_metadata := .Values.pod.mounts.nova_api_metadata.nova_api_metadata }} {{- $mounts_nova_api_metadata_init := .Values.pod.mounts.nova_api_metadata.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_api_metadata }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-api-metadata" }} {{ tuple $envAll "api_metadata" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: nova-api-metadata annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "metadata" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api_metadata }} selector: matchLabels: {{ tuple $envAll "nova" "metadata" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "metadata" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_api_metadata" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-api-metadata" "containerNames" (list "nova-api-metadata-init" "nova-api" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_api_metadata" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_api_metadata" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "metadata" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api_metadata.node_selector_key }}: {{ .Values.labels.api_metadata.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.metadata.timeout | default "30" }} initContainers: {{ tuple $envAll "api_metadata" $mounts_nova_api_metadata_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: nova-api-metadata-init {{ tuple $envAll "nova_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api_metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_api_metadata_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-api-metadata-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-api-metadata-init.sh subPath: nova-api-metadata-init.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true - name: pod-shared mountPath: /tmp/pod-shared containers: - name: nova-api {{ tuple $envAll "nova_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api_metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} command: - /tmp/nova-api-metadata.sh - start lifecycle: preStop: exec: command: - /tmp/nova-api-metadata.sh - stop ports: - containerPort: {{ .Values.network.metadata.port }} {{ dict "envAll" $envAll "component" "api-metadata" "container" "default" "type" "liveness" "probeTemplate" (include "novaApiMetadataLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "api-metadata" "container" "default" "type" "readiness" "probeTemplate" (include "novaApiMetadataReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-api-metadata.sh subPath: nova-api-metadata.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova-metadata-uwsgi.ini subPath: nova-metadata-uwsgi.ini readOnly: true - name: nova-bin mountPath: /sbin/iptables subPath: fake-iptables.sh readOnly: true - name: nova-bin mountPath: /sbin/iptables-restore subPath: fake-iptables.sh readOnly: true - name: nova-bin mountPath: /sbin/iptables-save subPath: fake-iptables.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/api-paste.ini subPath: api-paste.ini readOnly: true - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true - name: nova-etc mountPath: /etc/nova/api_audit_map.conf subPath: api_audit_map.conf readOnly: true - name: nova-etc # NOTE (Portdirect): We mount here to override Kollas # custom sudoers file when using Kolla images, this # location will also work fine for other images. mountPath: /etc/sudoers.d/kolla_nova_sudoers subPath: nova_sudoers readOnly: true - name: nova-etc mountPath: /etc/nova/rootwrap.conf subPath: rootwrap.conf readOnly: true {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- if ( has "metadata" $value.pods ) }} {{- $filePrefix := replace "_" "-" $key }} {{- $rootwrapFile := printf "/etc/nova/rootwrap.d/%s.filters" $filePrefix }} - name: nova-etc mountPath: {{ $rootwrapFile }} subPath: {{ base $rootwrapFile }} readOnly: true {{- end }} {{- end }} - name: pod-shared mountPath: /tmp/pod-shared readOnly: true {{- if .Values.manifests.certificates }} - name: nova-etc mountPath: {{ .Values.conf.software.apache2.conf_dir }}/wsgi-metadata.conf subPath: wsgi-metadata.conf readOnly: true - name: nova-etc mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf subPath: mpm_event.conf readOnly: true {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute_metadata.metadata.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_api_metadata.volumeMounts }}{{ toYaml $mounts_nova_api_metadata.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: pod-shared emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_api_metadata.volumes }}{{ toYaml $mounts_nova_api_metadata.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/deployment-api-osapi.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaApiOsapiLivenessProbeTemplate" }} httpGet: scheme: {{ tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "novaApiOsapiReadinessProbeTemplate" }} httpGet: scheme: {{ tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api_osapi }} {{- $envAll := . }} {{- $mounts_nova_api_osapi := .Values.pod.mounts.nova_api_osapi.nova_api_osapi }} {{- $mounts_nova_api_osapi_init := .Values.pod.mounts.nova_api_osapi.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_api_osapi }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-api-osapi" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: nova-api-osapi annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "os-api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.osapi }} selector: matchLabels: {{ tuple $envAll "nova" "os-api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "os-api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_api_osapi" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-api-osapi" "containerNames" (list "nova-osapi" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_api_osapi" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_api_osapi" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "os-api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.osapi.node_selector_key }}: {{ .Values.labels.osapi.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.osapi.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_nova_api_osapi_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: nova-osapi {{ tuple $envAll "nova_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_osapi" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} command: - /tmp/nova-api.sh - start lifecycle: preStop: exec: command: - /tmp/nova-api.sh - stop ports: - name: n-api containerPort: {{ tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "api-osapi" "container" "default" "type" "liveness" "probeTemplate" (include "novaApiOsapiLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "api-osapi" "container" "default" "type" "readiness" "probeTemplate" (include "novaApiOsapiReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: pod-var-nova mountPath: /var/lib/nova - name: nova-bin mountPath: /tmp/nova-api.sh subPath: nova-api.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true - name: nova-etc mountPath: /etc/nova/nova-api-uwsgi.ini subPath: nova-api-uwsgi.ini readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/api-paste.ini subPath: api-paste.ini readOnly: true - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true - name: nova-etc mountPath: /etc/nova/api_audit_map.conf subPath: api_audit_map.conf readOnly: true {{- if .Values.manifests.certificates }} - name: nova-etc mountPath: {{ .Values.conf.software.apache2.conf_dir }}/wsgi-api.conf subPath: wsgi-api.conf readOnly: true - name: nova-etc mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf subPath: mpm_event.conf readOnly: true {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_api_osapi.volumeMounts }}{{ toYaml $mounts_nova_api_osapi.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-var-nova emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_api_osapi.volumes}}{{ toYaml $mounts_nova_api_osapi.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/deployment-conductor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaConductorLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - conductor - --liveness-probe {{- end }} {{- define "novaConductorReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - conductor {{- end }} {{- if and .Values.manifests.deployment_conductor (not .Values.manifests.statefulset_conductor) }} {{- $envAll := . }} {{- $mounts_nova_conductor := .Values.pod.mounts.nova_conductor.nova_conductor }} {{- $mounts_nova_conductor_init := .Values.pod.mounts.nova_conductor.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_conductor }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-conductor" }} {{ tuple $envAll "conductor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: nova-conductor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.conductor }} selector: matchLabels: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_conductor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-conductor" "containerNames" (list "nova-conductor" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.conductor.node_selector_key }}: {{ .Values.labels.conductor.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "conductor" $mounts_nova_conductor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: nova-conductor {{ tuple $envAll "nova_conductor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.conductor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_conductor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "conductor" "container" "default" "type" "liveness" "probeTemplate" (include "novaConductorLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "conductor" "container" "default" "type" "readiness" "probeTemplate" (include "novaConductorReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} command: - /tmp/nova-conductor.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-conductor.sh subPath: nova-conductor.sh readOnly: true - name: nova-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" "certs" (tuple "ca.crt") | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_conductor.volumeMounts }}{{ toYaml $mounts_nova_conductor.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_conductor.volumes }}{{ toYaml $mounts_nova_conductor.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/deployment-novncproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaNovncproxyLivenessProbeTemplate" }} tcpSocket: port: {{ tuple "compute_novnc_proxy" "internal" "novnc_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "novaNovncproxyReadinessProbeTemplate" }} tcpSocket: port: {{ tuple "compute_novnc_proxy" "internal" "novnc_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if and .Values.manifests.deployment_novncproxy ( eq .Values.console.console_kind "novnc" )}} {{- $envAll := . }} {{- $mounts_nova_novncproxy := .Values.pod.mounts.nova_novncproxy.nova_novncproxy }} {{- $mounts_nova_novncproxy_init := .Values.pod.mounts.nova_novncproxy.init_novncproxy }} {{- $etcSources := .Values.pod.etcSources.nova_novncproxy }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $vencrypt_enabled := (contains "vencrypt" .Values.conf.nova.vnc.auth_schemes) }} {{- $serviceAccountName := "nova-novncproxy" }} {{ tuple $envAll "novncproxy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: nova-novncproxy annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "novnc-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.novncproxy }} selector: matchLabels: {{ tuple $envAll "nova" "novnc-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "novnc-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_novncproxy" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-novncproxy" "containerNames" (list "nova-novncproxy" "nova-novncproxy-init-assets" "nova-novncproxy-init" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_novncproxy" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_novncproxy" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "novnc-proxy" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.novncproxy.node_selector_key }}: {{ .Values.labels.novncproxy.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} {{- if .Values.pod.useHostNetwork.novncproxy }} hostNetwork: true dnsPolicy: ClusterFirstWithHostNet {{- end }} initContainers: {{ tuple $envAll "novncproxy" $mounts_nova_novncproxy_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: nova-novncproxy-init {{ tuple $envAll "nova_novncproxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.novncproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_novncproxy_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-proxy-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-proxy-init.sh subPath: nova-console-proxy-init.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: pod-shared mountPath: /tmp/pod-shared - name: nova-novncproxy-init-assets {{ tuple $envAll "nova_novncproxy_assets" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.novncproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_novncproxy_init_assests" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-proxy-init-assets.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-proxy-init-assets.sh subPath: nova-console-proxy-init-assets.sh readOnly: true - name: pod-usr-share-novnc mountPath: /tmp/usr/share/novnc containers: - name: nova-novncproxy {{ tuple $envAll "nova_novncproxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.novncproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_novncproxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "novncproxy" "container" "default" "type" "liveness" "probeTemplate" (include "novaNovncproxyLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "novncproxy" "container" "default" "type" "readiness" "probeTemplate" (include "novaNovncproxyReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/nova-console-proxy.sh ports: - name: n-novnc containerPort: {{ tuple "compute_novnc_proxy" "internal" "novnc_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-console-proxy.sh subPath: nova-console-proxy.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d readOnly: true - name: nova-etc mountPath: /etc/nova/logging.conf subPath: logging.conf readOnly: true - name: pod-usr-share-novnc mountPath: /usr/share/novnc readOnly: true - name: pod-shared mountPath: /tmp/pod-shared {{- if $vencrypt_enabled }} - name: {{ .Values.secrets.tls.compute_novnc_proxy.vencrypt.internal }} mountPath: /etc/pki/nova-novncproxy readOnly: true {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_novnc_proxy.novncproxy.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_novncproxy.volumeMounts }}{{ toYaml $mounts_nova_novncproxy.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: pod-usr-share-novnc emptyDir: {} - name: pod-shared emptyDir: {} {{- if $vencrypt_enabled }} - name: {{ .Values.secrets.tls.compute_novnc_proxy.vencrypt.internal }} secret: secretName: {{ .Values.secrets.tls.compute_novnc_proxy.vencrypt.internal }} defaultMode: 0444 {{- end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_novnc_proxy.novncproxy.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_novncproxy.volumes }}{{ toYaml $mounts_nova_novncproxy.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/deployment-scheduler.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaSchedulerLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - scheduler - --liveness-probe {{- end }} {{- define "novaSchedulerReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - scheduler {{- end }} {{- if and .Values.manifests.deployment_scheduler (not .Values.manifests.statefulset_scheduler) }} {{- $envAll := . }} {{- $mounts_nova_scheduler := .Values.pod.mounts.nova_scheduler.nova_scheduler }} {{- $mounts_nova_scheduler_init := .Values.pod.mounts.nova_scheduler.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_scheduler }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-scheduler" }} {{ tuple $envAll "scheduler" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: nova-scheduler annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.scheduler }} selector: matchLabels: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-scheduler" "containerNames" (list "nova-scheduler" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.scheduler.node_selector_key }}: {{ .Values.labels.scheduler.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "scheduler" $mounts_nova_scheduler_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: nova-scheduler {{ tuple $envAll "nova_scheduler" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.scheduler | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_scheduler" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "scheduler" "container" "default" "type" "liveness" "probeTemplate" (include "novaSchedulerLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "scheduler" "container" "default" "type" "readiness" "probeTemplate" (include "novaSchedulerReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} command: - /tmp/nova-scheduler.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-scheduler.sh subPath: nova-scheduler.sh readOnly: true - name: nova-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_scheduler.volumeMounts }}{{ toYaml $mounts_nova_scheduler.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_scheduler.volumes }}{{ toYaml $mounts_nova_scheduler.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/deployment-serialproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaSerialproxyLivenessProbeTemplate" }} tcpSocket: port: {{ tuple "compute_serial_proxy" "internal" "serial_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "novaSerialproxyReadinessProbeTemplate" }} tcpSocket: port: {{ tuple "compute_serial_proxy" "internal" "serial_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if and .Values.manifests.deployment_serialproxy ( eq .Values.console.console_kind "serial" )}} {{- $envAll := . }} {{- $mounts_nova_serialproxy := .Values.pod.mounts.nova_serialproxy.nova_serialproxy }} {{- $mounts_nova_serialproxy_init := .Values.pod.mounts.nova_serialproxy.init_serialproxy }} {{- $etcSources := .Values.pod.etcSources.nova_serialproxy }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-serialproxy" }} {{ tuple $envAll "serialproxy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: nova-serialproxy annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "serial-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.serialproxy }} selector: matchLabels: {{ tuple $envAll "nova" "serial-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "serial-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_serialproxy" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-serialproxy" "containerNames" (list "nova-serialproxy" "nova-serialproxy-init-assets" "nova-serialproxy-init" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_serialproxy" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_serialproxy" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "serial-proxy" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.serialproxy.node_selector_key }}: {{ .Values.labels.serialproxy.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} {{- if .Values.pod.useHostNetwork.serialproxy }} hostNetwork: true dnsPolicy: ClusterFirstWithHostNet {{- end }} initContainers: {{ tuple $envAll "serialproxy" $mounts_nova_serialproxy_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: nova-serialproxy-init {{ tuple $envAll "nova_serialproxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.serialproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_serialproxy_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-proxy-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-proxy-init.sh subPath: nova-console-proxy-init.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: pod-shared mountPath: /tmp/pod-shared containers: - name: nova-serialproxy {{ tuple $envAll "nova_serialproxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.serialproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_serialproxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "serialproxy" "container" "default" "type" "liveness" "probeTemplate" (include "novaSerialproxyLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "serialproxy" "container" "default" "type" "readiness" "probeTemplate" (include "novaSerialproxyReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/nova-console-proxy.sh ports: - name: n-serial containerPort: {{ tuple "compute_serial_proxy" "internal" "serial_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-console-proxy.sh subPath: nova-console-proxy.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true - name: nova-etc mountPath: /etc/nova/logging.conf subPath: logging.conf readOnly: true - name: pod-usr-share-serial mountPath: /usr/share/serial readOnly: true - name: pod-shared mountPath: /tmp/pod-shared {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_serial_proxy.serialproxy.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_serialproxy.volumeMounts }}{{ toYaml $mounts_nova_serialproxy.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: pod-usr-share-serial emptyDir: {} - name: pod-shared emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_serial_proxy.serialproxy.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_serialproxy.volumes }}{{ toYaml $mounts_nova_serialproxy.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/deployment-spiceproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaSpiceproxyLivenessProbeTemplate" }} tcpSocket: port: {{ tuple "compute_spice_proxy" "internal" "spice_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "novaSpiceproxyReadinessProbeTemplate" }} tcpSocket: port: {{ tuple "compute_spice_proxy" "internal" "spice_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if and .Values.manifests.deployment_spiceproxy ( eq .Values.console.console_kind "spice" )}} {{- $envAll := . }} {{- $mounts_nova_spiceproxy := .Values.pod.mounts.nova_spiceproxy.nova_spiceproxy }} {{- $mounts_nova_spiceproxy_init := .Values.pod.mounts.nova_spiceproxy.init_spiceproxy }} {{- $etcSources := .Values.pod.etcSources.nova_spiceproxy }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-spiceproxy" }} {{ tuple $envAll "spiceproxy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: nova-spiceproxy annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "spice-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.spiceproxy }} selector: matchLabels: {{ tuple $envAll "nova" "spice-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "spice-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_spiceproxy" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: {{ tuple "nova_spiceproxy" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_spiceproxy" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "spice-proxy" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.spiceproxy.node_selector_key }}: {{ .Values.labels.spiceproxy.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} hostNetwork: true dnsPolicy: ClusterFirstWithHostNet initContainers: {{ tuple $envAll "spiceproxy" $mounts_nova_spiceproxy_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: nova-spiceproxy-init {{ tuple $envAll "nova_spiceproxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.spiceproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_spiceproxy_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-proxy-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-proxy-init.sh subPath: nova-console-proxy-init.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: pod-shared mountPath: /tmp/pod-shared - name: nova-spiceproxy-init-assets {{ tuple $envAll "nova_spiceproxy_assets" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.spiceproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_spiceproxy_init_assets" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/nova-console-proxy-init-assets.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/nova-console-proxy-init-assets.sh subPath: nova-console-proxy-init-assets.sh readOnly: true - name: pod-usr-share-spice-html5 mountPath: /tmp/usr/share/spice-html5 containers: - name: nova-spiceproxy {{ tuple $envAll "nova_spiceproxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.spiceproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_spiceproxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "compute-spice-proxy" "container" "default" "type" "liveness" "probeTemplate" (include "novaSpiceproxyLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "compute-spice-proxy" "container" "default" "type" "readiness" "probeTemplate" (include "novaSpiceproxyReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/nova-console-proxy.sh ports: - name: n-spice containerPort: {{ tuple "compute_spice_proxy" "internal" "spice_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-console-proxy.sh subPath: nova-console-proxy.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: pod-usr-share-spice-html5 mountPath: /usr/share/spice-html5 readOnly: true - name: pod-shared mountPath: /tmp/pod-shared {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_spice_proxy.spiceproxy.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_spiceproxy.volumeMounts }}{{ toYaml $mounts_nova_spiceproxy.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: pod-usr-share-spice-html5 emptyDir: {} - name: pod-shared emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_spice_proxy.spiceproxy.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_spiceproxy.volumes }}{{ toYaml $mounts_nova_spiceproxy.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: nova/templates/ingress-metadata.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_metadata .Values.network.metadata.ingress.public }} {{- $envAll := . -}} {{- $ingressOpts := dict "envAll" $envAll "backendService" "metadata" "backendServiceType" "compute_metadata" "backendPort" "n-meta" -}} {{- $secretName := $envAll.Values.secrets.tls.compute_metadata.metadata.internal -}} {{- if and .Values.manifests.certificates $secretName }} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute_metadata.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: nova/templates/ingress-novncproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_novncproxy .Values.network.novncproxy.ingress.public (eq .Values.console.console_kind "novnc") }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "novncproxy" "backendServiceType" "compute_novnc_proxy" "backendPort" "n-novnc" -}} {{- $secretName := $envAll.Values.secrets.tls.compute_novnc_proxy.novncproxy.internal -}} {{- if and .Values.manifests.certificates $secretName }} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute_novnc_proxy.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: nova/templates/ingress-osapi.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_osapi .Values.network.osapi.ingress.public }} {{- $envAll := . -}} {{- $ingressOpts := dict "envAll" $envAll "backendService" "osapi" "backendServiceType" "compute" "backendPort" "n-api" -}} {{- $secretName := $envAll.Values.secrets.tls.compute.osapi.internal -}} {{- if and .Values.manifests.certificates $secretName }} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: nova/templates/ingress-serialproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_serialproxy .Values.network.serialproxy.ingress.public (eq .Values.console.console_kind "serial") }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "serialproxy" "backendServiceType" "compute_serial_proxy" "backendPort" "n-serial" -}} {{- $secretName := $envAll.Values.secrets.tls.compute_serial_proxy.serialproxy.internal -}} {{- if and .Values.manifests.certificates $secretName }} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute_serial_proxy.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: nova/templates/ingress-spiceproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_spiceproxy .Values.network.spiceproxy.ingress.public (eq .Values.console.console_kind "spice") }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "spiceproxy" "backendServiceType" "compute_spice_proxy" "backendPort" "n-spice" -}} {{- $secretName := $envAll.Values.secrets.tls.compute_spice_proxy.spiceproxy.internal -}} {{- if and .Values.manifests.certificates $secretName }} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute_spice_proxy.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: nova/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} {{- if and $envAll.Values.manifests.job_bootstrap $envAll.Values.bootstrap.enabled }} {{- $serviceName := "nova" -}} {{- $keystoneUser := $envAll.Values.bootstrap.ks_user -}} {{- $backoffLimit := index . "backoffLimit" | default "1000" -}} {{- $configMapBin := printf "%s-%s" $serviceName "bin" -}} {{- $configMapEtc := printf "%s-%s" $serviceName "etc" -}} {{- $configFile := printf "/etc/%s/%s.conf" $serviceName $serviceName -}} {{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} {{- $serviceAccountName := printf "%s-%s" $serviceName "bootstrap" -}} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ $serviceAccountName | quote }} labels: {{ tuple $envAll "nova" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple "nova_bootstrap" $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 }} spec: backoffLimit: {{ $backoffLimit }} template: metadata: labels: {{ tuple $envAll "nova" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "bootstrap" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if $envAll.Values.bootstrap.wait_for_computes.enabled }} - name: nova-wait-for-computes-init {{ tuple $envAll "nova_wait_for_computes_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "nova_wait_for_computes_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/wait-for-computes-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: bootstrap-sh mountPath: /tmp/wait-for-computes-init.sh subPath: wait-for-computes-init.sh readOnly: true {{- end }} containers: - name: bootstrap image: {{ $envAll.Values.images.tags.bootstrap }} imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "bootstrap" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- with $env := dict "ksUserSecret" ( index $envAll.Values.secrets.identity $keystoneUser ) "useCA" (or .Values.manifests.certificates .Values.tls.identity) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: WAIT_PERCENTAGE value: "{{ .Values.bootstrap.wait_for_computes.wait_percentage }}" - name: REMAINING_WAIT value: "{{ .Values.bootstrap.wait_for_computes.remaining_wait }}" command: - /bin/bash - -c - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: bootstrap-sh mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true - name: etc-service mountPath: {{ dir $configFile | quote }} - name: bootstrap-conf mountPath: {{ $configFile | quote }} subPath: {{ base $configFile | quote }} readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: bootstrap-conf mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append | quote }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append | quote }} readOnly: true {{- end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: bootstrap-sh configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 - name: etc-service emptyDir: {} - name: bootstrap-conf secret: secretName: {{ $configMapEtc | quote }} defaultMode: 0444 {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - '' resources: - nodes verbs: - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io {{- end }} ================================================ FILE: nova/templates/job-cell-setup.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_cell_setup }} {{- $envAll := . }} {{- $serviceAccountName := "nova-cell-setup" }} {{ tuple $envAll "cell_setup" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $etcSources := .Values.pod.etcSources.nova_cell_setup }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} --- apiVersion: batch/v1 kind: Job metadata: name: nova-cell-setup labels: {{ tuple $envAll "nova" "cell-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ tuple "nova_cell_setup" $envAll | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "nova" "cell-setup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "nova-cell-setup" "containerNames" (list "nova-cell-setup-init" "nova-cell-setup" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "cell_setup" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if $envAll.Values.bootstrap.wait_for_computes.enabled }} - name: nova-wait-for-computes-init {{ tuple $envAll "nova_wait_for_computes_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "bootstrap" "container" "nova_wait_for_computes_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/wait-for-computes-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/wait-for-computes-init.sh subPath: wait-for-computes-init.sh readOnly: true {{- end }} - name: nova-cell-setup-init {{ tuple $envAll "nova_cell_setup_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.cell_setup | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova_cell_setup" "container" "nova_cell_setup_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (or .Values.manifests.certificates .Values.tls.identity) }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/cell-setup-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/cell-setup-init.sh subPath: cell-setup-init.sh readOnly: true {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} containers: - name: nova-cell-setup {{ tuple $envAll "nova_cell_setup" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.cell_setup | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova_cell_setup" "container" "nova_cell_setup" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} command: - /tmp/cell-setup.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/cell-setup.sh subPath: cell-setup.sh readOnly: true - name: etcnova mountPath: /etc/nova - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: etcnova emptyDir: {} - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - '' resources: - nodes verbs: - get - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io {{- end }} ================================================ FILE: nova/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $serviceName := "nova" -}} {{- $dbSvc := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" -}} {{- $dbApi := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "api_database" "configDbKey" "connection" -}} {{- $dbCell := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "cell0_database" "configDbKey" "connection" -}} {{- $dbsToDrop := list $dbSvc $dbApi $dbCell }} {{- $dbDropJob := dict "envAll" . "serviceName" $serviceName "dbsToDrop" $dbsToDrop -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: nova/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $serviceName := "nova" -}} {{- $dbSvc := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" -}} {{- $dbApi := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "api_database" "configDbKey" "connection" -}} {{- $dbCell := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "cell0_database" "configDbKey" "connection" -}} {{- $dbsToInit := list $dbSvc $dbApi $dbCell }} {{- $dbInitJob := dict "envAll" . "serviceName" $serviceName "dbsToInit" $dbsToInit -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: nova/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- define "nova.templates._job_db_sync.env_vars" -}} {{- $envAll := index . 0 }} env: - name: TRANSPORT_URL valueFrom: secretKeyRef: name: {{ $envAll.Values.secrets.oslo_messaging.nova }} key: TRANSPORT_URL - name: DB_CONNECTION valueFrom: secretKeyRef: name: {{ $envAll.Values.secrets.oslo_db.nova }} key: DB_CONNECTION - name: DB_CONNECTION_CELL0 valueFrom: secretKeyRef: name: {{ $envAll.Values.secrets.oslo_db_cell0.nova }} key: DB_CONNECTION {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $podEnvVars := include "nova.templates._job_db_sync.env_vars" (tuple .) | toString | fromYaml }} {{- $dbSyncJob := dict "envAll" . "serviceName" "nova" "podVolMounts" .Values.pod.mounts.nova_db_sync.nova_db_sync.volumeMounts "podVols" .Values.pod.mounts.nova_db_sync.nova_db_sync.volumes "podEnvVars" $podEnvVars.env -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: nova/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "nova" -}} {{- $_ := set $imageRepoSyncJob "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: nova/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "nova" "serviceTypes" ( tuple "compute" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.compute.osapi.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: nova/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "nova" "serviceTypes" ( tuple "compute" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.compute.osapi.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: nova/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $serviceUsers := (tuple "nova" "neutron" "placement" "cinder") -}} {{- if .Values.conf.nova.service_user.send_service_user_token }} {{- $serviceUsers = append $serviceUsers "service" -}} {{- end }} {{- if .Values.manifests.statefulset_compute_ironic }} {{- $serviceUsers = append $serviceUsers "ironic" -}} {{- end }} {{- $ksUserJob := dict "envAll" . "serviceName" "nova" "serviceUsers" $serviceUsers -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.compute.osapi.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: nova/templates/job-nova-storage-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_storage_init .Values.conf.ceph.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "nova-storage-init" }} {{ tuple $envAll "storage_init" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "" resources: - secrets verbs: - get - create - update - patch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $serviceAccountName }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} --- apiVersion: batch/v1 kind: Job metadata: annotations: helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-6" name: nova-storage-init labels: {{ tuple $envAll "nova" "storage-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "nova" "storage-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "storage_init" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if $envAll.Values.conf.ceph.enabled }} - name: ceph-keyring-placement {{ tuple $envAll "nova_storage_init" | include "helm-toolkit.snippets.image" | indent 10 }} securityContext: runAsUser: 0 command: - /tmp/ceph-admin-keyring.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcceph mountPath: /etc/ceph - name: nova-bin mountPath: /tmp/ceph-admin-keyring.sh subPath: ceph-admin-keyring.sh readOnly: true {{- if empty .Values.conf.ceph.admin_keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{ end }} {{ end }} containers: - name: nova-storage-init {{ tuple $envAll "nova_storage_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.storage_init | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: STORAGE_BACKEND value: {{ .Values.conf.nova.libvirt.images_type | quote }} {{- if eq .Values.conf.nova.libvirt.images_type "rbd" }} - name: RBD_POOL_NAME value: {{ .Values.conf.nova.libvirt.images_rbd_pool | quote }} - name: RBD_POOL_APP_NAME value: {{ .Values.rbd_pool.app_name | quote }} - name: RBD_POOL_USER value: {{ .Values.conf.nova.libvirt.rbd_user | quote }} - name: RBD_POOL_CRUSH_RULE value: {{ .Values.rbd_pool.crush_rule | quote }} - name: RBD_POOL_REPLICATION value: {{ .Values.rbd_pool.replication | quote }} - name: RBD_POOL_CHUNK_SIZE value: {{ .Values.rbd_pool.chunk_size | quote }} {{ end }} command: - /tmp/storage-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/storage-init.sh subPath: storage-init.sh readOnly: true {{- if eq .Values.conf.nova.libvirt.images_type "rbd" }} - name: etcceph mountPath: /etc/ceph - name: ceph-etc mountPath: /etc/ceph/ceph.conf subPath: ceph.conf readOnly: true {{- if empty $envAll.Values.conf.ceph.admin_keyring }} - name: ceph-keyring mountPath: /tmp/client-keyring subPath: key readOnly: true {{- end }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 {{- if $envAll.Values.conf.ceph.enabled }} - name: etcceph emptyDir: {} - name: ceph-etc configMap: name: {{ .Values.ceph_client.configmap }} defaultMode: 0444 {{- if empty .Values.conf.ceph.admin_keyring }} - name: ceph-keyring secret: secretName: {{ .Values.ceph_client.user_secret_name }} {{- end }} {{- end }} {{- end }} ================================================ FILE: nova/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "nova" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $rmqUserJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $rmqUserJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{- if .Values.pod.tolerations.nova.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: nova/templates/netpol-nova.yaml ================================================ {{/* Copyright 2017-2018 The Openstack-Helm Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "nova" }} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: nova/templates/pdb-metadata.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_metadata }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: nova-api-metadata spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.metadata.min_available }} selector: matchLabels: {{ tuple $envAll "nova" "metadata" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: nova/templates/pdb-osapi.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_osapi }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: nova-api-osapi spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.osapi.min_available }} selector: matchLabels: {{ tuple $envAll "nova" "os-api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: nova/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.nova_tests.nova_tests }} {{- $mounts_tests_init := .Values.pod.mounts.nova_tests.init_container }} {{- $serviceAccountName := print $envAll.deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.deployment_name "-test" }} labels: {{ tuple $envAll "nova" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "nova-test" "containerNames" (list "init" "nova-test" "nova-test-ks-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} restartPolicy: Never {{ tuple "nova_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "nova_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: nova-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: nova-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates}} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.deployment_name}} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: nova-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: nova-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally {{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: rally-db emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/secret-db-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db_api }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "nova" }} {{- $secretName := index $envAll.Values.secrets.oslo_db_api $userClass }} {{- $connection := tuple "oslo_db_api" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db_api" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: nova/templates/secret-db-cell0.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db_cell0 }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "nova" }} {{- $secretName := index $envAll.Values.secrets.oslo_db_cell0 $userClass }} {{- $connection := tuple "oslo_db_cell0" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db_cell0" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: nova/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "nova" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: nova/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendService" "osapi" "backendServiceType" "compute" ) }} {{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendService" "novncproxy" "backendServiceType" "compute_novnc_proxy" ) }} {{- if .Values.manifests.ingress_placement }} {{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendService" "placement" "backendServiceType" "placement" ) }} {{- end }} {{- end }} ================================================ FILE: nova/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $userClass, $val := $envAll.Values.endpoints.identity.auth }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: nova/templates/secret-ks-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ks_etc }} {{- $envAll := . -}} {{/* the endpoints.identity.auth sections with the oslo conf sections they get rendered to */}} {{- $ksUsers := dict "nova" "keystone_authtoken" "neutron" "neutron" "placement" "placement" "cinder" "cinder" -}} {{- if .Values.conf.nova.service_user.send_service_user_token }} {{- $_ := set $ksUsers "service" "service_user" -}} {{- end }} {{- if .Values.manifests.statefulset_compute_ironic }} {{- $_ := set $ksUsers "ironic" "ironic" -}} {{- end }} {{ dict "envAll" $envAll "serviceName" "nova" "serviceUserSections" $ksUsers | include "helm-toolkit.manifests.secret_ks_etc" }} {{- end }} ================================================ FILE: nova/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "nova" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} TRANSPORT_URL: {{ tuple "oslo_messaging" "internal" $userClass "amqp" $envAll | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: nova/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: nova/templates/secret-ssh.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "nova.configmap.ssh" }} {{- $envAll := index . 1 }} {{- with $envAll }} --- apiVersion: v1 kind: Secret metadata: name: nova-ssh annotations: {{ tuple "ssh" "keys" . | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: private-key: {{ .Values.network.ssh.private_key | b64enc }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.network.ssh.public_key "key" "public-key" "format" "Secret" ) | indent 2 }} {{- end }} {{- end }} {{- if .Values.manifests.secret_ssh }} {{- list "nova-ssh" . | include "nova.configmap.ssh" }} {{- end }} ================================================ FILE: nova/templates/service-ingress-metadata.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_metadata .Values.network.metadata.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "compute_metadata" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: nova/templates/service-ingress-novncproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_novncproxy .Values.network.novncproxy.ingress.public (eq .Values.console.console_kind "novnc") }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "compute_novnc_proxy" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: nova/templates/service-ingress-osapi.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_osapi .Values.network.osapi.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "compute" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: nova/templates/service-ingress-serialproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_serialproxy .Values.network.serialproxy.ingress.public (eq .Values.console.console_kind "serial") }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "compute_serial_proxy" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: nova/templates/service-ingress-spiceproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_spiceproxy .Values.network.spiceproxy.ingress.public (eq .Values.console.console_kind "spice") }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "compute_spice_proxy" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: nova/templates/service-metadata.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_metadata }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "compute_metadata" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: n-meta port: {{ .Values.network.metadata.port }} {{ if .Values.network.metadata.node_port.enabled }} nodePort: {{ .Values.network.metadata.node_port.port }} {{ end }} selector: {{ tuple $envAll "nova" "metadata" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.metadata.node_port.enabled }} type: NodePort {{ if .Values.network.metadata.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: nova/templates/service-novncproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_novncproxy ( eq .Values.console.console_kind "novnc" ) }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "compute_novnc_proxy" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: n-novnc port: {{ tuple "compute_novnc_proxy" "internal" "novnc_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.novncproxy.node_port.enabled }} nodePort: {{ .Values.network.novncproxy.node_port.port }} {{ end }} selector: {{ tuple $envAll "nova" "novnc-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.novncproxy.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: nova/templates/service-osapi.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_osapi }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "compute" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: n-api port: {{ tuple "compute" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.osapi.node_port.enabled }} nodePort: {{ .Values.network.osapi.node_port.port }} {{ end }} selector: {{ tuple $envAll "nova" "os-api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.osapi.node_port.enabled }} type: NodePort {{ if .Values.network.osapi.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: nova/templates/service-serialproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_serialproxy ( eq .Values.console.console_kind "serial" ) }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "compute_serial_proxy" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: n-serial port: {{ tuple "compute_serial_proxy" "internal" "serial_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.serialproxy.node_port.enabled }} nodePort: {{ .Values.network.serialproxy.node_port.port }} {{ end }} selector: {{ tuple $envAll "noa" "serial-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.serialproxy.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: nova/templates/service-spiceproxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_spiceproxy (eq .Values.console.console_kind "spice") }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "compute_spice_proxy" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: n-spice port: {{ tuple "compute_spice_proxy" "internal" "spice_proxy" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.spiceproxy.node_port.enabled }} nodePort: {{ .Values.network.spiceproxy.node_port.port }} {{ end }} selector: {{ tuple $envAll "nova" "spice-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.spiceproxy.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: nova/templates/statefulset-compute-ironic.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset_compute_ironic }} {{- $envAll := . }} {{- $mounts_nova_compute_ironic := .Values.pod.mounts.nova_compute_ironic.nova_compute_ironic }} {{- $mounts_nova_compute_ironic_init := .Values.pod.mounts.nova_compute_ironic.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_compute_ironic }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-compute-ironic" }} {{ tuple $envAll "compute_ironic" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nova-compute-ironic annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "compute-ironic" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.compute_ironic }} selector: matchLabels: {{ tuple $envAll "nova" "compute-ironic" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} serviceName: "{{ tuple "baremetal" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }}-compute" template: metadata: labels: {{ tuple $envAll "nova" "compute-ironic" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "nova-compute-default" "containerNames" (list "nova-compute") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_compute_ironic" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_compute_ironic" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "compute-ironic" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.agent.compute_ironic.node_selector_key }}: {{ .Values.labels.agent.compute_ironic.node_selector_value }} hostPID: true dnsPolicy: ClusterFirstWithHostNet initContainers: {{ tuple $envAll "compute_ironic" $mounts_nova_compute_ironic_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: nova-compute-ironic {{ tuple $envAll "nova_compute_ironic" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.compute_ironic | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/nova-compute-ironic.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-compute-ironic.sh subPath: nova-compute-ironic.sh readOnly: true - name: nova-etc mountPath: /etc/nova/nova-compute.conf subPath: nova-compute.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/nova-ironic.conf subPath: nova-ironic.conf readOnly: true - name: nova-etc mountPath: /etc/nova/api-paste.ini subPath: api-paste.ini readOnly: true - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true - name: varlibironic mountPath: /var/lib/ironic {{ if $mounts_nova_compute_ironic.volumeMounts }}{{ toYaml $mounts_nova_compute_ironic.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} - name: varlibironic hostPath: path: /var/lib/ironic {{ if $mounts_nova_compute_ironic.volumes }}{{ toYaml $mounts_nova_compute_ironic.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/statefulset-conductor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaConductorLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - conductor - --liveness-probe {{- end }} {{- define "novaConductorReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - conductor {{- end }} {{- if .Values.manifests.statefulset_conductor }} {{- $envAll := . }} {{- $mounts_nova_conductor := .Values.pod.mounts.nova_conductor.nova_conductor }} {{- $mounts_nova_conductor_init := .Values.pod.mounts.nova_conductor.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_conductor }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-conductor" }} {{ tuple $envAll "conductor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nova-conductor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: nova-conductor replicas: {{ .Values.pod.replicas.conductor }} selector: matchLabels: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} podManagementPolicy: Parallel {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_statefulset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_conductor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-conductor" "containerNames" (list "nova-conductor" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.conductor.node_selector_key }}: {{ .Values.labels.conductor.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "conductor" $mounts_nova_conductor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: nova-conductor {{ tuple $envAll "nova_conductor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.conductor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_conductor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "conductor" "container" "default" "type" "liveness" "probeTemplate" (include "novaConductorLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "conductor" "container" "default" "type" "readiness" "probeTemplate" (include "novaConductorReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" - name: HOSTNAME valueFrom: fieldRef: fieldPath: metadata.name {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} command: - /bin/bash - -c - | set -x {{- if empty .Values.conf.nova.DEFAULT.host }} # When using StatefulSet, use the pod hostname for stable service names cat > /tmp/nova-conductor-host.conf << EOF [DEFAULT] host = ${HOSTNAME} EOF exec nova-conductor --config-file /etc/nova/nova.conf --config-file /tmp/nova-conductor-host.conf --config-dir /etc/nova/nova.conf.d {{- else }} exec /tmp/nova-conductor.sh {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-conductor.sh subPath: nova-conductor.sh readOnly: true - name: nova-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" "certs" (tuple "ca.crt") | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_conductor.volumeMounts }}{{ toYaml $mounts_nova_conductor.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_conductor.volumes }}{{ toYaml $mounts_nova_conductor.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/templates/statefulset-scheduler.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "novaSchedulerLivenessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - scheduler - --liveness-probe {{- end }} {{- define "novaSchedulerReadinessProbeTemplate" }} exec: command: - python - /tmp/health-probe.py - --config-file - /etc/nova/nova.conf - --config-dir - /etc/nova/nova.conf.d - --service-queue-name - scheduler {{- end }} {{- if .Values.manifests.statefulset_scheduler }} {{- $envAll := . }} {{- $mounts_nova_scheduler := .Values.pod.mounts.nova_scheduler.nova_scheduler }} {{- $mounts_nova_scheduler_init := .Values.pod.mounts.nova_scheduler.init_container }} {{- $etcSources := .Values.pod.etcSources.nova_scheduler }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} {{- end }} {{- $serviceAccountName := "nova-scheduler" }} {{ tuple $envAll "scheduler" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nova-scheduler annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: nova-scheduler replicas: {{ .Values.pod.replicas.scheduler }} selector: matchLabels: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} podManagementPolicy: Parallel {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_statefulset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "nova-scheduler" "containerNames" (list "nova-scheduler" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.scheduler.node_selector_key }}: {{ .Values.labels.scheduler.node_selector_value }} {{ if $envAll.Values.pod.tolerations.nova.enabled }} {{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} initContainers: {{ tuple $envAll "scheduler" $mounts_nova_scheduler_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: nova-scheduler {{ tuple $envAll "nova_scheduler" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.scheduler | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "nova" "container" "nova_scheduler" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" $envAll "component" "scheduler" "container" "default" "type" "liveness" "probeTemplate" (include "novaSchedulerLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "scheduler" "container" "default" "type" "readiness" "probeTemplate" (include "novaSchedulerReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: RPC_PROBE_TIMEOUT value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" - name: HOSTNAME valueFrom: fieldRef: fieldPath: metadata.name {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/nova/certs/ca.crt" {{- end }} command: - /bin/bash - -c - | set -xe {{- if empty .Values.conf.nova.DEFAULT.host }} # When using StatefulSet, use the pod hostname for stable service names cat > /tmp/nova-scheduler-host.conf << EOF [DEFAULT] host = ${HOSTNAME} EOF exec nova-scheduler --config-file /etc/nova/nova.conf --config-file /tmp/nova-scheduler-host.conf --config-dir /etc/nova/nova.conf.d {{- else }} exec /tmp/nova-scheduler.sh {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} - name: nova-bin mountPath: /tmp/nova-scheduler.sh subPath: nova-scheduler.sh readOnly: true - name: nova-bin mountPath: /tmp/health-probe.py subPath: health-probe.py readOnly: true - name: nova-etc mountPath: /etc/nova/nova.conf subPath: nova.conf readOnly: true - name: nova-etc-snippets mountPath: /etc/nova/nova.conf.d/ readOnly: true {{- if .Values.conf.nova.DEFAULT.log_config_append }} - name: nova-etc mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: nova-etc mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_scheduler.volumeMounts }}{{ toYaml $mounts_nova_scheduler.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: nova-bin configMap: name: nova-bin defaultMode: 0555 - name: nova-etc secret: secretName: nova-etc defaultMode: 0444 - name: nova-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_scheduler.volumes }}{{ toYaml $mounts_nova_scheduler.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: nova/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for nova. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null labels: agent: compute: node_selector_key: openstack-compute-node node_selector_value: enabled compute_ironic: node_selector_key: openstack-compute-node node_selector_value: enabled api_metadata: node_selector_key: openstack-control-plane node_selector_value: enabled conductor: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled novncproxy: node_selector_key: openstack-control-plane node_selector_value: enabled osapi: node_selector_key: openstack-control-plane node_selector_value: enabled scheduler: node_selector_key: openstack-control-plane node_selector_value: enabled serialproxy: node_selector_key: openstack-control-plane node_selector_value: enabled spiceproxy: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: pull_policy: IfNotPresent tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble nova_archive_deleted_rows: quay.io/airshipit/nova:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble nova_api: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_cell_setup: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_cell_setup_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble nova_compute: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_compute_ironic: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_compute_ssh: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_conductor: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_db_sync: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_novncproxy: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_novncproxy_assets: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_scheduler: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_storage_init: quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy # NOTE(portdirect): we simply use the ceph config helper here, # as it has both oscli and jq. nova_service_cleaner: quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy nova_serialproxy: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_spiceproxy: quay.io/airshipit/nova:2025.1-ubuntu_noble nova_spiceproxy_assets: quay.io/airshipit/nova:2025.1-ubuntu_noble test: docker.io/xrally/xrally-openstack:2.0.0 image_repo_sync: docker.io/docker:17.07.0 nova_wait_for_computes_init: quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy local_registry: active: false exclude: - dep_check - image_repo_sync jobs: # NOTE(portdirect): When using cells new nodes will be added to the cell on the hour by default. # TODO(portdirect): Add a post-start action to nova compute pods that registers themselves. cell_setup: cron: "0 */1 * * *" starting_deadline: 600 history: success: 3 failed: 1 extended_wait: enabled: false iteration: 3 duration: 5 extra_command: null service_cleaner: cron: "0 */1 * * *" starting_deadline: 600 history: success: 3 failed: 1 sleep_time: 60 extra_command: null archive_deleted_rows: cron: "0 */1 * * *" starting_deadline: 600 history: success: 3 failed: 1 bootstrap: enabled: true ks_user: admin script: null structured: flavors: enabled: true options: m1_tiny: name: "m1.tiny" ram: 512 disk: 1 vcpus: 1 m1_small: name: "m1.small" ram: 2048 disk: 20 vcpus: 1 m1_medium: name: "m1.medium" ram: 4096 disk: 40 vcpus: 2 m1_large: name: "m1.large" ram: 8192 disk: 80 vcpus: 4 m1_xlarge: name: "m1.xlarge" ram: 16384 disk: 160 vcpus: 8 wait_for_computes: enabled: false # Wait percentage is the minimum percentage of compute hypervisors which # must be available before the remainder of the bootstrap script can be run. wait_percentage: 70 # Once the wait_percentage above is achieved, the remaining_wait is the # amount of time in seconds to wait before executing the remainder of the # boostrap script. remaining_wait: 300 scripts: init_script: | # This runs in a bootstrap init container. It counts the number of compute nodes. COMPUTE_NODES=$(kubectl get nodes -o custom-columns=NAME:.metadata.name -l openstack-compute-node=enabled --no-headers | sort) /bin/echo $COMPUTE_NODES > /tmp/compute_nodes.txt wait_script: | # This script runs in the main bootstrap container just before the # bootstrap.script is called. COMPUTE_HOSTS=`cat /tmp/compute_nodes.txt | wc -w` if [[ $COMPUTE_HOSTS == 0 ]]; then echo "There are no compute hosts found!" exit 1 fi # Wait for all hypervisors to come up before moving on with the deployment HYPERVISOR_WAIT=true WAIT_AFTER_READY=0 SLEEP=5 while [[ $HYPERVISOR_WAIT == true ]]; do date '+%Y-%m-%d %H:%M:%S.%3N' # Its possible that openstack command may fail due to not being able to # reach the compute service set +e HYPERVISORS=$(openstack hypervisor list -f value -c 'Hypervisor Hostname' | wc -w) set -e PERCENT_READY=$(( $HYPERVISORS * 100 / $COMPUTE_HOSTS )) if [[ $PERCENT_READY -ge $WAIT_PERCENTAGE ]]; then echo "Hypervisor ready percentage is $PERCENT_READY" if [[ $PERCENT_READY == 100 ]]; then HYPERVISOR_WAIT=false echo "All hypervisors are ready." elif [[ $WAIT_AFTER_READY -ge $REMAINING_WAIT ]]; then HYPERVISOR_WAIT=false echo "Waited the configured time -- $HYPERVISORS out of $COMPUTE_HOSTS hypervisor(s) ready -- proceeding with the bootstrap." else sleep $SLEEP WAIT_AFTER_READY=$(( $WAIT_AFTER_READY + $SLEEP )) fi else echo "Waiting $SLEEP seconds for enough hypervisors to be discovered..." sleep $SLEEP fi done network: # provide what type of network wiring will be used # possible options: openvswitch, linuxbridge, sriov backend: - openvswitch osapi: port: 8774 ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30774 metadata: port: 8775 ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30775 novncproxy: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30680 serialproxy: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30683 spiceproxy: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30682 ssh: enabled: false port: 8022 from_subnet: 0.0.0.0/0 key_types: - rsa - dsa - ecdsa - ed25519 private_key: 'null' public_key: 'null' dependencies: dynamic: common: local_image_registry: jobs: - nova-image-repo-sync services: - endpoint: node service: local_image_registry targeted: ovn: compute: pod: - requireSameNode: true labels: application: ovn component: ovn-controller openvswitch: compute: pod: - requireSameNode: true labels: application: neutron component: neutron-ovs-agent linuxbridge: compute: pod: - requireSameNode: true labels: application: neutron component: neutron-lb-agent sriov: compute: pod: - requireSameNode: true labels: application: neutron component: neutron-sriov-agent static: api: jobs: - nova-db-sync - nova-ks-user - nova-ks-endpoints - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity api_metadata: jobs: - nova-db-sync - nova-ks-user - nova-ks-endpoints - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity bootstrap: jobs: - nova-cell-setup services: - endpoint: internal service: identity - endpoint: internal service: compute cell_setup: jobs: - nova-db-sync - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: compute pod: - requireSameNode: false labels: application: nova component: compute service_cleaner: jobs: - nova-db-sync - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: compute compute: pod: - requireSameNode: true labels: application: libvirt component: libvirt jobs: - nova-db-sync - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: image - endpoint: internal service: compute - endpoint: internal service: network - endpoint: internal service: compute_metadata compute_ironic: jobs: - nova-db-sync - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: image - endpoint: internal service: compute - endpoint: internal service: network - endpoint: internal service: baremetal conductor: jobs: - nova-db-sync - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: compute db_drop: services: - endpoint: internal service: oslo_db archive_deleted_rows: jobs: - nova-db-init - nova-db-sync db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - nova-db-init services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - nova-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - service: oslo_messaging endpoint: internal novncproxy: jobs: - nova-db-sync services: - endpoint: internal service: oslo_db serialproxy: jobs: - nova-db-sync services: - endpoint: internal service: oslo_db spiceproxy: jobs: - nova-db-sync services: - endpoint: internal service: oslo_db scheduler: jobs: - nova-db-sync - nova-rabbit-init services: - endpoint: internal service: oslo_messaging - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: compute tests: services: - endpoint: internal service: image - endpoint: internal service: compute - endpoint: internal service: network - endpoint: internal service: compute_metadata image_repo_sync: services: - endpoint: internal service: local_image_registry console: # serial | spice | novnc | none console_kind: novnc serial: compute: # IF blank, search default routing interface server_proxyclient_interface: null # or set network cidr server_proxyclient_network_cidr: 0/0 proxy: # IF blank, search default routing interface server_proxyclient_interface: null # or set network cidr server_proxyclient_network_cidr: 0/0 spice: compute: # IF blank, search default routing interface server_proxyclient_interface: null # or set network cidr server_proxyclient_network_cidr: 0/0 proxy: # IF blank, search default routing interface server_proxyclient_interface: null # or set network cidr server_proxyclient_network_cidr: 0/0 novnc: compute: # IF blank, search default routing interface vncserver_proxyclient_interface: null # or set network cidr vncserver_proxyclient_network_cidr: 0/0 vncproxy: # IF blank, search default routing interface vncserver_proxyclient_interface: null # or set network cidr vncserver_proxyclient_network_cidr: 0/0 address_search_enabled: true ceph_client: configmap: ceph-etc user_secret_name: pvc-ceph-client-key rbd_pool: app_name: nova-vms replication: 3 crush_rule: replicated_rule chunk_size: 8 conf: security: | # # Disable access to the entire file system except for the directories that # are explicitly allowed later. # # This currently breaks the configurations that come with some web application # Debian packages. # # # AllowOverride None # Require all denied # # Changing the following options will not really affect the security of the # server, but might make attacks slightly more difficult in some cases. # # ServerTokens # This directive configures what you return as the Server HTTP response # Header. The default is 'Full' which sends information about the OS-Type # and compiled in modules. # Set to one of: Full | OS | Minimal | Minor | Major | Prod # where Full conveys the most information, and Prod the least. ServerTokens Prod # # Optionally add a line containing the server version and virtual host # name to server-generated pages (internal error documents, FTP directory # listings, mod_status and mod_info output etc., but not CGI generated # documents or custom error documents). # Set to "EMail" to also include a mailto: link to the ServerAdmin. # Set to one of: On | Off | EMail ServerSignature Off # # Allow TRACE method # # Set to "extended" to also reflect the request body (only for testing and # diagnostic purposes). # # Set to one of: On | Off | extended TraceEnable Off # # Forbid access to version control directories # # If you use version control systems in your document root, you should # probably deny access to their directories. For example, for subversion: # # # Require all denied # # # Setting this header will prevent MSIE from interpreting files as something # else than declared by the content type in the HTTP headers. # Requires mod_headers to be enabled. # #Header set X-Content-Type-Options: "nosniff" # # Setting this header will prevent other sites from embedding pages from this # site as frames. This defends against clickjacking attacks. # Requires mod_headers to be enabled. # #Header set X-Frame-Options: "sameorigin" software: apache2: binary: apache2 start_parameters: -DFOREGROUND conf_dir: /etc/apache2/conf-enabled site_dir: /etc/apache2/sites-enable mods_dir: /etc/apache2/mods-available a2enmod: null a2dismod: null ceph: enabled: true admin_keyring: null cinder: user: "cinder" keyring: null secret_uuid: 457eb676-33da-42ec-9a8c-9293d545c337 rally_tests: run_tempest: false clean_up: | FLAVORS=$(openstack flavor list -f value --all | awk '$2 ~ /^s_rally_/ { print $1 }') if [ -n "$FLAVORS" ]; then echo $FLAVORS | xargs openstack flavor delete fi SERVERS=$(openstack server list -f value --all | awk '$2 ~ /^s_rally_/ { print $1 }') if [ -n "$SERVERS" ]; then echo $SERVERS | xargs openstack server delete fi IMAGES=$(openstack image list -f value | awk '$2 ~ /^c_rally_/ { print $1 }') if [ -n "$IMAGES" ]; then echo $IMAGES | xargs openstack image delete fi tests: NovaAggregates.create_and_get_aggregate_details: - args: availability_zone: nova runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaAggregates.create_and_update_aggregate: - args: availability_zone: nova runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaAggregates.list_aggregates: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaAvailabilityZones.list_availability_zones: - args: detailed: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaFlavors.create_and_delete_flavor: - args: disk: 1 ram: 500 vcpus: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaFlavors.create_and_list_flavor_access: - args: disk: 1 ram: 500 vcpus: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaFlavors.create_flavor: - args: disk: 1 ram: 500 vcpus: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaFlavors.create_flavor_and_add_tenant_access: - args: disk: 1 ram: 500 vcpus: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaFlavors.create_flavor_and_set_keys: - args: disk: 1 extra_specs: 'quota:disk_read_bytes_sec': 10240 ram: 500 vcpus: 1 runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaFlavors.list_flavors: - args: detailed: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaHypervisors.list_and_get_hypervisors: - args: detailed: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaHypervisors.list_and_get_uptime_hypervisors: - args: detailed: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaHypervisors.list_and_search_hypervisors: - args: detailed: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaHypervisors.list_hypervisors: - args: detailed: true runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaHypervisors.statistics_hypervisors: - args: {} runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaKeypair.create_and_delete_keypair: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaKeypair.create_and_list_keypairs: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaServerGroups.create_and_list_server_groups: - args: all_projects: false kwargs: policies: - affinity runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 NovaServices.list_services: - runner: concurrency: 1 times: 1 type: constant sla: failure_rate: max: 0 paste: composite:metadata: use: egg:Paste#urlmap /: meta pipeline:meta: pipeline: cors metaapp app:metaapp: paste.app_factory: nova.api.metadata.handler:MetadataRequestHandler.factory composite:osapi_compute: use: call:nova.api.openstack.urlmap:urlmap_factory /: oscomputeversions /v2: openstack_compute_api_v21_legacy_v2_compatible /v2.1: openstack_compute_api_v21 composite:openstack_compute_api_v21: use: call:nova.api.auth:pipeline_factory_v21 noauth2: cors http_proxy_to_wsgi compute_req_id faultwrap sizelimit noauth2 osapi_compute_app_v21 keystone: cors http_proxy_to_wsgi compute_req_id faultwrap sizelimit authtoken audit keystonecontext osapi_compute_app_v21 composite:openstack_compute_api_v21_legacy_v2_compatible: use: call:nova.api.auth:pipeline_factory_v21 noauth2: cors http_proxy_to_wsgi compute_req_id faultwrap sizelimit noauth2 legacy_v2_compatible osapi_compute_app_v21 keystone: cors http_proxy_to_wsgi compute_req_id faultwrap sizelimit authtoken audit keystonecontext legacy_v2_compatible osapi_compute_app_v21 filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:compute_req_id: paste.filter_factory: nova.api.compute_req_id:ComputeReqIdMiddleware.factory filter:faultwrap: paste.filter_factory: nova.api.openstack:FaultWrapper.factory filter:noauth2: paste.filter_factory: nova.api.openstack.auth:NoAuthMiddleware.factory filter:sizelimit: paste.filter_factory: oslo_middleware:RequestBodySizeLimiter.factory filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory filter:legacy_v2_compatible: paste.filter_factory: nova.api.openstack:LegacyV2CompatibleWrapper.factory app:osapi_compute_app_v21: paste.app_factory: nova.api.openstack.compute:APIRouterV21.factory pipeline:oscomputeversions: pipeline: faultwrap http_proxy_to_wsgi oscomputeversionapp app:oscomputeversionapp: paste.app_factory: nova.api.openstack.compute.versions:Versions.factory filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: nova filter:keystonecontext: paste.filter_factory: nova.api.auth:NovaKeystoneContext.factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:audit: paste.filter_factory: keystonemiddleware.audit:filter_factory audit_map_file: /etc/nova/api_audit_map.conf policy: {} nova_sudoers: | # This sudoers file supports rootwrap for both Kolla and LOCI Images. Defaults !requiretty Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin:/var/lib/kolla/venv/bin" nova ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/nova-rootwrap /etc/nova/rootwrap.conf *, /var/lib/openstack/bin/nova-rootwrap /etc/nova/rootwrap.conf * api_audit_map: DEFAULT: target_endpoint_type: None custom_actions: enable: enable disable: disable delete: delete startup: start/startup shutdown: stop/shutdown reboot: start/reboot os-migrations/get: read os-server-password/post: update path_keywords: add: None action: None enable: None disable: None configure-project: None defaults: None delete: None detail: None diagnostics: None entries: entry extensions: alias flavors: flavor images: image ips: label limits: None metadata: key os-agents: os-agent os-aggregates: os-aggregate os-availability-zone: None os-certificates: None os-cloudpipe: None os-fixed-ips: ip os-extra_specs: key os-flavor-access: None os-floating-ip-dns: domain os-floating-ips-bulk: host os-floating-ip-pools: None os-floating-ips: floating-ip os-hosts: host os-hypervisors: hypervisor os-instance-actions: instance-action os-keypairs: keypair os-migrations: None os-networks: network os-quota-sets: tenant os-security-groups: security_group os-security-group-rules: rule os-server-password: None os-services: None os-simple-tenant-usage: tenant os-virtual-interfaces: None os-volume_attachments: attachment os-volumes_boot: None os-volumes: volume os-volume-types: volume-type os-snapshots: snapshot reboot: None servers: server shutdown: None startup: None statistics: None service_endpoints: compute: service/compute rootwrap: | # Configuration for nova-rootwrap # This file should be owned by (and only-writeable by) the root user [DEFAULT] # List of directories to load filter definitions from (separated by ','). # These directories MUST all be only writeable by root ! filters_path=/etc/nova/rootwrap.d,/usr/share/nova/rootwrap # List of directories to search executables in, in case filters do not # explicitely specify a full path (separated by ',') # If not specified, defaults to system PATH environment variable. # These directories MUST all be only writeable by root ! exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin,/var/lib/openstack/bin,/var/lib/kolla/venv/bin # Enable logging to syslog # Default value is False use_syslog=False # Which syslog facility to use. # Valid values include auth, authpriv, syslog, local0, local1... # Default value is 'syslog' syslog_log_facility=syslog # Which messages to log. # INFO means log all usage # ERROR means only log unsuccessful attempts syslog_log_level=ERROR rootwrap_filters: api_metadata: pods: - metadata content: | # nova-rootwrap command filters for api-metadata nodes # This is needed on nova-api hosts running with "metadata" in enabled_apis # or when running nova-api-metadata # This file should be owned by (and only-writeable by) the root user [Filters] # nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ... iptables-save: CommandFilter, iptables-save, root ip6tables-save: CommandFilter, ip6tables-save, root # nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,) iptables-restore: CommandFilter, iptables-restore, root ip6tables-restore: CommandFilter, ip6tables-restore, root compute: pods: - compute content: | # nova-rootwrap command filters for compute nodes # This file should be owned by (and only-writeable by) the root user [Filters] # nova/virt/disk/mount/api.py: 'kpartx', '-a', device # nova/virt/disk/mount/api.py: 'kpartx', '-d', device kpartx: CommandFilter, kpartx, root # nova/virt/xenapi/vm_utils.py: tune2fs, -O ^has_journal, part_path # nova/virt/xenapi/vm_utils.py: tune2fs, -j, partition_path tune2fs: CommandFilter, tune2fs, root # nova/virt/disk/mount/api.py: 'mount', mapped_device # nova/virt/disk/api.py: 'mount', '-o', 'bind', src, target # nova/virt/xenapi/vm_utils.py: 'mount', '-t', 'ext2,ext3,ext4,reiserfs'.. # nova/virt/configdrive.py: 'mount', device, mountdir # nova/virt/libvirt/volume.py: 'mount', '-t', 'sofs' ... mount: CommandFilter, mount, root # nova/virt/disk/mount/api.py: 'umount', mapped_device # nova/virt/disk/api.py: 'umount' target # nova/virt/xenapi/vm_utils.py: 'umount', dev_path # nova/virt/configdrive.py: 'umount', mountdir umount: CommandFilter, umount, root # nova/virt/disk/mount/nbd.py: 'qemu-nbd', '-c', device, image # nova/virt/disk/mount/nbd.py: 'qemu-nbd', '-d', device qemu-nbd: CommandFilter, qemu-nbd, root # nova/virt/disk/mount/loop.py: 'losetup', '--find', '--show', image # nova/virt/disk/mount/loop.py: 'losetup', '--detach', device losetup: CommandFilter, losetup, root # nova/virt/disk/vfs/localfs.py: 'blkid', '-o', 'value', '-s', 'TYPE', device blkid: CommandFilter, blkid, root # nova/virt/libvirt/utils.py: 'blockdev', '--getsize64', path # nova/virt/disk/mount/nbd.py: 'blockdev', '--flushbufs', device blockdev: RegExpFilter, blockdev, root, blockdev, (--getsize64|--flushbufs), /dev/.* # nova/virt/disk/vfs/localfs.py: 'tee', canonpath tee: CommandFilter, tee, root # nova/virt/disk/vfs/localfs.py: 'mkdir', canonpath mkdir: CommandFilter, mkdir, root # nova/virt/disk/vfs/localfs.py: 'chown' # nova/virt/libvirt/connection.py: 'chown', os.getuid( console_log # nova/virt/libvirt/connection.py: 'chown', os.getuid( console_log # nova/virt/libvirt/connection.py: 'chown', 'root', basepath('disk') chown: CommandFilter, chown, root # nova/virt/disk/vfs/localfs.py: 'chmod' chmod: CommandFilter, chmod, root # nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap' # nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up' # nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev # nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i.. # nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'.. # nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',.. # nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',.. # nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev) # nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1] # nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge # nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', .. # nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',.. # nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ... # nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,.. # nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up' # nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up' # nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, .. # nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, .. # nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up' # nova/network/linux_net.py: 'ip', 'route', 'add', .. # nova/network/linux_net.py: 'ip', 'route', 'del', . # nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev ip: CommandFilter, ip, root # nova/virt/libvirt/vif.py: 'tunctl', '-b', '-t', dev # nova/network/linux_net.py: 'tunctl', '-b', '-t', dev tunctl: CommandFilter, tunctl, root # nova/virt/libvirt/vif.py: 'ovs-vsctl', ... # nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ... # nova/network/linux_net.py: 'ovs-vsctl', .... ovs-vsctl: CommandFilter, ovs-vsctl, root # nova/virt/libvirt/vif.py: 'vrouter-port-control', ... vrouter-port-control: CommandFilter, vrouter-port-control, root # nova/virt/libvirt/vif.py: 'ebrctl', ... ebrctl: CommandFilter, ebrctl, root # nova/virt/libvirt/vif.py: 'mm-ctl', ... mm-ctl: CommandFilter, mm-ctl, root # nova/network/linux_net.py: 'ovs-ofctl', .... ovs-ofctl: CommandFilter, ovs-ofctl, root # nova/virt/libvirt/connection.py: 'dd', if=%s % virsh_output, ... dd: CommandFilter, dd, root # nova/virt/xenapi/volume_utils.py: 'iscsiadm', '-m', ... iscsiadm: CommandFilter, iscsiadm, root # nova/virt/libvirt/volume/aoe.py: 'aoe-revalidate', aoedev # nova/virt/libvirt/volume/aoe.py: 'aoe-discover' aoe-revalidate: CommandFilter, aoe-revalidate, root aoe-discover: CommandFilter, aoe-discover, root # nova/virt/xenapi/vm_utils.py: parted, --script, ... # nova/virt/xenapi/vm_utils.py: 'parted', '--script', dev_path, ..*. parted: CommandFilter, parted, root # nova/virt/xenapi/vm_utils.py: 'pygrub', '-qn', dev_path pygrub: CommandFilter, pygrub, root # nova/virt/xenapi/vm_utils.py: fdisk %(dev_path)s fdisk: CommandFilter, fdisk, root # nova/virt/xenapi/vm_utils.py: e2fsck, -f, -p, partition_path # nova/virt/disk/api.py: e2fsck, -f, -p, image e2fsck: CommandFilter, e2fsck, root # nova/virt/xenapi/vm_utils.py: resize2fs, partition_path # nova/virt/disk/api.py: resize2fs, image resize2fs: CommandFilter, resize2fs, root # nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ... iptables-save: CommandFilter, iptables-save, root ip6tables-save: CommandFilter, ip6tables-save, root # nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,) iptables-restore: CommandFilter, iptables-restore, root ip6tables-restore: CommandFilter, ip6tables-restore, root # nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ... # nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],.. arping: CommandFilter, arping, root # nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address dhcp_release: CommandFilter, dhcp_release, root # nova/network/linux_net.py: 'kill', '-9', pid # nova/network/linux_net.py: 'kill', '-HUP', pid kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP # nova/network/linux_net.py: 'kill', pid kill_radvd: KillFilter, root, /usr/sbin/radvd # nova/network/linux_net.py: dnsmasq call dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq # nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'.. radvd: CommandFilter, radvd, root # nova/network/linux_net.py: 'brctl', 'addbr', bridge # nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0 # nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off' # nova/network/linux_net.py: 'brctl', 'addif', bridge, interface brctl: CommandFilter, brctl, root # nova/virt/libvirt/utils.py: 'mkswap' # nova/virt/xenapi/vm_utils.py: 'mkswap' mkswap: CommandFilter, mkswap, root # nova/virt/libvirt/utils.py: 'nova-idmapshift' nova-idmapshift: CommandFilter, nova-idmapshift, root # nova/virt/xenapi/vm_utils.py: 'mkfs' # nova/utils.py: 'mkfs', fs, path, label mkfs: CommandFilter, mkfs, root # nova/virt/libvirt/utils.py: 'qemu-img' qemu-img: CommandFilter, qemu-img, root # nova/virt/disk/vfs/localfs.py: 'readlink', '-e' readlink: CommandFilter, readlink, root # nova/virt/disk/api.py: mkfs.ext3: CommandFilter, mkfs.ext3, root mkfs.ext4: CommandFilter, mkfs.ext4, root mkfs.ntfs: CommandFilter, mkfs.ntfs, root # nova/virt/libvirt/connection.py: lvremove: CommandFilter, lvremove, root # nova/virt/libvirt/utils.py: lvcreate: CommandFilter, lvcreate, root # nova/virt/libvirt/utils.py: lvs: CommandFilter, lvs, root # nova/virt/libvirt/utils.py: vgs: CommandFilter, vgs, root # nova/utils.py:read_file_as_root: 'cat', file_path # (called from nova/virt/disk/vfs/localfs.py:VFSLocalFS.read_file) read_passwd: RegExpFilter, cat, root, cat, (/var|/usr)?/tmp/openstack-vfs-localfs[^/]+/etc/passwd read_shadow: RegExpFilter, cat, root, cat, (/var|/usr)?/tmp/openstack-vfs-localfs[^/]+/etc/shadow # os-brick needed commands read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi multipath: CommandFilter, multipath, root # multipathd show status multipathd: CommandFilter, multipathd, root systool: CommandFilter, systool, root vgc-cluster: CommandFilter, vgc-cluster, root # os_brick/initiator/connector.py drv_cfg: CommandFilter, /opt/emc/scaleio/sdc/bin/drv_cfg, root, /opt/emc/scaleio/sdc/bin/drv_cfg, --query_guid # TODO(smcginnis) Temporary fix. # Need to pull in os-brick os-brick.filters file instead and clean # out stale brick values from this file. scsi_id: CommandFilter, /lib/udev/scsi_id, root # os_brick.privileged.default oslo.privsep context # This line ties the superuser privs with the config files, context name, # and (implicitly) the actual python code invoked. privsep-rootwrap: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, os_brick.privileged.default, --privsep_sock_path, /tmp/.* # nova/storage/linuxscsi.py: sg_scan device sg_scan: CommandFilter, sg_scan, root # nova/volume/encryptors/cryptsetup.py: # nova/volume/encryptors/luks.py: ln: RegExpFilter, ln, root, ln, --symbolic, --force, /dev/mapper/crypt-.+, .+ # nova/volume/encryptors.py: # nova/virt/libvirt/dmcrypt.py: cryptsetup: CommandFilter, cryptsetup, root # nova/virt/xenapi/vm_utils.py: xenstore-read: CommandFilter, xenstore-read, root # nova/virt/libvirt/utils.py: rbd: CommandFilter, rbd, root # nova/virt/libvirt/utils.py: 'shred', '-n3', '-s%d' % volume_size, path shred: CommandFilter, shred, root # nova/virt/libvirt/volume.py: 'cp', '/dev/stdin', delete_control.. cp: CommandFilter, cp, root # nova/virt/xenapi/vm_utils.py: sync: CommandFilter, sync, root # nova/virt/libvirt/imagebackend.py: ploop: RegExpFilter, ploop, root, ploop, restore-descriptor, .* prl_disk_tool: RegExpFilter, prl_disk_tool, root, prl_disk_tool, resize, --size, .*M$, --resize_partition, --hdd, .* # nova/virt/libvirt/utils.py: 'xend', 'status' xend: CommandFilter, xend, root # nova/virt/libvirt/utils.py: touch: CommandFilter, touch, root # nova/virt/libvirt/volume/vzstorage.py pstorage-mount: CommandFilter, pstorage-mount, root network: pods: - compute content: | # nova-rootwrap command filters for network nodes # This file should be owned by (and only-writeable by) the root user [Filters] # nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap' # nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up' # nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev # nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i.. # nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'.. # nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',.. # nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',.. # nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev) # nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1] # nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge # nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', .. # nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',.. # nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ... # nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,.. # nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up' # nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up' # nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, .. # nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, .. # nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up' # nova/network/linux_net.py: 'ip', 'route', 'add', .. # nova/network/linux_net.py: 'ip', 'route', 'del', . # nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev ip: CommandFilter, ip, root # nova/virt/libvirt/vif.py: 'ovs-vsctl', ... # nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ... # nova/network/linux_net.py: 'ovs-vsctl', .... ovs-vsctl: CommandFilter, ovs-vsctl, root # nova/network/linux_net.py: 'ovs-ofctl', .... ovs-ofctl: CommandFilter, ovs-ofctl, root # nova/virt/libvirt/vif.py: 'ivs-ctl', ... # nova/virt/libvirt/vif.py: 'ivs-ctl', 'del-port', ... # nova/network/linux_net.py: 'ivs-ctl', .... ivs-ctl: CommandFilter, ivs-ctl, root # nova/virt/libvirt/vif.py: 'ifc_ctl', ... ifc_ctl: CommandFilter, /opt/pg/bin/ifc_ctl, root # nova/network/linux_net.py: 'ebtables', '-D' ... # nova/network/linux_net.py: 'ebtables', '-I' ... ebtables: CommandFilter, ebtables, root ebtables_usr: CommandFilter, ebtables, root # nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ... iptables-save: CommandFilter, iptables-save, root ip6tables-save: CommandFilter, ip6tables-save, root # nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,) iptables-restore: CommandFilter, iptables-restore, root ip6tables-restore: CommandFilter, ip6tables-restore, root # nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ... # nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],.. arping: CommandFilter, arping, root # nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address dhcp_release: CommandFilter, dhcp_release, root # nova/network/linux_net.py: 'kill', '-9', pid # nova/network/linux_net.py: 'kill', '-HUP', pid kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP # nova/network/linux_net.py: 'kill', pid kill_radvd: KillFilter, root, /usr/sbin/radvd # nova/network/linux_net.py: dnsmasq call dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq # nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'.. radvd: CommandFilter, radvd, root # nova/network/linux_net.py: 'brctl', 'addbr', bridge # nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0 # nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off' # nova/network/linux_net.py: 'brctl', 'addif', bridge, interface brctl: CommandFilter, brctl, root # nova/network/linux_net.py: 'sysctl', .... sysctl: CommandFilter, sysctl, root # nova/network/linux_net.py: 'conntrack' conntrack: CommandFilter, conntrack, root # nova/network/linux_net.py: 'fp-vdev' fp-vdev: CommandFilter, fp-vdev, root nova_ironic: DEFAULT: scheduler_host_manager: ironic_host_manager compute_driver: ironic.IronicDriver ram_allocation_ratio: 1.0 cpu_allocation_ratio: 1.0 reserved_host_memory_mb: 0 libvirt: address_search_enabled: true # When "address_search_enabled", get the IP address to be used as the target for live migration # traffic using interface name. # If this option is set to None, the hostname of the migration target compute node will be used. live_migration_interface: null # or set cidr live_migration_network_cidr: 0/0 hypervisor: address_search_enabled: true # my_ip can be set automatically through this interface name. host_interface: null # If host_interface is null there is a fallback mechanism to search # for interface with routing using host network cidr. host_network_cidr: 0/0 # This list is the keys to exclude from the config file ingested by nova-compute nova_compute_redactions: - database - api_database - cell0_database nova: DEFAULT: log_config_append: /etc/nova/logging.conf default_ephemeral_format: ext4 ram_allocation_ratio: 1.0 disk_allocation_ratio: 1.0 cpu_allocation_ratio: 3.0 state_path: /var/lib/nova osapi_compute_listen: 0.0.0.0 # NOTE(portdirect): the bind port should not be defined, and is manipulated # via the endpoints section. osapi_compute_listen_port: null osapi_compute_workers: 1 metadata_workers: 1 compute_driver: libvirt.LibvirtDriver my_ip: 0.0.0.0 instance_usage_audit: True instance_usage_audit_period: hour resume_guests_state_on_host_boot: True vnc: auth_schemes: none novncproxy_host: 0.0.0.0 server_listen: 0.0.0.0 # This would be set by each compute nodes's ip # server_proxyclient_address: 127.0.0.1 spice: html5proxy_host: 0.0.0.0 server_listen: 0.0.0.0 # This would be set by each compute nodes's ip # server_proxyclient_address: 127.0.0.1 serial_console: serialproxy_host: 0.0.0.0 # This would be set by each compute nodes's ip # proxyclient_address: 127.0.0.1 conductor: workers: 1 scheduler: max_attempts: 10 discover_hosts_in_cells_interval: -1 workers: 1 oslo_policy: policy_file: /etc/nova/policy.yaml oslo_concurrency: lock_path: /var/lock oslo_middleware: enable_proxy_headers_parsing: true glance: num_retries: 3 ironic: api_endpoint: null auth_url: null neutron: metadata_proxy_shared_secret: "password" service_metadata_proxy: True auth_type: password auth_version: v3 cinder: auth_type: password catalog_info: volumev3::internalURL database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" api_database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" cell0_database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: service_token_roles: service service_token_roles_required: true auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT service_type: compute notifications: notify_on_state_change: vm_and_task_state service_user: auth_type: password send_service_user_token: true libvirt: connection_uri: "qemu+unix:///system?socket=/run/libvirt/libvirt-sock" images_type: qcow2 images_rbd_pool: vms images_rbd_ceph_conf: /etc/ceph/ceph.conf rbd_user: cinder rbd_secret_uuid: 457eb676-33da-42ec-9a8c-9293d545c337 disk_cachemodes: "network=writeback" hw_disk_discard: unmap upgrade_levels: compute: auto cache: enabled: true backend: dogpile.cache.memcached wsgi: api_paste_config: /etc/nova/api-paste.ini oslo_messaging_notifications: driver: messagingv2 oslo_messaging_rabbit: rabbit_ha_queues: true placement: auth_type: password auth_version: v3 logging: loggers: keys: - root - nova - os.brick handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_nova: level: INFO handlers: - stdout qualname: nova logger_os.brick: level: INFO handlers: - stdout qualname: os.brick logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" rabbitmq: # NOTE(rk760n): adding rmq policy to mirror messages from notification queues and set expiration time for the ones policies: - vhost: "nova" name: "ha_ttl_nova" definition: # mirror messges to other nodes in rmq cluster ha-mode: "all" ha-sync-mode: "automatic" # 70s message-ttl: 70000 priority: 0 apply-to: all pattern: '^(?!(amq\.|reply_)).*' enable_iscsi: false archive_deleted_rows: purge_deleted_rows: false until_completion: true all_cells: false max_rows: enabled: False rows: 1000 before: enabled: false date: 'nil' nova_api_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "nova-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/nova-api-wsgi stats: 0.0.0.0:1717 stats-http: true nova_metadata_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "nova-metadata:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/nova-metadata-wsgi stats: 0.0.0.0:1717 stats-http: true # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: nova-keystone-admin nova: nova-keystone-user neutron: nova-keystone-neutron placement: nova-keystone-placement cinder: nova-keystone-cinder ironic: nova-keystone-ironic service: nova-keystone-service test: nova-keystone-test oslo_db: admin: nova-db-admin nova: nova-db-user oslo_db_api: admin: nova-db-api-admin nova: nova-db-api-user oslo_db_cell0: admin: nova-db-cell0-admin nova: nova-db-cell0-user oslo_messaging: admin: nova-rabbitmq-admin nova: nova-rabbitmq-user tls: compute: osapi: public: nova-tls-public internal: nova-tls-api compute_novnc_proxy: novncproxy: public: nova-novncproxy-tls-public internal: nova-novncproxy-tls-proxy vencrypt: internal: nova-novncproxy-vencrypt compute_metadata: metadata: public: metadata-tls-public internal: metadata-tls-metadata compute_spice_proxy: spiceproxy: public: nova-spiceproxy-tls-public internal: nova-spiceproxy-tls-proxy compute_serial_proxy: serialproxy: public: nova-serialproxy-tls-public internal: nova-serialproxy-tls-proxy oci_image_registry: nova: nova-oci-image-registry # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false nova: username: nova password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct nova: username: nova password: password hosts: default: mariadb host_fqdn_override: default: null path: /nova scheme: mysql+pymysql port: mysql: default: 3306 oslo_db_api: auth: admin: username: root password: password nova: username: nova password: password hosts: default: mariadb host_fqdn_override: default: null path: /nova_api scheme: mysql+pymysql port: mysql: default: 3306 oslo_db_cell0: auth: admin: username: root password: password nova: username: nova password: password hosts: default: mariadb host_fqdn_override: default: null path: /nova_cell0 scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct nova: username: nova password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /nova scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default nova: role: admin,service region_name: RegionOne username: nova password: password project_name: service user_domain_name: service project_domain_name: service service: role: admin,service region_name: RegionOne username: nova_service_user password: password project_name: service user_domain_name: service project_domain_name: service # NOTE(portdirect): the neutron user is not managed by the nova chart # these values should match those set in the neutron chart. neutron: role: admin,service region_name: RegionOne project_name: service user_domain_name: service project_domain_name: service username: nova_neutron password: password # NOTE(portdirect): the ironic user is not managed by the nova chart # these values should match those set in the ironic chart. ironic: role: admin,service auth_type: password auth_version: v3 region_name: RegionOne project_name: service user_domain_name: service project_domain_name: service username: nova_ironic password: password placement: role: admin,service region_name: RegionOne username: nova_placement password: password project_name: service user_domain_name: service project_domain_name: service cinder: role: admin,service region_name: RegionOne username: nova_cinder password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: nova-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 image: name: glance hosts: default: glance-api public: glance host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 9292 public: 80 volumev3: name: cinderv3 hosts: default: cinder-api public: cinder host_fqdn_override: default: null path: default: '/v3' healthcheck: /healthcheck scheme: default: http port: api: default: 8776 public: 80 compute: name: nova hosts: default: nova-api public: nova host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: "/v2.1/" scheme: default: 'http' service: 'http' port: api: default: 8774 public: 80 service: 8774 novncproxy: default: 6080 compute_metadata: name: nova ip: # IF blank, set clusterIP and metadata_host dynamically ingress: null hosts: default: nova-metadata public: metadata host_fqdn_override: default: null path: default: / scheme: default: 'http' port: metadata: default: 8775 public: 80 compute_novnc_proxy: name: nova hosts: default: nova-novncproxy public: novncproxy host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: /vnc_auto.html scheme: default: 'http' port: novnc_proxy: default: 6080 public: 80 # This endpoint is only to allow configuring the cert used specifically for # vencrypt. Specifically, the same CA/issuer needs to be used to sign both # this cert, and the libvirt/qemu certs. compute_novnc_vencrypt: hosts: default: nova-novncproxy host_fqdn_override: default: commonName: nova-novncproxy usages: - client auth compute_serial_proxy: name: nova hosts: default: nova-serialproxy public: serialproxy host_fqdn_override: default: null scheme: default: 'ws' path: default: /serial_auto.html port: serial_proxy: default: 6083 public: 80 compute_spice_proxy: name: nova hosts: default: nova-spiceproxy public: spiceproxy host_fqdn_override: default: null path: default: /spice_auto.html scheme: default: 'http' port: spice_proxy: default: 6082 public: 80 placement: name: placement hosts: default: placement-api public: placement host_fqdn_override: default: null path: default: / scheme: default: 'http' service: 'http' port: api: default: 8778 public: 80 service: 8778 network: name: neutron hosts: default: neutron-server public: neutron host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9696 public: 80 baremetal: name: ironic hosts: default: ironic-api public: ironic host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 6385 public: 80 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 # NOTE(tp6510): these endpoints allow for things like DNS lookups and ingress # They are using to enable the Egress K8s network policy. kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 pod: probes: rpc_timeout: 60 rpc_retries: 2 compute: default: liveness: enabled: True params: periodSeconds: 90 timeoutSeconds: 70 readiness: enabled: True params: periodSeconds: 90 timeoutSeconds: 70 startup: enabled: True params: failureThreshold: 120 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 70 api-metadata: default: liveness: enabled: True params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 readiness: enabled: True params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 api-osapi: default: liveness: enabled: True params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 readiness: enabled: True params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 5 conductor: default: liveness: enabled: True params: initialDelaySeconds: 120 periodSeconds: 90 timeoutSeconds: 70 readiness: enabled: True params: initialDelaySeconds: 80 periodSeconds: 90 timeoutSeconds: 70 novncproxy: default: liveness: enabled: True params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 readiness: enabled: True params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 scheduler: default: liveness: enabled: True params: initialDelaySeconds: 120 periodSeconds: 90 timeoutSeconds: 70 readiness: enabled: True params: initialDelaySeconds: 80 periodSeconds: 90 timeoutSeconds: 70 serialproxy: default: liveness: enabled: True params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 readiness: enabled: True params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 compute-spice-proxy: default: liveness: enabled: True params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 readiness: enabled: True params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 15 security_context: nova: pod: runAsUser: 42424 container: nova_compute_init: readOnlyRootFilesystem: true runAsUser: 0 ceph_perms: readOnlyRootFilesystem: true runAsUser: 0 nova_compute_vnc_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_compute_serial_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_compute_spice_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_compute: readOnlyRootFilesystem: true privileged: true nova_compute_ssh: privileged: true runAsUser: 0 nova_compute_ssh_init: runAsUser: 0 nova_api_metadata_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_api: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_osapi: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_conductor: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_novncproxy_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_novncproxy_init_assests: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_novncproxy: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_scheduler: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_serialproxy_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_serialproxy: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_spiceproxy_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_spiceproxy_init_assets: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_spiceproxy: readOnlyRootFilesystem: true allowPrivilegeEscalation: false bootstrap: pod: runAsUser: 42424 container: nova_wait_for_computes_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false bootstrap: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_cell_setup: pod: runAsUser: 42424 container: nova_wait_for_computes_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_cell_setup_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_cell_setup: readOnlyRootFilesystem: true allowPrivilegeEscalation: false archive_deleted_rows: pod: runAsUser: 42424 container: nova_archive_deleted_rows_init: readOnlyRootFilesystem: true allowPrivilegeEscalation: false nova_archive_deleted_rows: readOnlyRootFilesystem: true allowPrivilegeEscalation: false cell_setup: pod: runAsUser: 42424 container: nova_cell_setup: readOnlyRootFilesystem: true allowPrivilegeEscalation: false service_cleaner: pod: runAsUser: 42424 container: nova_service_cleaner: readOnlyRootFilesystem: true allowPrivilegeEscalation: false use_fqdn: # NOTE: If the option "host" is not specified in nova.conf, the host name # shown in the hypervisor host is defaulted to the short name of the host. # Setting the option here to true will cause use $(hostname --fqdn) as the # host name by default. If the short name is desired $(hostname --short), # set the option to false. Specifying a host in the nova.conf via the conf: # section will supersede the value of this option. compute: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: nova: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/nova/nova.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/job ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: nova_compute: [] nova_compute_ironic: [] nova_api_metadata: [] nova_api_osapi: [] nova_conductor: [] nova_scheduler: [] nova_bootstrap: [] nova_tests: [] nova_novncproxy: [] nova_serialproxy: [] nova_spiceproxy: [] nova_db_sync: [] nova_archive_deleted_rows: [] nova_service_cleaner: [] nova_cell_setup: [] mounts: nova_compute: init_container: null nova_compute: volumeMounts: volumes: nova_compute_ironic: init_container: null nova_compute_ironic: volumeMounts: volumes: nova_api_metadata: init_container: null nova_api_metadata: volumeMounts: volumes: nova_api_osapi: init_container: null nova_api_osapi: volumeMounts: volumes: nova_conductor: init_container: null nova_conductor: volumeMounts: volumes: nova_scheduler: init_container: null nova_scheduler: volumeMounts: volumes: nova_bootstrap: init_container: null nova_bootstrap: volumeMounts: volumes: nova_tests: init_container: null nova_tests: volumeMounts: volumes: nova_novncproxy: init_novncproxy: null nova_novncproxy: volumeMounts: volumes: nova_serialproxy: init_serialproxy: null nova_serialproxy: volumeMounts: volumes: nova_spiceproxy: init_spiceproxy: null nova_spiceproxy: volumeMounts: volumes: nova_db_sync: nova_db_sync: volumeMounts: volumes: useHostNetwork: novncproxy: true replicas: api_metadata: 1 compute_ironic: 1 osapi: 1 conductor: 1 scheduler: 1 novncproxy: 1 serialproxy: 1 spiceproxy: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 daemonsets: pod_replacement_strategy: RollingUpdate compute: enabled: true min_ready_seconds: 0 max_unavailable: 1 disruption_budget: metadata: min_available: 0 osapi: min_available: 0 termination_grace_period: metadata: timeout: 30 osapi: timeout: 30 resources: enabled: false compute: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" compute_ironic: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" api_metadata: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conductor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" scheduler: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ssh: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" novncproxy: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" serialproxy: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" spiceproxy: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" storage_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" archive_deleted_rows: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" cell_setup: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" service_cleaner: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network_policy: nova: # TODO(lamt): Need to tighten this ingress for security. ingress: - {} egress: - {} health_probe: logging: level: ERROR tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false compute_uuid_self_provisioning: true configmap_bin: true configmap_etc: true cron_job_cell_setup: true cron_job_service_cleaner: true cron_job_archive_deleted_rows: false daemonset_compute: true deployment_api_metadata: true deployment_api_osapi: true deployment_conductor: true deployment_novncproxy: true deployment_serialproxy: true deployment_spiceproxy: true deployment_scheduler: true # NOTE: StatefulSets provide stable pod hostnames (e.g., nova-conductor-0, nova-conductor-1) # which are used as service host names in `openstack compute service list`. # When enabled, the corresponding deployment_* manifest is automatically disabled. # This ensures service names remain stable across pod restarts. statefulset_conductor: false statefulset_scheduler: false ingress_metadata: true ingress_novncproxy: true ingress_serialproxy: true ingress_spiceproxy: true ingress_osapi: true job_bootstrap: true job_storage_init: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_rabbit_init: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_cell_setup: true pdb_metadata: true pdb_osapi: true pod_rally_test: true network_policy: false secret_db_api: true secret_db_cell0: true secret_db: true secret_ingress_tls: true secret_keystone: true secret_ks_etc: true secret_rabbitmq: true secret_registry: true secret_ssh: true service_ingress_metadata: true service_ingress_novncproxy: true service_ingress_serialproxy: true service_ingress_spiceproxy: true service_ingress_osapi: true service_metadata: true service_novncproxy: true service_serialproxy: true service_spiceproxy: true service_osapi: true statefulset_compute_ironic: false # List of compute hosts and its respective uuids # Items should be in the following format # - name: compute-node-hostname # uuid: hosts_uuids: [] # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: octavia/Chart.yaml ================================================ # Copyright 2019 Samsung Electronics Co., Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Octavia name: octavia version: 2025.2.0 home: https://docs.openstack.org/octavia/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Octavia/OpenStack_Project_Octavia_vertical.png sources: - https://opendev.org/openstack/octavia - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: octavia/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Samsung Electronics Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: octavia/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Samsung Electronics Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex octavia-db-manage upgrade head octavia-db-manage upgrade_persistence ================================================ FILE: octavia/templates/bin/_octavia-api.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Samsung Electronics Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/octavia/octavia-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: octavia/templates/bin/_octavia-driver-agent.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2024 Vexxhost Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec octavia-driver-agent \ --config-file /etc/octavia/octavia.conf \ --config-dir /etc/octavia/octavia.conf.d } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: octavia/templates/bin/_octavia-health-manager-get-port.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Samsung Electronics Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex HOSTNAME=$(hostname -s) PORTNAME=octavia-health-manager-port-$HOSTNAME HM_PORT_ID=$(openstack port show $PORTNAME -c id -f value) HM_PORT_MAC=$(openstack port show $PORTNAME -c mac_address -f value) echo $HM_PORT_ID > /tmp/pod-shared/HM_PORT_ID echo $HM_PORT_MAC > /tmp/pod-shared/HM_PORT_MAC ================================================ FILE: octavia/templates/bin/_octavia-health-manager-nic-init.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Samsung Electronics Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex HM_PORT_ID=$(cat /tmp/pod-shared/HM_PORT_ID) HM_PORT_MAC=$(cat /tmp/pod-shared/HM_PORT_MAC) ovs-vsctl --no-wait show ovs-vsctl --may-exist add-port br-int o-hm0 \ -- set Interface o-hm0 type=internal \ -- set Interface o-hm0 external-ids:iface-status=active \ -- set Interface o-hm0 external-ids:attached-mac=$HM_PORT_MAC \ -- set Interface o-hm0 external-ids:iface-id=$HM_PORT_ID \ -- set Interface o-hm0 external-ids:skip_cleanup=true ip link set dev o-hm0 address $HM_PORT_MAC iptables -I INPUT -i o-hm0 -p udp --dport {{ .Values.conf.octavia.health_manager.bind_port }} -j ACCEPT ================================================ FILE: octavia/templates/bin/_octavia-health-manager.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Samsung Electronics Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { cat > /tmp/dhclient.conf < /tmp/pod-shared/HM_PORT_ID echo $HM_PORT_MAC > /tmp/pod-shared/HM_PORT_MAC ================================================ FILE: octavia/templates/bin/_octavia-worker-nic-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex HM_PORT_ID=$(cat /tmp/pod-shared/HM_PORT_ID) HM_PORT_MAC=$(cat /tmp/pod-shared/HM_PORT_MAC) ovs-vsctl --no-wait show ovs-vsctl --may-exist add-port br-int o-w0 \ -- set Interface o-w0 type=internal \ -- set Interface o-w0 external-ids:iface-status=active \ -- set Interface o-w0 external-ids:attached-mac=$HM_PORT_MAC \ -- set Interface o-w0 external-ids:iface-id=$HM_PORT_ID \ -- set Interface o-w0 external-ids:skip_cleanup=true ip link set dev o-w0 address $HM_PORT_MAC ================================================ FILE: octavia/templates/bin/_octavia-worker.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Samsung Electronics Co., Ltd. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { cat > /tmp/dhclient.conf <= 0.1.0" ... ================================================ FILE: openvswitch/templates/bin/_openvswitch-db-server.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" OVS_DB=/run/openvswitch/conf.db OVS_SCHEMA=/usr/share/openvswitch/vswitch.ovsschema OVS_PID=/run/openvswitch/ovsdb-server.pid OVS_SOCKET=/run/openvswitch/db.sock function start () { mkdir -p "$(dirname ${OVS_DB})" if [[ ! -e "${OVS_DB}" ]]; then ovsdb-tool create "${OVS_DB}" fi if [[ "$(ovsdb-tool needs-conversion ${OVS_DB} ${OVS_SCHEMA})" == 'yes' ]]; then ovsdb-tool convert ${OVS_DB} ${OVS_SCHEMA} fi umask 000 exec /usr/sbin/ovsdb-server ${OVS_DB} \ -vconsole:emer \ -vconsole:err \ -vconsole:info \ --pidfile=${OVS_PID} \ --remote=punix:${OVS_SOCKET} \ --remote=db:Open_vSwitch,Open_vSwitch,manager_options \ {{- if .Values.conf.openvswitch_db_server.ptcp_port }} --remote=ptcp:{{ .Values.conf.openvswitch_db_server.ptcp_port }} \ {{- end }} --private-key=db:Open_vSwitch,SSL,private_key \ --certificate=db:Open_vSwitch,SSL,certificate \ --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert } function stop () { PID=$(cat $OVS_PID) ovs-appctl -T1 -t /run/openvswitch/ovsdb-server.${PID}.ctl exit } $COMMAND ================================================ FILE: openvswitch/templates/bin/_openvswitch-vswitchd-init-modules.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex chroot /mnt/host-rootfs modprobe openvswitch chroot /mnt/host-rootfs modprobe gre chroot /mnt/host-rootfs modprobe vxlan {{- if .Values.conf.ovs_dpdk.enabled }} {{- if hasKey .Values.conf.ovs_dpdk "driver"}} chroot /mnt/host-rootfs modprobe {{ .Values.conf.ovs_dpdk.driver | quote }} {{- end }} {{- end }} ================================================ FILE: openvswitch/templates/bin/_openvswitch-vswitchd.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" OVS_SOCKET=/run/openvswitch/db.sock OVS_PID=/run/openvswitch/ovs-vswitchd.pid # Create vhostuser directory and grant nova user (default UID 42424) access # permissions. {{- if .Values.conf.ovs_dpdk.enabled }} mkdir -p /run/openvswitch/{{ .Values.conf.ovs_dpdk.vhostuser_socket_dir }} chown {{ .Values.pod.user.nova.uid }}.{{ .Values.pod.user.nova.uid }} /run/openvswitch/{{ .Values.conf.ovs_dpdk.vhostuser_socket_dir }} chown {{ .Values.pod.user.nova.uid }}.{{ .Values.pod.user.nova.uid }} {{ .Values.conf.ovs_dpdk.hugepages_mountpath }} {{- end }} function start () { t=0 while [ ! -e "${OVS_SOCKET}" ] ; do echo "waiting for ovs socket $sock" sleep 1 t=$(($t+1)) if [ $t -ge 10 ] ; then echo "no ovs socket, giving up" exit 1 fi done ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait show {{- if .Values.conf.ovs_hw_offload.enabled }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:hw-offload={{ .Values.conf.ovs_hw_offload.enabled }} {{- end }} {{- if .Values.conf.ovs_other_config.handler_threads }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:n-handler-threads={{ .Values.conf.ovs_other_config.handler_threads }} {{- end }} {{- if .Values.conf.ovs_other_config.revalidator_threads }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:n-revalidator-threads={{ .Values.conf.ovs_other_config.revalidator_threads }} {{- end }} {{- if .Values.conf.ovs_dpdk.enabled }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:dpdk-hugepage-dir={{ .Values.conf.ovs_dpdk.hugepages_mountpath | quote }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:dpdk-socket-mem={{ .Values.conf.ovs_dpdk.socket_memory | quote }} {{- if .Values.conf.ovs_dpdk.mem_channels }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:dpdk-mem-channels={{ .Values.conf.ovs_dpdk.mem_channels | quote }} {{- end }} {{- if hasKey .Values.conf.ovs_dpdk "pmd_cpu_mask" }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:pmd-cpu-mask={{ .Values.conf.ovs_dpdk.pmd_cpu_mask | quote }} PMD_CPU_MASK={{ .Values.conf.ovs_dpdk.pmd_cpu_mask | quote }} {{- end }} {{- if hasKey .Values.conf.ovs_dpdk "lcore_mask" }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:dpdk-lcore-mask={{ .Values.conf.ovs_dpdk.lcore_mask | quote }} LCORE_MASK={{ .Values.conf.ovs_dpdk.lcore_mask | quote }} {{- end }} {{- if hasKey .Values.conf.ovs_dpdk "vhost_iommu_support" }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:vhost-iommu-support={{ .Values.conf.ovs_dpdk.vhost_iommu_support }} {{- end }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:vhost-sock-dir={{ .Values.conf.ovs_dpdk.vhostuser_socket_dir | quote }} ovs-vsctl --db=unix:${OVS_SOCKET} --no-wait set Open_vSwitch . other_config:dpdk-init=true # No need to create the cgroup if lcore_mask or pmd_cpu_mask is not set. if [[ -n ${PMD_CPU_MASK} || -n ${LCORE_MASK} ]]; then if [ "$(stat -fc %T /sys/fs/cgroup/)" = "cgroup2fs" ]; then # Setup Cgroups to use when breaking out of Kubernetes defined groups mkdir -p /sys/fs/cgroup/osh-openvswitch target_mems="/sys/fs/cgroup/osh-openvswitch/cpuset.mems" target_cpus="/sys/fs/cgroup/osh-openvswitch/cpuset.cpus" touch $target_mems touch $target_cpus # Ensure the write target for the for cpuset.mem for the pod exists if [[ -f "$target_mems" && -f "$target_cpus" ]]; then # Write cpuset.mem and cpuset.cpus for new cgroup and add current task to new cgroup {{- if hasKey .Values.conf.ovs_dpdk "cgroup_cpuset_mems" }} echo "{{ .Values.conf.ovs_dpdk.cgroup_cpuset_mems }}" > "$target_mems" {{- else }} cat /sys/fs/cgroup/cpuset.mems.effective > "$target_mems" {{- end }} {{- if hasKey .Values.conf.ovs_dpdk "cgroup_cpuset_cpus" }} echo "{{ .Values.conf.ovs_dpdk.cgroup_cpuset_cpus }}" > "$target_cpus" {{- else }} cat /sys/fs/cgroup/cpuset.cpus.effective > "$target_cpus" {{- end }} echo $$ > /sys/fs/cgroup/osh-openvswitch/cgroup.procs else echo "ERROR: Could not find write target for either cpuset.mems: $target_mems or cpuset.cpus: $target_cpus" fi else # Setup Cgroups to use when breaking out of Kubernetes defined groups mkdir -p /sys/fs/cgroup/cpuset/osh-openvswitch target_mems="/sys/fs/cgroup/cpuset/osh-openvswitch/cpuset.mems" target_cpus="/sys/fs/cgroup/cpuset/osh-openvswitch/cpuset.cpus" # Ensure the write target for the for cpuset.mem for the pod exists if [[ -f "$target_mems" && -f "$target_cpus" ]]; then # Write cpuset.mem and cpuset.cpus for new cgroup and add current task to new cgroup {{- if hasKey .Values.conf.ovs_dpdk "cgroup_cpuset_mems" }} echo "{{ .Values.conf.ovs_dpdk.cgroup_cpuset_mems }}" > "$target_mems" {{- else }} cat /sys/fs/cgroup/cpuset/cpuset.mems > "$target_mems" {{- end }} {{- if hasKey .Values.conf.ovs_dpdk "cgroup_cpuset_cpus" }} echo "{{ .Values.conf.ovs_dpdk.cgroup_cpuset_cpus }}" > "$target_cpus" {{- else }} cat /sys/fs/cgroup/cpuset/cpuset.cpus > "$target_cpus" {{- end }} echo $$ > /sys/fs/cgroup/cpuset/osh-openvswitch/tasks else echo "ERROR: Could not find write target for either cpuset.mems: $target_mems or cpuset.cpus: $target_cpus" fi fi fi {{- end }} exec /usr/sbin/ovs-vswitchd unix:${OVS_SOCKET} \ -vconsole:emer \ -vconsole:err \ -vconsole:info \ --pidfile=${OVS_PID} \ {{- if .Values.conf.ovs_user_name }} --user="{{ .Values.conf.ovs_user_name }}" \ {{- end }} --mlockall } function stop () { PID=$(cat $OVS_PID) ovs-appctl -T1 -t /run/openvswitch/ovs-vswitchd.${PID}.ctl exit } find_latest_ctl_file() { latest_file="" latest_file=$(ls -lt /run/openvswitch/*.ctl | awk 'NR==1 {if ($3 == "{{ .Values.conf.poststart.rootUser }}") print $NF}') echo "$latest_file" } function poststart () { # This enables the usage of 'ovs-appctl' from neutron-ovs-agent pod. # Wait for potential new ctl file before continuing timeout={{ .Values.conf.poststart.timeout }} start_time=$(date +%s) while true; do latest_ctl_file=$(find_latest_ctl_file) if [ -n "$latest_ctl_file" ]; then break fi current_time=$(date +%s) if (( current_time - start_time >= timeout )); then break fi sleep 1 done until [ -f $OVS_PID ] do echo "Waiting for file $OVS_PID" sleep 1 done PID=$(cat $OVS_PID) OVS_CTL=/run/openvswitch/ovs-vswitchd.${PID}.ctl until [ -S $OVS_CTL ] do echo "Waiting for file $OVS_CTL" sleep 1 done chown {{ .Values.pod.user.nova.uid }}.{{ .Values.pod.user.nova.uid }} ${OVS_CTL} {{- if .Values.conf.poststart.extraCommand }} {{ .Values.conf.poststart.extraCommand | indent 2 }} {{- end }} } $COMMAND ================================================ FILE: openvswitch/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: openvswitch-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} openvswitch-db-server.sh: | {{ tuple "bin/_openvswitch-db-server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} openvswitch-vswitchd.sh: | {{ tuple "bin/_openvswitch-vswitchd.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} openvswitch-vswitchd-init-modules.sh: | {{ tuple "bin/_openvswitch-vswitchd-init-modules.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: openvswitch/templates/daemonset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovsdblivenessProbeTemplate" }} exec: command: - /usr/bin/ovs-vsctl - show {{- end }} {{- define "ovsdbreadinessProbeTemplate" }} exec: command: - /usr/bin/ovs-vsctl - list - Open_Vswitch {{- end }} {{- define "ovsvswitchlivenessProbeTemplate" }} exec: command: {{- if .Values.pod.probes.ovs.ovs_vswitch.liveness.exec }} {{ .Values.pod.probes.ovs.ovs_vswitch.liveness.exec | toYaml | indent 4 }} {{- else }} - /usr/bin/ovs-appctl - bond/list {{- end }} {{- end }} {{- define "ovsvswitchreadinessProbeTemplate" }} exec: command: {{- if .Values.pod.probes.ovs.ovs_vswitch.readiness.exec }} {{ .Values.pod.probes.ovs.ovs_vswitch.readiness.exec | toYaml | indent 4 }} {{- else if not .Values.conf.ovs_dpdk.enabled }} - /bin/bash - -c - '/usr/bin/ovs-vsctl show' {{- else }} - /bin/bash - -c - '/usr/bin/ovs-vsctl show && ! /usr/bin/ovs-vsctl list Open_vSwitch | grep -q dpdk_initialized.*false' {{- end }} {{- end }} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $serviceAccountName := "openvswitch-server" }} {{ tuple $envAll "ovs" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: openvswitch annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "openvswitch" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "openvswitch" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "ovs" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "openvswitch" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "openvswitch" "containerNames" (list "openvswitch-db" "openvswitch-db-perms" "openvswitch-vswitchd" "openvswitch-vswitchd-modules" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "openvswitch" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "openvswitch" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "ovs" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} nodeSelector: {{ .Values.labels.ovs.node_selector_key }}: {{ .Values.labels.ovs.node_selector_value }} {{ if $envAll.Values.pod.tolerations.openvswitch.enabled }} {{ tuple $envAll "openvswitch" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} dnsPolicy: {{ .Values.pod.dns_policy }} hostNetwork: true initContainers: {{ tuple $envAll "ovs" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: openvswitch-db-perms {{ tuple $envAll "openvswitch_db_server" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "ovs" "container" "perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovs.db | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - chown - -R - {{ $envAll.Values.pod.security_context.ovs.container.server.runAsUser | quote }} - /run/openvswitch volumeMounts: - name: pod-tmp mountPath: /tmp - name: run-openvswitch mountPath: /run/openvswitch - name: openvswitch-vswitchd-modules {{ tuple $envAll "openvswitch_vswitchd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "ovs" "container" "modules" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/openvswitch-vswitchd-init-modules.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: openvswitch-bin mountPath: /tmp/openvswitch-vswitchd-init-modules.sh subPath: openvswitch-vswitchd-init-modules.sh readOnly: true - name: host-rootfs mountPath: /mnt/host-rootfs mountPropagation: HostToContainer readOnly: true containers: - name: openvswitch-db {{ tuple $envAll "openvswitch_db_server" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "ovs" "container" "server" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovs.db | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "component" "ovs" "container" "ovs_db" "type" "liveness" "probeTemplate" (include "ovsdblivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "ovs" "container" "ovs_db" "type" "readiness" "probeTemplate" (include "ovsdbreadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: - /tmp/openvswitch-db-server.sh - start lifecycle: preStop: exec: command: - /tmp/openvswitch-db-server.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: openvswitch-bin mountPath: /tmp/openvswitch-db-server.sh subPath: openvswitch-db-server.sh readOnly: true - name: run mountPath: /run - name: openvswitch-vswitchd {{/* Run the container in priviledged mode due to the need for root permissions when we specify --user to run in non-root. */}} {{- $_ := set $envAll.Values.pod.security_context.ovs.container.vswitchd "privileged" true -}} {{- if .Values.conf.ovs_dpdk.enabled }} {{/* Limiting CPU cores would severely affect packet throughput It should be handled through lcore and pmd core masks. */}} {{- if .Values.pod.resources.enabled }} {{ $_ := unset $envAll.Values.pod.resources.ovs.vswitchd.requests "cpu" }} {{ $_ := unset $envAll.Values.pod.resources.ovs.vswitchd.limits "cpu" }} {{- end }} {{- end }} {{ tuple $envAll "openvswitch_vswitchd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "ovs" "container" "vswitchd" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovs.vswitchd | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} # ensures this container can speak to the ovs database # successfully before its marked as ready {{ dict "envAll" $envAll "component" "ovs" "container" "ovs_vswitch" "type" "liveness" "probeTemplate" (include "ovsvswitchlivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "ovs" "container" "ovs_vswitch" "type" "readiness" "probeTemplate" (include "ovsvswitchreadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{- if .Values.pod.tini.enabled }} command: - /tini - -s - -- args: - /tmp/openvswitch-vswitchd.sh - start {{- else }} command: - /tmp/openvswitch-vswitchd.sh - start {{- end }} lifecycle: postStart: exec: command: - /tmp/openvswitch-vswitchd.sh - poststart preStop: exec: command: - /tmp/openvswitch-vswitchd.sh - stop volumeMounts: - name: pod-tmp mountPath: /tmp - name: openvswitch-bin mountPath: /tmp/openvswitch-vswitchd.sh subPath: openvswitch-vswitchd.sh readOnly: true - name: run mountPath: /run {{- if .Values.conf.ovs_dpdk.enabled }} - name: hugepages mountPath: {{ .Values.conf.ovs_dpdk.hugepages_mountpath | quote }} - name: pci-devices mountPath: /sys/bus/pci/devices - name: huge-pages-kernel mountPath: /sys/kernel/mm/hugepages - name: node-devices mountPath: /sys/devices/system/node - name: modules mountPath: /lib/modules - name: devs mountPath: /dev - name: pci-drivers mountPath: /sys/bus/pci/drivers - name: cgroup mountPath: /sys/fs/cgroup - name: var-tmp mountPath: /var/tmp {{- end }} {{- with .Values.openvswitch.extraContainers }} {{- tpl (toYaml .) $envAll | nindent 8 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: openvswitch-bin configMap: name: openvswitch-bin defaultMode: 0555 - name: run hostPath: path: /run type: Directory - name: run-openvswitch hostPath: path: /run/openvswitch type: DirectoryOrCreate - name: host-rootfs hostPath: path: / type: Directory {{- if .Values.conf.ovs_dpdk.enabled }} - name: devs hostPath: path: /dev type: Directory - name: pci-devices hostPath: path: /sys/bus/pci/devices type: Directory - name: huge-pages-kernel hostPath: path: /sys/kernel/mm/hugepages type: Directory - name: node-devices hostPath: path: /sys/devices/system/node type: Directory - name: modules hostPath: path: /lib/modules type: Directory - name: pci-drivers hostPath: path: /sys/bus/pci/drivers type: Directory - name: hugepages hostPath: path: {{ .Values.conf.ovs_dpdk.hugepages_mountpath | quote }} type: Directory - name: cgroup hostPath: path: /sys/fs/cgroup - name: var-tmp hostPath: path: /var/tmp type: DirectoryOrCreate {{- end }} {{- end }} ================================================ FILE: openvswitch/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: openvswitch/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "openvswitch" -}} {{- if .Values.pod.tolerations.openvswitch.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: openvswitch/templates/network-policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "openvswitch" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: openvswitch/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: openvswitch/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for openvswitch. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null images: tags: openvswitch_db_server: quay.io/airshipit/openvswitch:latest-ubuntu_noble openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: ovs: node_selector_key: openvswitch node_selector_value: enabled pod: tini: enabled: true tolerations: openvswitch: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule probes: ovs: ovs_db: liveness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readiness: enabled: true params: initialDelaySeconds: 90 periodSeconds: 30 timeoutSeconds: 5 ovs_vswitch: liveness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 5 readiness: enabled: true params: failureThreshold: 3 periodSeconds: 10 timeoutSeconds: 1 security_context: ovs: pod: runAsUser: 42424 container: perms: runAsUser: 0 allowPrivilegeEscalation: false readOnlyRootFilesystem: true server: runAsUser: 42424 allowPrivilegeEscalation: false readOnlyRootFilesystem: true modules: runAsUser: 0 capabilities: add: - SYS_MODULE - SYS_CHROOT readOnlyRootFilesystem: true vswitchd: runAsUser: 0 capabilities: add: - NET_ADMIN readOnlyRootFilesystem: true dns_policy: "ClusterFirstWithHostNet" lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate ovs: enabled: true min_ready_seconds: 0 max_unavailable: 1 resources: enabled: false ovs: db: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" vswitchd: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" # set resources to enabled and specify one of the following when using dpdk # hugepages-1Gi: "1Gi" # hugepages-2Mi: "512Mi" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" user: nova: uid: 42424 secrets: oci_image_registry: openvswitch: openvswitch-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false openvswitch: username: openvswitch password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null network_policy: openvswitch: ingress: - {} egress: - {} dependencies: dynamic: common: local_image_registry: jobs: - openvswitch-image-repo-sync services: - endpoint: node service: local_image_registry static: ovs: null image_repo_sync: services: - endpoint: internal service: local_image_registry manifests: configmap_bin: true daemonset: true daemonset_ovs_vswitchd: true job_image_repo_sync: true network_policy: false secret_registry: true openvswitch: extraContainers: [] conf: poststart: timeout: 5 rootUser: "root" extraCommand: null openvswitch_db_server: ptcp_port: null ovs_other_config: handler_threads: null revalidator_threads: null ovs_hw_offload: enabled: false ovs_dpdk: enabled: false ## Mandatory parameters. Please uncomment when enabling DPDK # socket_memory: 1024 # hugepages_mountpath: /dev/hugepages # vhostuser_socket_dir: vhostuser # ## Optional hardware specific parameters: modify to match NUMA topology # mem_channels: 4 # lcore_mask: 0x1 # pmd_cpu_mask: 0x4 # ## Optional driver to use. Driver name should be the same as the one ## specified in the ovs_dpdk section in the Neutron values and vice versa # driver: vfio-pci # ## Optional security feature # vHost IOMMU feature restricts the vhost memory that a virtio device # access, available with DPDK v17.11 # vhost_iommu_support: true # ## Optional cgroups cpuset mems/cpus override ## The default is to copy the values from root cgroup, cpuset.mems.effective ## and cpuset.cpus.effective. ## Note: cgroup only created if lcore_mask or pmd_cpu_mask is set # cgroup_cpuset_mems: some_list_of_memory_nodes # cgroup_cpuset_cpus: some_list_of_cpus ## OVS supports run in non-root for both OVS and OVS DPDK mode, the user # for OVS need to be added to container image with user id 42424. # useradd -u 42424 openvswitch; groupmod -g 42424 openvswitch # # Leave empty to run as user that invokes the command (default: root) ovs_user_name: "openvswitch:openvswitch" # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: ovn/.helmignore ================================================ values_overrides ================================================ FILE: ovn/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v23.3.0 description: OpenStack-Helm OVN name: ovn version: 2025.2.0 home: https://www.ovn.org icon: https://www.ovn.org/images/ovn-logo.png sources: - https://github.com/ovn-org/ovn - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: ovn/templates/bin/_ovn-controller-init.sh.tpl ================================================ #!/bin/bash -xe # Copyright 2023 VEXXHOST, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ANNOTATION_KEY="openstack-helm/ovn-system-id" function get_ip_address_from_interface { local interface=$1 local ip=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' 'NR==1 {print $1}') if [ -z "${ip}" ] ; then exit 1 fi echo ${ip} } function get_ip_prefix_from_interface { local interface=$1 local prefix=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' 'NR==1 {print $2}') if [ -z "${prefix}" ] ; then exit 1 fi echo ${prefix} } function migrate_ip_from_nic { src_nic=$1 bridge_name=$2 # Enabling explicit error handling: We must avoid to lose the IP # address in the migration process. Hence, on every error, we # attempt to assign the IP back to the original NIC and exit. set +e ip=$(get_ip_address_from_interface ${src_nic}) prefix=$(get_ip_prefix_from_interface ${src_nic}) bridge_ip=$(get_ip_address_from_interface "${bridge_name}") bridge_prefix=$(get_ip_prefix_from_interface "${bridge_name}") ip link set ${bridge_name} up if [[ -n "${ip}" && -n "${prefix}" ]]; then ip addr flush dev ${src_nic} if [ $? -ne 0 ] ; then ip addr replace ${ip}/${prefix} dev ${src_nic} echo "Error while flushing IP from ${src_nic}." exit 1 fi ip addr replace ${ip}/${prefix} dev "${bridge_name}" if [ $? -ne 0 ] ; then echo "Error assigning IP to bridge "${bridge_name}"." ip addr replace ${ip}/${prefix} dev ${src_nic} exit 1 fi elif [[ -n "${bridge_ip}" && -n "${bridge_prefix}" ]]; then echo "Bridge '${bridge_name}' already has IP assigned. Keeping the same:: IP:[${bridge_ip}]; Prefix:[${bridge_prefix}]..." elif [[ -z "${bridge_ip}" && -z "${ip}" ]]; then echo "Interface and bridge have no ips configured. Leaving as is." else echo "Interface ${src_nic} has invalid IP address. IP:[${ip}]; Prefix:[${prefix}]..." exit 1 fi set -e } function get_current_system_id { ovs-vsctl --if-exists get Open_vSwitch . external_ids:system-id | tr -d '"' } function get_stored_system_id { kubectl get node "$NODE_NAME" -o "jsonpath={.metadata.annotations.openstack-helm/ovn-system-id}" } function store_system_id() { local system_id=$1 kubectl annotate node "$NODE_NAME" "$ANNOTATION_KEY=$system_id" } # Detect tunnel interface tunnel_interface="{{- .Values.network.interface.tunnel -}}" if [ -z "${tunnel_interface}" ] ; then # search for interface with tunnel network routing tunnel_network_cidr="{{- .Values.network.interface.tunnel_network_cidr -}}" if [ -z "${tunnel_network_cidr}" ] ; then tunnel_network_cidr="0/0" fi # If there is not tunnel network gateway, exit tunnel_interface=$(ip -4 route list ${tunnel_network_cidr} | awk -F 'dev' '{ print $2; exit }' \ | awk '{ print $1 }') || exit 1 fi ovs-vsctl set open . external_ids:ovn-encap-ip="$(get_ip_address_from_interface ${tunnel_interface})" # Get the stored system-id from the Kubernetes node annotation stored_system_id=$(get_stored_system_id) # Get the current system-id set in OVS current_system_id=$(get_current_system_id) if [ -n "$stored_system_id" ] && [ "$stored_system_id" != "$current_system_id" ]; then # If the annotation exists and does not match the current system-id, set the system-id to the stored one ovs-vsctl set Open_vSwitch . external_ids:system-id="$stored_system_id" elif [ -z "$current_system_id" ]; then # If no current system-id is set, generate a new one current_system_id=$(uuidgen) ovs-vsctl set Open_vSwitch . external_ids:system-id="$current_system_id" # Store the new system-id in the Kubernetes node annotation store_system_id "$current_system_id" elif [ -z "$stored_system_id" ]; then # If there is no stored system-id, store the current one store_system_id "$current_system_id" fi # Configure OVN remote {{- if empty .Values.conf.ovn_remote -}} {{- $sb_svc_name := "ovn-ovsdb-sb" -}} {{- $sb_svc := (tuple $sb_svc_name "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") -}} {{- $sb_port := (tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup") -}} {{- $sb_service_list := list -}} {{- range $i := until (.Values.pod.replicas.ovn_ovsdb_sb | int) -}} {{- $sb_service_list = printf "tcp:%s-%d.%s:%s" $sb_svc_name $i $sb_svc $sb_port | append $sb_service_list -}} {{- end }} ovs-vsctl set open . external-ids:ovn-remote="{{ include "helm-toolkit.utils.joinListWithComma" $sb_service_list }}" {{- else }} ovs-vsctl set open . external-ids:ovn-remote="{{ .Values.conf.ovn_remote }}" {{- end }} # Configure OVN values ovs-vsctl set open . external-ids:rundir="/var/run/openvswitch" ovs-vsctl set open . external-ids:ovn-encap-type="{{ .Values.conf.ovn_encap_type }}" ovs-vsctl set open . external-ids:ovn-bridge="{{ .Values.conf.ovn_bridge }}" ovs-vsctl set open . external-ids:ovn-bridge-mappings="{{ .Values.conf.ovn_bridge_mappings }}" ovs-vsctl set open . external-ids:ovn-monitor-all="{{ .Values.conf.ovn_monitor_all }}" GW_ENABLED=$(cat /tmp/gw-enabled/gw-enabled) if [[ ${GW_ENABLED} == {{ .Values.labels.ovn_controller_gw.node_selector_value }} ]]; then ovs-vsctl set open . external-ids:ovn-cms-options={{ .Values.conf.ovn_cms_options_gw_enabled }} else ovs-vsctl set open . external-ids:ovn-cms-options={{ .Values.conf.ovn_cms_options }} fi {{ if .Values.conf.ovn_bridge_datapath_type -}} ovs-vsctl set open . external-ids:ovn-bridge-datapath-type="{{ .Values.conf.ovn_bridge_datapath_type }}" {{- end }} # Configure hostname {{- if .Values.pod.use_fqdn.compute }} ovs-vsctl set open . external-ids:hostname="$(hostname -f)" {{- else }} ovs-vsctl set open . external-ids:hostname="$(hostname)" {{- end }} # Create bridges and create ports # handle any bridge mappings # /tmp/auto_bridge_add is one line json file: {"br-ex1":"eth1","br-ex2":"eth2"} for bmap in `sed 's/[{}"]//g' /tmp/auto_bridge_add | tr "," "\n"` do bridge=${bmap%:*} iface=${bmap#*:} ovs-vsctl --may-exist add-br $bridge -- set bridge $bridge protocols=OpenFlow13 if [ -n "$iface" ] && [ "$iface" != "null" ] && ( ip link show $iface 1>/dev/null 2>&1 ); then ovs-vsctl --may-exist add-port $bridge $iface migrate_ip_from_nic $iface $bridge fi done ================================================ FILE: ovn/templates/bin/_ovn-network-logging-parser.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/neutron/neutron-ovn-network-logging-parser-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: ovn/templates/clusterrole-controller.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: ovn-controller rules: - apiGroups: - "" resources: - nodes verbs: - get - patch - list ================================================ FILE: ovn/templates/clusterrolebinding-controller.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ovn-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: ovn-controller subjects: - kind: ServiceAccount name: ovn-controller namespace: {{ .Release.Namespace }} - kind: ServiceAccount name: ovn-controller-gw namespace: {{ .Release.Namespace }} ================================================ FILE: ovn/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovn.configmap.bin" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapName }} data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ovn-controller-init.sh: | {{ tuple "bin/_ovn-controller-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ovn-network-logging-parser.sh: | {{ tuple "bin/_ovn-network-logging-parser.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_bin }} {{- list "ovn-bin" . | include "ovn.configmap.bin" }} {{- end }} ================================================ FILE: ovn/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovn.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty (index .Values.conf.ovn_network_logging_parser_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "ovn_logging_parser" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.ovn_network_logging_parser_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: auto_bridge_add: {{ toJson $envAll.Values.conf.auto_bridge_add | b64enc }} neutron-ovn-network-logging-parser-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.ovn_network_logging_parser_uwsgi | b64enc }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "ovn-etc" . | include "ovn.configmap.etc" }} {{- end }} ================================================ FILE: ovn/templates/daemonset-controller.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "controllerReadinessProbeTemplate" }} exec: command: - /usr/bin/ovn-kube-util - readiness-probe - -t - ovn-controller {{- end }} {{- define "ovn.daemonset" }} {{- $daemonset := index . 0 }} {{- $configMapName := index . 1 }} {{- $serviceAccountName := index . 2 }} {{- $envAll := index . 3 }} {{- with $envAll }} {{- $env_ovn := .Values.pod.envs }} --- kind: DaemonSet apiVersion: apps/v1 metadata: name: ovn-controller annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} labels: {{ tuple $envAll "ovn" "ovn-controller" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "ovn" "ovn-controller" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "ovn" "ovn-controller" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} hostNetwork: true hostPID: true hostIPC: true dnsPolicy: {{ .Values.pod.dns_policy }} nodeSelector: {{ .Values.labels.ovn_controller.node_selector_key }}: {{ .Values.labels.ovn_controller.node_selector_value }} initContainers: {{- tuple $envAll "ovn_controller" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: get-gw-enabled {{ tuple $envAll "ovn_controller_kubectl" | include "helm-toolkit.snippets.image" | indent 10 }} command: - /bin/bash - -c - | kubectl get node ${NODENAME} -o jsonpath='{.metadata.labels.{{ .Values.labels.ovn_controller_gw.node_selector_key }}}' > /tmp/gw-enabled/gw-enabled env: - name: NODENAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: gw-enabled mountPath: /tmp/gw-enabled readOnly: false - name: controller-init {{ dict "envAll" $envAll "application" "ovn_controller" "container" "controller_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll "ovn_controller" | include "helm-toolkit.snippets.image" | indent 10 }} command: - /tmp/ovn-controller-init.sh env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: ovn-bin mountPath: /tmp/ovn-controller-init.sh subPath: ovn-controller-init.sh readOnly: true - name: run-openvswitch mountPath: /run/openvswitch - name: ovn-etc mountPath: /tmp/auto_bridge_add subPath: auto_bridge_add readOnly: true - name: gw-enabled mountPath: /tmp/gw-enabled readOnly: true containers: - name: controller {{ tuple $envAll "ovn_controller" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovn_controller | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ovn_controller" "container" "controller" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /root/ovnkube.sh - ovn-controller {{ dict "envAll" . "component" "ovn_controller" "container" "controller" "type" "readiness" "probeTemplate" (include "controllerReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: - name: OVS_USER_ID value: {{ .Values.conf.ovs_user_name }} {{ if $env_ovn.common }}{{ toYaml $env_ovn.common | indent 12 }}{{ end }} {{ if $env_ovn.controller }}{{ toYaml $env_ovn.controller | indent 12 }}{{ end }} volumeMounts: - name: run-openvswitch mountPath: /run/openvswitch - name: logs mountPath: /var/log/ovn - name: run-openvswitch mountPath: /run/ovn {{- if .Values.pod.sidecars.vector }} - name: vector {{ tuple $envAll "vector" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.vector | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ovn_controller" "container" "vector" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - vector - --config - /etc/vector/vector.toml volumeMounts: - name: vector-config mountPath: /etc/vector - name: logs mountPath: /logs - name: vector-data mountPath: /var/lib/vector {{- end }} {{- if .Values.pod.sidecars.ovn_logging_parser }} - name: log-parser {{ tuple $envAll "ovn_logging_parser" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovn_logging_parser | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ovn_controller" "container" "ovn_logging_parser" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ovn-network-logging-parser.sh - start env: - name: VECTOR_HTTP_ENDPOINT value: http://localhost:5001 ports: - name: http containerPort: {{ tuple "ovn_logging_parser" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP volumeMounts: - name: neutron-etc mountPath: /etc/neutron/neutron.conf subPath: neutron.conf readOnly: true - name: ovn-bin mountPath: /tmp/ovn-network-logging-parser.sh subPath: ovn-network-logging-parser.sh readOnly: true - name: ovn-etc mountPath: /etc/neutron/neutron-ovn-network-logging-parser-uwsgi.ini subPath: neutron-ovn-network-logging-parser-uwsgi.ini readOnly: true {{- end }} volumes: - name: ovn-bin configMap: name: ovn-bin defaultMode: 0777 - name: run-openvswitch hostPath: path: /run/openvswitch type: DirectoryOrCreate - name: ovn-etc secret: secretName: {{ $configMapName }} defaultMode: 0444 - name: logs hostPath: path: /var/log/ovn type: DirectoryOrCreate - name: run-ovn hostPath: path: /run/ovn type: DirectoryOrCreate - name: gw-enabled emptyDir: {} {{- if .Values.pod.sidecars.vector }} - name: vector-config secret: secretName: ovn-vector-config - name: vector-data emptyDir: {} {{- end }} {{- if .Values.pod.sidecars.ovn_logging_parser }} - name: neutron-etc secret: secretName: neutron-etc defaultMode: 0444 {{- end }} {{- end }} {{- end }} {{- if .Values.manifests.daemonset_ovn_controller }} {{- $envAll := . }} {{- $daemonset := "controller" }} {{- $configMapName := "ovn-etc" }} {{- $serviceAccountName := "ovn-controller" }} {{ tuple $envAll "ovn_controller" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $configmap_yaml := "ovn.configmap.etc" }} {{/* Preffer using .Values.overrides rather than .Values.conf.overrides */}} {{- list $daemonset "ovn.daemonset" $serviceAccountName $configmap_yaml $configMapName "ovn.configmap.bin" "ovn-bin" . | include "helm-toolkit.utils.daemonset_overrides_root" }} {{- $serviceAccountNamespace := $envAll.Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: ovn-controller-list-nodes-role-{{ $serviceAccountNamespace }} rules: - apiGroups: [""] resources: ["nodes"] verbs: ["list", "get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ovn-controller-list-nodes-rolebinding-{{ $serviceAccountNamespace }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $serviceAccountNamespace }} roleRef: kind: ClusterRole name: ovn-controller-list-nodes-role-{{ $serviceAccountNamespace }} apiGroup: rbac.authorization.k8s.io {{- end }} ================================================ FILE: ovn/templates/deployment-northd.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "northdReadinessProbeTemplate" }} exec: command: - /usr/bin/ovn-kube-util - readiness-probe - -t - ovn-northd {{- end }} {{- if .Values.manifests.deployment_northd }} {{- $envAll := . }} {{- $serviceAccountName := "ovn-northd" }} {{ tuple $envAll "ovn_northd" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $env_ovn := .Values.pod.envs }} --- kind: Deployment apiVersion: apps/v1 metadata: name: ovn-northd annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ovn" "ovn-northd" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.ovn_northd }} selector: matchLabels: {{ tuple $envAll "ovn" "ovn-northd" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "ovn" "ovn-northd" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.ovn_northd.node_selector_key }}: {{ .Values.labels.ovn_northd.node_selector_value }} initContainers: {{- tuple $envAll "ovn_northd" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: northd command: - /root/ovnkube.sh - run-ovn-northd {{ tuple $envAll "ovn_northd" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovn_northd | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "ovn_northd" "container" "northd" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ dict "envAll" . "component" "ovn_northd" "container" "northd" "type" "readiness" "probeTemplate" (include "northdReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "ovn_northd" "container" "northd" "type" "liveness" "probeTemplate" (include "northdReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: {{ if $env_ovn.common }}{{ toYaml $env_ovn.common | indent 12 }}{{ end }} {{ if $env_ovn.northd }}{{ toYaml $env_ovn.northd | indent 12 }}{{ end }} {{- end }} ================================================ FILE: ovn/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: ovn/templates/role-controller.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ovn-controller namespace: {{ .Release.Namespace }} rules: - apiGroups: - discovery.k8s.io resources: - endpointslices verbs: - list ================================================ FILE: ovn/templates/role-northd.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ovn-northd namespace: {{ .Release.Namespace }} rules: - apiGroups: - discovery.k8s.io resources: - endpointslices verbs: - list ================================================ FILE: ovn/templates/role-ovsdb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ovn-ovsdb namespace: {{ .Release.Namespace }} rules: - apiGroups: - "apps" resources: - statefulsets verbs: - get - apiGroups: - "" resources: - pods - endpoints verbs: - list - get ================================================ FILE: ovn/templates/rolebinding-controller.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ovn-controller namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: ovn-controller subjects: - kind: ServiceAccount name: ovn-controller namespace: {{ .Release.Namespace }} - kind: ServiceAccount name: ovn-controller-gw namespace: {{ .Release.Namespace }} ================================================ FILE: ovn/templates/rolebinding-northd.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ovn-northd namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: ovn-northd subjects: - kind: ServiceAccount name: ovn-northd namespace: {{ .Release.Namespace }} ================================================ FILE: ovn/templates/rolebinding-ovsdb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ovn-ovsdb namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: ovn-ovsdb subjects: - kind: ServiceAccount name: ovn-ovsdb-nb namespace: {{ .Release.Namespace }} - kind: ServiceAccount name: ovn-ovsdb-sb namespace: {{ .Release.Namespace }} ================================================ FILE: ovn/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: ovn/templates/secret-vector.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.pod.sidecars.vector }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: ovn-vector-config type: Opaque data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.vector "key" "vector.toml" "format" "Secret" ) | indent 2 }} {{- end }} ================================================ FILE: ovn/templates/service-ovsdb-nb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_ovn_ovsdb_nb }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "ovn-ovsdb-nb" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: publishNotReadyAddresses: true ports: - name: ovsdb port: {{ tuple "ovn-ovsdb-nb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: raft port: {{ tuple "ovn-ovsdb-nb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: ovn/templates/service-ovsdb-sb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_ovn_ovsdb_sb }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "ovn-ovsdb-sb" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: publishNotReadyAddresses: true ports: - name: ovsdb port: {{ tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: raft port: {{ tuple "ovn-ovsdb-sb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: ovn/templates/statefulset-ovsdb-nb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovnnbReadinessProbeTemplate" }} exec: command: - /usr/bin/ovn-kube-util - readiness-probe - -t {{- if gt (int .Values.pod.replicas.ovn_ovsdb_nb) 1 }} - ovnnb-db-raft {{- else }} - ovnnb-db {{- end }} {{- end }} {{- if .Values.manifests.statefulset_ovn_ovsdb_nb }} {{- $envAll := . }} {{- $serviceAccountName := "ovn-ovsdb-nb" }} {{ tuple $envAll "ovn_ovsdb_nb" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $env_ovn := .Values.pod.envs }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: ovn-ovsdb-nb annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: {{ tuple "ovn-ovsdb-nb" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} podManagementPolicy: Parallel replicas: {{ .Values.pod.replicas.ovn_ovsdb_nb }} selector: matchLabels: {{ tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{- tuple $envAll "ovn" "ovn-ovsdb-nb" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.ovn_ovsdb_nb.node_selector_key }}: {{ .Values.labels.ovn_ovsdb_nb.node_selector_value }} initContainers: {{- tuple $envAll "ovn_ovsdb_nb" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ovsdb command: - /root/ovnkube.sh {{- if gt (int .Values.pod.replicas.ovn_ovsdb_nb) 1 }} - nb-ovsdb-raft {{- else }} - nb-ovsdb {{- end }} {{ tuple $envAll "ovn_ovsdb_nb" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovn_ovsdb_nb | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" . "component" "ovn_ovsdb_nb" "container" "ovsdb" "type" "readiness" "probeTemplate" (include "ovnnbReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} ports: - containerPort: {{ tuple "ovn-ovsdb-nb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - containerPort: {{ tuple "ovn-ovsdb-nb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: OVN_NB_PORT value: {{ tuple "ovn-ovsdb-nb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: OVN_NB_RAFT_PORT value: {{ tuple "ovn-ovsdb-nb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} {{ if $env_ovn.common }}{{ toYaml $env_ovn.common | indent 12 }}{{ end }} {{ if $env_ovn.ovsdb_nb }}{{ toYaml $env_ovn.ovsdb_nb | indent 12 }}{{ end }} volumeMounts: - name: run-openvswitch mountPath: /var/run/openvswitch - name: run-openvswitch mountPath: /var/run/ovn - name: data mountPath: {{ $envAll.Values.volume.ovn_ovsdb_nb.path }} volumes: - name: run-openvswitch hostPath: path: /run/openvswitch type: DirectoryOrCreate {{- if not .Values.volume.ovn_ovsdb_nb.enabled }} - name: data emptyDir: {} {{- else }} volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: {{ $envAll.Values.volume.ovn_ovsdb_nb.class_name }} resources: requests: storage: {{ $envAll.Values.volume.ovn_ovsdb_nb.size }} {{- end }} {{- end }} ================================================ FILE: ovn/templates/statefulset-ovsdb-sb.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "ovnsbReadinessProbeTemplate" }} exec: command: - /usr/bin/ovn-kube-util - readiness-probe - -t {{- if gt (int .Values.pod.replicas.ovn_ovsdb_sb) 1 }} - ovnsb-db-raft {{- else }} - ovnsb-db {{- end }} {{- end }} {{- if .Values.manifests.statefulset_ovn_ovsdb_sb }} {{- $envAll := . }} {{- $serviceAccountName := "ovn-ovsdb-sb" }} {{ tuple $envAll "ovn_ovsdb_sb" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $env_ovn := .Values.pod.envs }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: ovn-ovsdb-sb annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: {{ tuple "ovn-ovsdb-sb" "direct" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} podManagementPolicy: Parallel replicas: {{ .Values.pod.replicas.ovn_ovsdb_sb }} selector: matchLabels: {{ tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{- tuple $envAll "ovn" "ovn-ovsdb-sb" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.ovn_ovsdb_sb.node_selector_key }}: {{ .Values.labels.ovn_ovsdb_sb.node_selector_value }} initContainers: {{- tuple $envAll "ovn_ovsdb_sb" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ovsdb command: - /root/ovnkube.sh {{- if gt (int .Values.pod.replicas.ovn_ovsdb_sb) 1 }} - sb-ovsdb-raft {{- else }} - sb-ovsdb {{- end }} {{ tuple $envAll "ovn_ovsdb_sb" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.ovn_ovsdb_sb | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" . "component" "ovn_ovsdb_sb" "container" "ovsdb" "type" "readiness" "probeTemplate" (include "ovnsbReadinessProbeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} ports: - containerPort: {{ tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - containerPort: {{ tuple "ovn-ovsdb-sb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: OVN_SB_PORT value: {{ tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: OVN_SB_RAFT_PORT value: {{ tuple "ovn-ovsdb-sb" "internal" "raft" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} {{ if $env_ovn.common }}{{ toYaml $env_ovn.common | indent 12 }}{{ end }} {{ if $env_ovn.ovsdb_sb }}{{ toYaml $env_ovn.ovsdb_sb | indent 12 }}{{ end }} volumeMounts: - name: run-openvswitch mountPath: /var/run/openvswitch - name: run-openvswitch mountPath: /var/run/ovn - name: data mountPath: {{ $envAll.Values.volume.ovn_ovsdb_sb.path }} volumes: - name: run-openvswitch hostPath: path: /run/openvswitch type: DirectoryOrCreate {{- if not .Values.volume.ovn_ovsdb_sb.enabled }} - name: data emptyDir: {} {{- else }} volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: data spec: accessModes: ["ReadWriteOnce"] storageClassName: {{ $envAll.Values.volume.ovn_ovsdb_sb.class_name }} resources: requests: storage: {{ $envAll.Values.volume.ovn_ovsdb_sb.size }} {{- end }} {{- end }} ================================================ FILE: ovn/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for openvswitch. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null images: tags: ovn_ovsdb_nb: quay.io/airshipit/ovn:ubuntu_noble ovn_ovsdb_sb: quay.io/airshipit/ovn:ubuntu_noble ovn_northd: quay.io/airshipit/ovn:ubuntu_noble ovn_controller: quay.io/airshipit/ovn:ubuntu_noble ovn_controller_kubectl: quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 vector: docker.io/timberio/vector:0.51.1-debian ovn_logging_parser: quay.io/airshipit/neutron:2025.1-ubuntu_noble pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: ovn_ovsdb_nb: node_selector_key: openstack-network-node node_selector_value: enabled ovn_ovsdb_sb: node_selector_key: openstack-network-node node_selector_value: enabled ovn_northd: node_selector_key: openstack-network-node node_selector_value: enabled ovn_controller: node_selector_key: openvswitch node_selector_value: enabled ovn_controller_gw: node_selector_key: l3-agent node_selector_value: enabled volume: ovn_ovsdb_nb: path: /var/lib/ovn enabled: true class_name: general size: 5Gi ovn_ovsdb_sb: path: /var/lib/ovn enabled: true class_name: general size: 5Gi network: interface: # Tunnel interface will be used for VXLAN tunneling. tunnel: null # If tunnel is null there is a fallback mechanism to search # for interface with routing using tunnel network cidr. tunnel_network_cidr: "0/0" conf: ovn_cms_options: "availability-zones=nova" ovn_cms_options_gw_enabled: "enable-chassis-as-gw,availability-zones=nova" ovn_encap_type: geneve ovn_bridge: br-int ovn_bridge_mappings: external:br-ex ovn_monitor_all: false # For DPDK enabled environments, enable netdev datapath type for br-int # ovn_bridge_datapath_type: netdev # auto_bridge_add: # br-private: eth0 # br-public: eth1 auto_bridge_add: {} ovs_user_name: openvswitch ovn_network_logging_parser_uwsgi: uwsgi: add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true processes: 1 procname-prefix-spaced: "neutron-ovn-network-logging-parser:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/neutron-ovn-network-logging-parser-wsgi stats: 0.0.0.0:1717 stats-http: true vector: | [sources.file_logs] type = "file" include = [ "/logs/ovn-controller.log" ] [sinks.ovn_log_parser_in] type = "http" inputs = ["file_logs"] uri = "{{ tuple "ovn_logging_parser" "default" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }}" encoding.codec = "json" method = "post" [sources.ovn_log_parser_out] type = "http_server" address = "0.0.0.0:5001" encoding = "json" [transforms.parse_log_message] type = "remap" inputs = ["ovn_log_parser_out"] source = ''' del(.source_type) del(.path) ''' [sinks.loki_sink] type = "loki" labels.event_source = "network_logs" inputs = ["parse_log_message"] endpoint = "http://loki.monitoring:3100" encoding.codec = "json" tenant_id = "{{`{{ project_id }}`}}" pod: # NOTE: should be same as nova.pod.use_fqdn.compute use_fqdn: compute: true envs: common: - name: OVN_DAEMONSET_VERSION value: "3" - name: OVN_KUBERNETES_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: OVN_KUBERNETES_NB_STATEFULSET value: ovn-ovsdb-nb - name: OVN_KUBERNETES_SB_STATEFULSET value: ovn-ovsdb-sb - name: OVN_SSL_ENABLE value: "no" controller: - name: OVN_LOGLEVEL_CONTROLLER value: "-vconsole:info -vfile:info" northd: - name: OVN_LOGLEVEL_NORTHD value: "-vconsole:info -vfile:info" ovsdb_nb: - name: OVN_LOGLEVEL_NB value: "-vconsole:info -vfile:info" - name: OVN_KUBERNETES_STATEFULSET value: ovn-ovsdb-nb - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: ENABLE_IPSEC value: "false" - name: OVN_NB_RAFT_ELECTION_TIMER value: "1000" ovsdb_sb: - name: OVN_LOGLEVEL_SB value: "-vconsole:info -vfile:info" - name: OVN_KUBERNETES_STATEFULSET value: ovn-ovsdb-sb - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: ENABLE_IPSEC value: "false" - name: OVN_SB_RAFT_ELECTION_TIMER value: "1000" security_context: ovn_northd: container: northd: capabilities: add: - SYS_NICE ovn_controller: container: controller_init: readOnlyRootFilesystem: true privileged: true controller: readOnlyRootFilesystem: true privileged: true ovn_logging_parser: allowPrivilegeEscalation: false readOnlyRootFilesystem: true vector: allowPrivilegeEscalation: false readOnlyRootFilesystem: true tolerations: ovn_ovsdb_nb: enabled: false ovn_ovsdb_sb: enabled: false ovn_northd: enabled: false ovn_controller: enabled: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 probes: ovn_northd: northd: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 periodSeconds: 60 ovn_ovsdb_nb: ovsdb: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 periodSeconds: 60 ovn_ovsdb_sb: ovsdb: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 periodSeconds: 60 ovn_controller: controller: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 periodSeconds: 60 ovn_controller_gw: controller: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 periodSeconds: 60 dns_policy: "ClusterFirstWithHostNet" replicas: ovn_ovsdb_nb: 1 ovn_ovsdb_sb: 1 ovn_northd: 1 lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate ovn_ovsdb_nb: enabled: true min_ready_seconds: 0 max_unavailable: 1 ovn_ovsdb_sb: enabled: true min_ready_seconds: 0 max_unavailable: 1 ovn_northd: enabled: true min_ready_seconds: 0 max_unavailable: 1 ovn_controller: enabled: true min_ready_seconds: 0 max_unavailable: 1 resources: enabled: false ovn_ovsdb_nb: requests: memory: "384Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "1000m" ovn_ovsdb_sb: requests: memory: "384Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "1000m" ovn_northd: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ovn_controller: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ovn_logging_parser: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m" vector: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" sidecars: ovn_logging_parser: false vector: false secrets: oci_image_registry: ovn: ovn-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false ovn: username: openvswitch password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null ovn_ovsdb_nb: name: ovn-ovsdb-nb namespace: null hosts: default: ovn-ovsdb-nb host_fqdn_override: default: null port: ovsdb: default: 6641 raft: default: 6643 ovn_ovsdb_sb: name: ovn-ovsdb-sb namespace: null hosts: default: ovn-ovsdb-sb host_fqdn_override: default: null port: ovsdb: default: 6642 raft: default: 6644 ovn_logging_parser: name: ovn-logging-parser namespace: null hosts: default: localhost host_fqdn_override: default: localhost scheme: default: 'http' service: 'http' path: default: "/logs" port: api: default: 9697 service: 9697 network_policy: ovn_ovsdb_nb: ingress: - {} egress: - {} ovn_ovsdb_sb: ingress: - {} egress: - {} ovn_northd: ingress: - {} egress: - {} ovn_controller: ingress: - {} egress: - {} dependencies: dynamic: common: local_image_registry: jobs: - openvswitch-image-repo-sync services: - endpoint: node service: local_image_registry static: ovn_ovsdb_nb: null ovn_ovsdb_sb: null ovn_northd: services: - endpoint: internal service: ovn-ovsdb-nb - endpoint: internal service: ovn-ovsdb-sb ovn_controller: services: - endpoint: internal service: ovn-ovsdb-sb pod: - requireSameNode: true labels: application: openvswitch component: server image_repo_sync: services: - endpoint: internal service: local_image_registry manifests: configmap_bin: true configmap_etc: true deployment_northd: true service_ovn_ovsdb_nb: true service_ovn_ovsdb_sb: true statefulset_ovn_ovsdb_nb: true statefulset_ovn_ovsdb_sb: true deployment_ovn_northd: true daemonset_ovn_controller: true job_image_repo_sync: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: placement/.helmignore ================================================ values_overrides ================================================ FILE: placement/Chart.yaml ================================================ # Copyright 2019 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Placement name: placement version: 2025.2.0 home: https://docs.openstack.org/placement/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Placement/OpenStack_Project_Placement_vertical.png sources: - https://opendev.org/openstack/placement - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: placement/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex placement-manage db sync ================================================ FILE: placement/templates/bin/_placement-api.sh.tpl ================================================ #!/bin/bash {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { {{- if .Values.manifests.certificates }} cp -a $(type -p placement-api) /var/www/cgi-bin/placement/ if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/apache2/envvars # The directory below has to be created due to the fact that # libapache2-mod-wsgi-py3 doesn't create it in contrary by libapache2-mod-wsgi mkdir -p ${APACHE_RUN_DIR} fi # Get rid of stale pid file if present. rm -f /var/run/apache2/*.pid # Start Apache2 {{- if .Values.conf.software.apache2.a2enmod }} {{- range .Values.conf.software.apache2.a2enmod }} a2enmod {{ . }} {{- end }} {{- end }} {{- if .Values.conf.software.apache2.a2dismod }} {{- range .Values.conf.software.apache2.a2dismod }} a2dismod {{ . }} {{- end }} {{- end }} exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} {{- else }} exec uwsgi --ini /etc/placement/placement-api-uwsgi.ini {{- end }} } function stop () { {{- if .Values.manifests.certificates }} if [ -f /etc/apache2/envvars ]; then source /etc/apache2/envvars fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop {{- else }} kill -TERM 1 {{- end }} } $COMMAND ================================================ FILE: placement/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "placement" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: placement/templates/configmap-bin.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: placement-bin data: placement-api.sh: | {{ tuple "bin/_placement-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} {{- end }} ================================================ FILE: placement/templates/configmap-etc.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if and (not (kindIs "invalid" .Values.conf.placement.placement_database.connection)) (empty .Values.conf.placement.placement_database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "placement" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.placement.placement_database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.placement.placement_database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.placement.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.placement.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.placement.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.placement.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.placement.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.placement.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.placement.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.placement.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if empty (index .Values.conf.placement_api_uwsgi.uwsgi "http-socket") -}} {{- $http_socket_port := tuple "placement" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | toString }} {{- $http_socket := printf "0.0.0.0:%s" $http_socket_port }} {{- $_ := set .Values.conf.placement_api_uwsgi.uwsgi "http-socket" $http_socket -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: placement-etc type: Opaque data: policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} placement.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.placement | b64enc }} placement-api-uwsgi.ini: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.placement_api_uwsgi | b64enc }} {{- if .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_placement "key" "wsgi-placement.conf" "format" "Secret" ) | indent 2 }} {{- end }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} {{- end }} ================================================ FILE: placement/templates/deployment.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $mounts_placement := .Values.pod.mounts.placement.placement }} {{- $mounts_placement_init := .Values.pod.mounts.placement.init_container }} {{- $etcSources := .Values.pod.etcSources.placement }} {{- if eq .Values.manifests.secret_ks_etc true }} {{- $etcSources = append $etcSources (dict "secret" (dict "name" "placement-ks-etc")) }} {{- end }} {{- $serviceAccountName := "placement-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: placement-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "placement" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "placement" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "placement" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "placement" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "placement-api" "containerNames" (list "placement-api" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "placement" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "placement" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "placement" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "placement" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.placement.enabled }} {{ tuple $envAll "placement" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_placement_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} {{- if .Values.conf.placement.DEFAULT.log_dir }} - name: placement-api-init-log {{ tuple $envAll "placement" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "placement" "container" "placement_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - "placement:" - {{ .Values.conf.placement.DEFAULT.log_dir }} volumeMounts: - name: log mountPath: {{ .Values.conf.placement.DEFAULT.log_dir }} {{- end }} containers: - name: placement-api {{ tuple $envAll "placement" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "placement" "container" "placement_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/placement/certs/ca.crt" {{- end }} command: - /tmp/placement-api.sh - start lifecycle: preStop: exec: command: - /tmp/placement-api.sh - stop ports: - name: p-api containerPort: {{ tuple "placement" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: {{ tuple "placement" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "placement" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: scheme: {{ tuple "placement" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / {{- if .Values.pod.probes.placement.api.liveness.port }} port: {{ .Values.pod.probes.placement.api.liveness.port }} {{- else }} port: {{ tuple "placement" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} initialDelaySeconds: 5 periodSeconds: 10 volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.placement.oslo_concurrency.lock_path }} - name: wsgi-placement mountPath: /var/www/cgi-bin/placement - name: placement-bin mountPath: /tmp/placement-api.sh subPath: placement-api.sh readOnly: true - name: placement-etc mountPath: /etc/placement/placement.conf subPath: placement.conf readOnly: true - name: placement-etc-snippets mountPath: /etc/placement/placement.conf.d/ readOnly: true - name: placement-etc mountPath: /etc/placement/placement-api-uwsgi.ini subPath: placement-api-uwsgi.ini readOnly: true {{- if .Values.conf.placement.DEFAULT.log_config_append }} - name: placement-etc mountPath: {{ .Values.conf.placement.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.placement.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: placement-etc mountPath: /etc/placement/policy.yaml subPath: policy.yaml readOnly: true - name: placement-etc mountPath: /etc/apache2/conf-enabled/wsgi-placement.conf subPath: wsgi-placement.conf readOnly: true {{- if .Values.conf.placement.DEFAULT.log_dir }} - name: log mountPath: {{ .Values.conf.placement.DEFAULT.log_dir }} {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.placement.api.internal "path" "/etc/placement/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_placement.volumeMounts }}{{ toYaml $mounts_placement.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: wsgi-placement emptyDir: {} - name: placement-bin configMap: name: placement-bin defaultMode: 0555 - name: placement-etc secret: secretName: placement-etc defaultMode: 0444 - name: placement-etc-snippets {{- if $etcSources }} projected: sources: {{ toYaml $etcSources | indent 14 }} {{- else }} emptyDir: {} {{ end }} {{- if .Values.conf.placement.DEFAULT.log_dir }} - name: log hostPath: path: {{ .Values.conf.placement.DEFAULT.log_dir }} type: DirectoryOrCreate {{- end }} {{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.placement.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_placement.volumes }}{{ toYaml $mounts_placement.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: placement/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: placement/templates/ingress.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.api.ingress.public }} {{- $envAll := . -}} {{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "placement" "backendPort" "p-api" -}} {{- $secretName := $envAll.Values.secrets.tls.placement.api.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.placement.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: placement/templates/job-db-drop.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $serviceName := "placement" -}} {{- $dbDropJob := dict "envAll" . "serviceName" $serviceName -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.placement.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: placement/templates/job-db-init.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $serviceName := "placement" -}} {{- $dbApi := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "placement_database" "configDbKey" "connection" -}} {{- $dbsToInit := list $dbApi }} {{- $dbInitJob := dict "envAll" . "serviceName" $serviceName "dbsToInit" $dbsToInit -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) -}} {{- if .Values.pod.tolerations.placement.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: placement/templates/job-db-sync.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "placement" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.placement.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: placement/templates/job-image-repo-sync.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "placement" -}} {{- $_ := set $imageRepoSyncJob "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.placement.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: placement/templates/job-ks-endpoints.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "1" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "placement" "serviceTypes" ( tuple "placement" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.placement.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) -}} {{- if .Values.pod.tolerations.placement.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: placement/templates/job-ks-service.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "placement" "serviceTypes" ( tuple "placement" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.placement.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) -}} {{- if .Values.pod.tolerations.placement.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: placement/templates/job-ks-user.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "placement" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.placement.api.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.placement.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: placement/templates/network_policy.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "placement" }} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: placement/templates/pdb.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: placement-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "placement" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: placement/templates/secret-db.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "placement" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: placement/templates/secret-ingress-tls.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "placement" ) }} {{- end }} ================================================ FILE: placement/templates/secret-keystone.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "placement" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: placement/templates/secret-ks-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ks_etc }} {{- $envAll := . -}} {{/* the endpoints.identity.auth sections with the oslo conf sections they get rendered to */}} {{- $ksUsers := dict "placement" "keystone_authtoken" -}} {{ dict "envAll" $envAll "serviceName" "placement" "serviceUserSections" $ksUsers | include "helm-toolkit.manifests.secret_ks_etc" }} {{- end }} ================================================ FILE: placement/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: placement/templates/service-ingress.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "placement" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: placement/templates/service.yaml ================================================ {{/* Copyright 2019 Intel Corporation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "placement" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: p-api port: {{ tuple "placement" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "placement" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: placement/values.yaml ================================================ # Copyright 2019 Intel Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for openstack-placement. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- release_group: null labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: pull_policy: IfNotPresent tags: placement: quay.io/airshipit/placement:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble placement_db_sync: quay.io/airshipit/placement:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 local_registry: active: false exclude: - dep_check - image_repo_sync network: api: port: 8778 ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30778 conf: policy: {} placement: DEFAULT: debug: false use_syslog: false log_config_append: /etc/placement/logging.conf placement_database: # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: service_token_roles: service service_token_roles_required: true auth_version: v3 auth_type: password memcache_security_strategy: ENCRYPT service_type: placement oslo_concurrency: lock_path: /var/lock logging: loggers: keys: - root - placement handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_placement: level: INFO handlers: - stdout qualname: placement logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" placement_api_uwsgi: uwsgi: processes: 1 add-header: "Connection: close" buffer-size: 65535 die-on-term: true enable-threads: true exit-on-reload: false hook-master-start: unix_signal:15 gracefully_kill_them_all lazy-apps: true log-x-forwarded-for: true master: true procname-prefix-spaced: "placement-api:" route-user-agent: '^kube-probe.* donotlog:' thunder-lock: true worker-reload-mercy: 80 wsgi-file: /var/lib/openstack/bin/placement-api stats: 0.0.0.0:1717 stats-http: true endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false placement: username: placement password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct placement: username: placement password: password # NOTE: This should be the username/password used to access the nova_api # database. This is required only if database migration from nova to # placement is desired. nova_api: username: nova password: password hosts: default: mariadb host_fqdn_override: default: null path: /placement scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default placement: role: admin region_name: RegionOne username: placement password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 placement: name: placement hosts: default: placement-api public: placement host_fqdn_override: default: null path: default: / scheme: default: 'http' service: 'http' port: api: default: 8778 public: 80 service: 8778 pod: security_context: placement: pod: runAsUser: 42424 container: placement_api: readOnlyRootFilesystem: false runAsUser: 0 placement_mysql_migration: readOnlyRootFilesystem: false runAsUser: 0 affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname tolerations: placement: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: placement: init_container: null placement: volumeMounts: volumes: placement_db_sync: init_container: null placement_db_sync: volumeMounts: volumes: # -- This allows users to add Kubernetes Projected Volumes to be mounted at /etc/placement/placement.conf.d/ ## This is a list of projected volume source objects for each deployment/statefulset/daemonset/cronjob ## https://kubernetes.io/docs/concepts/storage/projected-volumes/ etcSources: placement: [] placement_db_sync: [] replicas: api: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" probes: placement: api: liveness: port: 1717 secrets: identity: admin: placement-keystone-admin placement: placement-keystone-user oslo_db: admin: placement-db-admin placement: placement-db-user tls: placement: api: public: placement-tls-public internal: placement-tls-api oci_image_registry: placement: placement-oci-image-registry dependencies: dynamic: common: local_image_registry: jobs: - image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - placement-db-sync - placement-ks-service - placement-ks-user - placement-ks-endpoints ks_endpoints: jobs: - placement-ks-user - placement-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - placement-db-init services: - endpoint: internal service: oslo_db tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false configmap_bin: true configmap_etc: true deployment: true job_image_repo_sync: true job_db_init: true job_db_sync: true job_db_drop: false job_ks_endpoints: true job_ks_service: true job_ks_user: true network_policy: false secret_db: true secret_ingress_tls: true secret_registry: true pdb: true ingress: true secret_keystone: true secret_ks_etc: true service_ingress: true service: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: playbooks/build-chart.yaml ================================================ --- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - hosts: all roles: - ensure-helm - ensure-chart-testing tasks: - name: Install reno pip: name: reno>=4.1.0 virtualenv: "{{ virtualenv }}" virtualenv_command: python3 -m venv - name: Get list of changed charts shell: "ct list-changed --target-branch master --since {{ zuul.oldrev | default('HEAD~1') }} --chart-dirs . 2>/dev/null" args: chdir: "{{ zuul.project.src_dir }}" register: changed_charts_output changed_when: false - name: Parse changed charts set_fact: changed_charts: "{{ changed_charts_output.stdout_lines }}" - name: Display changed charts debug: msg: "Changed charts: {{ changed_charts }}" - name: Build each changed chart make: chdir: "{{ zuul.project.src_dir }}" target: "{{ item }}" params: PYTHON: "{{ virtualenv }}/bin/python" BASE_VERSION: "{{ base_version }}" loop: "{{ changed_charts }}" when: changed_charts | length > 0 - name: Move chart packages to subdirectories shell: | mkdir -p {{ zuul.project.src_dir }}/{{ item }} mv {{ zuul.project.src_dir }}/{{ item }}-*.tgz {{ zuul.project.src_dir }}/{{ item }}/ loop: "{{ changed_charts }}" when: changed_charts | length > 0 ... ================================================ FILE: playbooks/collect-logs.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - hosts: all vars: work_dir: "{{ zuul.project.src_dir }}" logs_dir: "/tmp/logs" roles: - gather-host-logs - hosts: primary vars: work_dir: "{{ zuul.project.src_dir }}" logs_dir: "/tmp/logs" roles: - helm-release-status - describe-kubernetes-objects - gather-pod-logs - gather-prom-metrics - gather-selenium-data ... ================================================ FILE: playbooks/deploy-env-kubespray.yaml ================================================ --- - hosts: all become: true gather_facts: true tasks: - name: Install prerequisites include_role: name: deploy-env tasks_from: prerequisites - name: Create loopback devices include_role: name: deploy-env tasks_from: loopback_devices when: - loopback_setup - inventory_hostname in (groups['k8s_cluster'] | default([])) - hosts: primary become: false gather_facts: true vars: home_dir: /home/zuul ansible_user: zuul tasks: - name: Clone Kubespray repo shell: | set -x git clone https://github.com/kubernetes-sigs/kubespray.git cd kubespray git checkout -b release-2.25 git reset --hard v2.25.0 args: chdir: "{{ home_dir }}" - name: Install Kubespray Python dependencies become: true pip: chdir: "{{ home_dir }}/kubespray" requirements: requirements.txt - name: Prepare Kubespray inventory (not Zuul job inventory) shell: | #!/bin/bash set -x python3 contrib/inventory_builder/inventory.py {{ groups['k8s_cluster'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(' ') }} args: chdir: "{{ home_dir }}/kubespray" environment: KUBE_MASTERS: "1" - name: Prepare Kubespray variables shell: | #!/bin/bash set -x tee inventory/sample/group_vars/all/xxx.yaml <- {% raw %}{{ ansible_hostname }}{% endraw %} EOF args: chdir: "{{ home_dir }}/kubespray" - name: Deploy Kubernetes shell: | #!/bin/bash set -x ansible-playbook -i inventory/sample/hosts.yaml --become --become-user=root cluster.yml args: chdir: /home/zuul/kubespray - name: Copy kubectl config to localhost (will be used in the following tasks) synchronize: mode: pull src: /home/zuul/kubespray/inventory/sample/artifacts/admin.conf dest: /tmp/kube_config - hosts: primary become: true gather_facts: true tasks: - name: Install Docker include_role: name: deploy-env tasks_from: containerd - name: Install and configure Kubectl and Helm include_role: name: deploy-env tasks_from: k8s_client - name: Deploy Metallb on K8s include_role: name: deploy-env tasks_from: metallb - name: Create Openstack Metallb endpoint include_role: name: deploy-env tasks_from: openstack_metallb_endpoint - hosts: all become: true gather_facts: true tasks: - name: Create client-to-cluster wireguard tunnel include_role: name: deploy-env tasks_from: client_cluster_tunnel - name: Install Docker include_role: name: deploy-env tasks_from: containerd when: - openstack_provider_gateway_setup - inventory_hostname in (groups['k8s_control_plane'] | default([])) - name: Deploy Openstack provider gateway include_role: name: deploy-env tasks_from: openstack_provider_gateway when: - openstack_provider_gateway_setup - inventory_hostname in (groups['k8s_control_plane'] | default([])) ... ================================================ FILE: playbooks/deploy-env.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - hosts: all strategy: linear become: true gather_facts: true roles: - ensure-python - ensure-pip - clear-firewall - deploy-apparmor - deploy-selenium - deploy-env ... ================================================ FILE: playbooks/enable-hugepages.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - hosts: all gather_facts: True become: yes roles: - role: enable-hugepages when: hugepages.enabled|default(false)|bool == true ... ================================================ FILE: playbooks/inject-keys.yaml ================================================ --- - hosts: all tasks: - name: Put keys to .ssh/authorized_keys lineinfile: path: /home/zuul/.ssh/authorized_keys state: present line: "{{ item }}" loop: - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN9wbA25JdmVAKqiO78/1P97r4ctR1tH3MLelByCj8wC vlad@russell" ... ================================================ FILE: playbooks/lint.yaml ================================================ --- # Copyright 2018 SUSE LINUX GmbH. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - hosts: all roles: - ensure-python - ensure-pip - ensure-helm - ensure-chart-testing - name: chart-testing chart_testing_options: "--target-branch=master --chart-dirs=. --validate-maintainers=false --check-version-increment=false" zuul_work_dir: "{{ work_dir }}" vars: work_dir: "{{ zuul.project.src_dir }}" tasks: - name: Install yamllint pip: name: - yq - yamllint virtualenv: "{{ virtualenv }}" virtualenv_command: python3 -m venv - name: Run yamllint shell: | cat > /tmp/yamllint.sh <&1 > /dev/null done find .yamllint -type f -exec sed -i 's/%%%.*/XXX/g' {} + shopt -s globstar extglob # Lint all yaml files except templates yamllint -c yamllint.conf .yamllint/*{,/!(templates)/**}/*.y*ml yamllint*.conf # Lint templates yamllint -c yamllint-templates.conf .yamllint/*/templates/*.yaml EOF chmod +x /tmp/yamllint.sh /tmp/yamllint.sh args: chdir: "{{ work_dir }}" executable: /bin/bash ... ================================================ FILE: playbooks/mount-volumes.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - hosts: all roles: - mount-extra-volume ... ================================================ FILE: playbooks/osh-bandit.yaml ================================================ --- - hosts: primary roles: - ensure-python - ensure-pip - osh-bandit ... ================================================ FILE: playbooks/prepare-hosts.yaml ================================================ --- - hosts: all roles: - ensure-python - ensure-pip - clear-firewall ... ================================================ FILE: playbooks/publish/post.yaml ================================================ --- # Copyright 2020 VEXXHOST, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - hosts: all tasks: - name: Get list of changed charts shell: "ct list-changed --target-branch master --since {{ zuul.oldrev | default('HEAD~1') }} --chart-dirs . 2>/dev/null" args: chdir: "{{ zuul.project.src_dir }}" register: changed_charts_output changed_when: false - name: Parse changed charts set_fact: changed_charts: "{{ changed_charts_output.stdout_lines }}" - name: Display changed charts debug: msg: "Changed charts to publish: {{ changed_charts }}" - name: Download current index register: _get_url failed_when: _get_url.status_code not in (200, 404) get_url: url: "https://tarballs.opendev.org/{{ zuul.project.name }}/index.yaml" dest: "{{ zuul.project.src_dir }}/index.yaml" - name: Create a new index when: _get_url.status_code == 404 shell: helm repo index {{ zuul.project.src_dir }} --url https://tarballs.opendev.org/{{ zuul.project.name }} - name: Merge into existing index when: _get_url.status_code == 200 shell: helm repo index {{ zuul.project.src_dir }} --merge {{ zuul.project.src_dir }}/index.yaml --url https://tarballs.opendev.org/{{ zuul.project.name }} - name: Cat updated index shell: cat {{ zuul.project.src_dir }}/index.yaml register: index_content changed_when: false - name: Display updated index debug: msg: "{{ index_content.stdout }}" - name: Ensure artifact directory exists file: path: "{{ zuul.executor.work_root }}/artifacts/" state: directory delegate_to: localhost - name: Ensure chart subdirectories exist in artifacts file: path: "{{ zuul.executor.work_root }}/artifacts/{{ item }}" state: directory delegate_to: localhost loop: "{{ changed_charts }}" when: changed_charts | length > 0 - name: Gather packaged charts from changed chart directories find: file_type: file paths: "{{ zuul.project.src_dir }}" patterns: "{{ item }}-*.tgz" recurse: true register: chart_packages loop: "{{ changed_charts }}" when: changed_charts | length > 0 - name: Display chart tarballs to be published debug: msg: "src: {{ item.1.path }} dest: {{ zuul.executor.work_root }}/artifacts/{{ item.0.item }}/" loop: "{{ chart_packages.results | subelements('files', skip_missing=True) }}" when: changed_charts | length > 0 - name: Copy packaged charts to artifacts preserving directory structure synchronize: mode: pull src: "{{ item.1.path }}" dest: "{{ zuul.executor.work_root }}/artifacts/{{ item.0.item }}/" verify_host: true owner: no group: no loop: "{{ chart_packages.results | subelements('files', skip_missing=True) }}" when: changed_charts | length > 0 - name: Copy index.yaml to artifacts synchronize: mode: pull src: "{{ zuul.project.src_dir }}/index.yaml" dest: "{{ zuul.executor.work_root }}/artifacts/" verify_host: true owner: no group: no ... ================================================ FILE: playbooks/publish/run.yaml ================================================ --- # Copyright 2020 VEXXHOST, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - hosts: all roles: - name: build-helm-packages work_dir: "{{ zuul.project.src_dir }}" ... ================================================ FILE: playbooks/run-scripts.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - hosts: all become: true tasks: - name: Configure /etc/hosts for buildset_registry to workaround docker not understanding ipv6 addresses lineinfile: path: /etc/hosts state: present regex: "^{{ buildset_registry.host }}\tzuul-jobs.buildset-registry$" line: "{{ buildset_registry.host }}\tzuul-jobs.buildset-registry" insertafter: EOF when: - buildset_registry is defined - buildset_registry.host | ipaddr - hosts: primary tasks: - name: Override images when: buildset_registry is defined vars: work_dir: "{{ zuul.project.src_dir }}" block: - name: Set buildset_registry alias variable when using ip set_fact: buildset_registry_alias: zuul-jobs.buildset-registry when: - buildset_registry.host | ipaddr - name: Set buildset_registry alias variable when using name set_fact: buildset_registry_alias: "{{ buildset_registry.host }}" when: - not ( buildset_registry.host | ipaddr ) - name: Print zuul debug: var: zuul - name: Override proposed images from artifacts shell: > set -ex; find {{ override_paths | join(" ") }} -type f -exec sed -Ei "s#['\"]?(docker|quay)\.io/(openstackhelm|loci|airshipit)/({{ repo }}):({{ tag }})['\"]?\$#{{ buildset_registry_alias }}:{{ buildset_registry.port }}/{{ repo_org }}/{{ repo }}:\4#g" {} + loop: "{{ zuul.artifacts | default([]) }}" args: chdir: "{{ work_dir }}" loop_control: loop_var: zj_zuul_artifact when: "'metadata' in zj_zuul_artifact and zj_zuul_artifact.metadata.type | default('') == 'container_image'" vars: tag: "{{ zj_zuul_artifact.metadata.tag }}" repo_org: "{{ zj_zuul_artifact.metadata.repository | dirname }}" repo: "{{ zj_zuul_artifact.metadata.repository | basename }}" override_paths: - ../openstack-helm/values_overrides - ../openstack-helm/*/values* - ../openstack-helm/tools/deployment/ - name: Diff shell: | set -ex cd "{{ work_dir }}/../openstack-helm" git diff - name: "creating directory for run artifacts" file: path: "/tmp/artifacts" state: directory # NOTE: After switching to Ansible 2.11 then xtrace stopped working # for shell tasks in included roles. So instead of using # osh-run-script-* roles we directly run the scripts in the # playbook. - name: "Run script {{ item }}" shell: | set -xe env {{ item }} args: chdir: "{{ zuul.project.src_dir }}/{{ gate_scripts_relative_path }}" executable: /bin/bash environment: CEPH_OSD_DATA_DEVICE: "{{ ceph_osd_data_device }}" POD_NETWORK_CIDR: "{{ kubeadm.pod_network_cidr }}" zuul_site_mirror_fqdn: "{{ zuul_site_mirror_fqdn }}" OSH_EXTRA_HELM_ARGS: "{{ zuul_osh_extra_helm_args | default('') }}" OSH_HELM_REPO: "{{ osh_helm_repo | default('../openstack-helm') }}" DOWNLOAD_OVERRIDES: "{{ download_overrides | default('') }}" OSH_PATH: "{{ zuul_osh_relative_path | default('../openstack-helm/') }}" OSH_VALUES_OVERRIDES_PATH: "{{ osh_values_overrides_path }}" OPENSTACK_RELEASE: "{{ osh_params.openstack_release | default('') }}" CONTAINER_DISTRO_NAME: "{{ osh_params.container_distro_name | default('') }}" CONTAINER_DISTRO_VERSION: "{{ osh_params.container_distro_version | default('') }}" FEATURES: "{{ osh_params.feature_gates | default('') | regex_replace(',', ' ') }} {{ osh_params.openstack_release | default('') }} {{ osh_params.container_distro_name | default('') }}_{{ osh_params.container_distro_version | default('') }} {{ osh_params.container_distro_name | default('') }}" RUN_HELM_TESTS: "{{ run_helm_tests | default('yes') }}" loop: "{{ gate_scripts }}" - name: "Downloads artifacts to executor" synchronize: src: "/tmp/artifacts" dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}" mode: pull ignore_errors: True ... ================================================ FILE: postgresql/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *~ # Various IDEs .project .idea/ *.tmproj ================================================ FILE: postgresql/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v14.5 description: OpenStack-Helm PostgreSQL name: postgresql version: 2025.2.0 home: https://www.postgresql.org sources: - https://github.com/postgres/postgres - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: postgresql/templates/bin/_backup_postgresql.sh.tpl ================================================ #!/bin/bash SCOPE=${1:-"all"} # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # This is needed to get the postgresql admin password # Turn off tracing so the password doesn't get printed. set +x export PGPASSWORD=$(cat /etc/postgresql/admin_user.conf \ | grep postgres | awk -F: '{print $5}') # Note: not using set -e in this script because more elaborate error handling # is needed. source /tmp/backup_main.sh # Export the variables required by the framework # Note: REMOTE_BACKUP_ENABLED and CONTAINER_NAME are already exported export DB_NAMESPACE=${POSTGRESQL_POD_NAMESPACE} export DB_NAME="postgres" export LOCAL_DAYS_TO_KEEP=$POSTGRESQL_LOCAL_BACKUP_DAYS_TO_KEEP export REMOTE_DAYS_TO_KEEP=$POSTGRESQL_REMOTE_BACKUP_DAYS_TO_KEEP export REMOTE_BACKUP_RETRIES=${NUMBER_OF_RETRIES_SEND_BACKUP_TO_REMOTE} export MIN_DELAY_SEND_REMOTE=${MIN_DELAY_SEND_BACKUP_TO_REMOTE} export MAX_DELAY_SEND_REMOTE=${MAX_DELAY_SEND_BACKUP_TO_REMOTE} export ARCHIVE_DIR=${POSTGRESQL_BACKUP_BASE_DIR}/db/${DB_NAMESPACE}/${DB_NAME}/archive # This function dumps all database files to the $TMP_DIR that is being # used as a staging area for preparing the backup tarball. Log file to # write to is passed in - the framework will expect that file to have any # errors that occur if the database dump is unsuccessful, so that it can # add the file contents to its own logs. dump_databases_to_directory() { TMP_DIR=$1 LOG_FILE=$2 SCOPE=${3:-"all"} PG_DUMP_OPTIONS=$(echo $POSTGRESQL_BACKUP_PG_DUMPALL_OPTIONS | sed 's/"//g') PG_DUMP="pg_dump \ $PG_DUMP_OPTIONS --create \ -U $POSTGRESQL_ADMIN_USER \ -h $POSTGRESQL_SERVICE_HOST" PG_DUMPALL="pg_dumpall \ $PG_DUMP_OPTIONS \ -U $POSTGRESQL_ADMIN_USER \ -h $POSTGRESQL_SERVICE_HOST" SQL_FILE=postgres.${POSTGRESQL_POD_NAMESPACE}.${SCOPE} cd $TMP_DIR if [[ "${SCOPE}" == "all" ]]; then # Dump all databases ${PG_DUMPALL} --file=${TMP_DIR}/${SQL_FILE}.sql 2>>${LOG_FILE} else if [[ "${SCOPE}" != "postgres" && "${SCOPE}" != "template0" && "${SCOPE}" != "template1" ]]; then # Dump the specified database ${PG_DUMP} --file=${TMP_DIR}/${SQL_FILE}.sql ${SCOPE} 2>>${LOG_FILE} else log ERROR "It is not allowed to backup up the ${SCOPE} database." return 1 fi fi if [[ $? -eq 0 && -s "${TMP_DIR}/${SQL_FILE}.sql" ]]; then log INFO postgresql_backup "Database(s) dumped successfully. (SCOPE = ${SCOPE})" return 0 else log ERROR "Backup of the postgresql database(s) failed and needs attention. (SCOPE = ${SCOPE})" return 1 fi } # Verify all the databases backup archives verify_databases_backup_archives() { #################################### # TODO: add implementation of local backup verification #################################### return 0 } # Call main program to start the database backup backup_databases ${SCOPE} ================================================ FILE: postgresql/templates/bin/_common_backup_restore.sh.tpl ================================================ #!/bin/bash # Copyright 2018 The Openstack-Helm Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # Do not use set -x here because the manual backup or restore pods may be using # these functions, and it will distort the command output to have tracing on. log_backup_error_exit() { MSG=$1 ERRCODE=$2 log ERROR postgresql_backup "${MSG}" exit $ERRCODE } log() { #Log message to a file or stdout #TODO: This can be convert into mail alert of alert send to a monitoring system #Params: $1 log level #Params: $2 service #Params: $3 message #Params: $4 Destination LEVEL=$1 SERVICE=$2 MSG=$3 DEST=$4 DATE=$(date +"%m-%d-%y %H:%M:%S") if [ -z "$DEST" ] then echo "${DATE} ${LEVEL}: $(hostname) ${SERVICE}: ${MSG}" else echo "${DATE} ${LEVEL}: $(hostname) ${SERVICE}: ${MSG}" >>$DEST fi } #Get the day delta since the archive file backup seconds_difference() { archive_date=$( date --date="$1" +%s ) if [ "$?" -ne 0 ] then second_delta=0 fi current_date=$( date +%s ) second_delta=$(($current_date-$archive_date)) if [ "$second_delta" -lt 0 ] then second_delta=0 fi echo $second_delta } # Wait for a file to be available on the file system (written by the other # container). wait_for_file() { WAIT_FILE=$1 NO_TIMEOUT=${2:-false} TIMEOUT=300 if [[ $NO_TIMEOUT == "true" ]] then # Such a large value to virtually never timeout TIMEOUT=999999999 fi TIMEOUT_EXP=$(( $(date +%s) + $TIMEOUT )) DONE=false while [[ $DONE == "false" ]] do DELTA=$(( TIMEOUT_EXP - $(date +%s) )) if [[ "$(ls -l ${WAIT_FILE} 2>/dev/null | wc -l)" -gt 0 ]]; then DONE=true elif [[ $DELTA -lt 0 ]] then DONE=true echo "Timed out waiting for file ${WAIT_FILE}." return 1 else echo "Still waiting ...will time out in ${DELTA} seconds..." sleep 5 fi done return 0 } ================================================ FILE: postgresql/templates/bin/_db_test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex trap cleanup EXIT SIGTERM SIGINT SIGKILL TEST_DATABASE_NAME="pg_helmtest_db" TEST_DATABASE_USER="pg_helmtest_user" TEST_DATABASE_PASSWORD=$RANDOM TEST_TABLE_NAME="pg_helmtest" function psql_cmd { DATABASE=$1 DB_USER=$2 export PGPASSWORD=$3 DB_COMMAND=$4 EXIT_ON_FAIL=${5:-1} psql \ -h $DB_FQDN \ -p $DB_PORT \ -U $DB_USER \ -d $DATABASE \ -v "ON_ERROR_STOP=1" \ --command="${DB_COMMAND}" RC=$? if [[ $RC -ne 0 ]] then echo 'FAIL!' if [[ $EXIT_ON_FAIL -eq 1 ]] then exit $RC fi fi return 0 } function cleanup { echo 'Cleaning up the database...' psql_cmd "postgres" ${DB_ADMIN_USER} ${ADMIN_PASSWORD} "DROP DATABASE IF EXISTS ${TEST_DATABASE_NAME};" 0 psql_cmd "postgres" ${DB_ADMIN_USER} ${ADMIN_PASSWORD} "DROP ROLE IF EXISTS ${TEST_DATABASE_USER};" 0 echo 'Cleanup Finished.' } # Create db echo 'Testing database connectivity as admin user...' psql_cmd "postgres" ${DB_ADMIN_USER} ${ADMIN_PASSWORD} "SELECT 1 FROM pg_database;" echo 'Connectivity Test SUCCESS!' echo 'Testing creation of an application database...' psql_cmd "postgres" ${DB_ADMIN_USER} ${ADMIN_PASSWORD} "CREATE DATABASE ${TEST_DATABASE_NAME};" echo 'Database Creation Test SUCCESS!' echo 'Testing creation of an application user...' psql_cmd "postgres" ${DB_ADMIN_USER} ${ADMIN_PASSWORD} "CREATE ROLE ${TEST_DATABASE_USER} LOGIN PASSWORD '${TEST_DATABASE_PASSWORD}';" psql_cmd "postgres" ${DB_ADMIN_USER} ${ADMIN_PASSWORD} "GRANT ALL PRIVILEGES ON DATABASE ${TEST_DATABASE_NAME} to ${TEST_DATABASE_USER};" echo 'User Creation SUCCESS!' echo 'Testing creation of an application table...' psql_cmd ${TEST_DATABASE_NAME} ${TEST_DATABASE_USER} ${TEST_DATABASE_PASSWORD} "CREATE TABLE ${TEST_TABLE_NAME} (name text);" echo 'Table Creation SUCCESS!' echo 'Testing DML...' psql_cmd ${TEST_DATABASE_NAME} ${TEST_DATABASE_USER} ${TEST_DATABASE_PASSWORD} "INSERT INTO ${TEST_TABLE_NAME} (name) VALUES ('test.');" psql_cmd ${TEST_DATABASE_NAME} ${TEST_DATABASE_USER} ${TEST_DATABASE_PASSWORD} "SELECT * FROM ${TEST_TABLE_NAME};" psql_cmd ${TEST_DATABASE_NAME} ${TEST_DATABASE_USER} ${TEST_DATABASE_PASSWORD} "DELETE FROM ${TEST_TABLE_NAME};" echo 'DML Test SUCCESS!' exit 0 ================================================ FILE: postgresql/templates/bin/_postgresql_archive_cleanup.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set +ex # ARCHIVE_LIMIT env variable is Threshold of archiving supposed to be kept in percentage clean_up () { echo "Cleanup required as Utilization is above threshold" # Get file count and delete half of the archive while maintaining the order of the files FILE_COUNT=$(ls -1 ${ARCHIVE_PATH} | sort | wc -l) COUNT=0 echo $((FILE_COUNT/2)) for file in $(ls -1 ${ARCHIVE_PATH} | sort); do if [[ $COUNT -lt $((FILE_COUNT/2)) ]]; then echo "removing following file $file" rm -rf ${ARCHIVE_PATH}/$file else break fi COUNT=$((COUNT+1)) done } #infinite loop to check the utilization of archive while true do # checking the utilization of archive directory UTILIZATION=$(df -h ${ARCHIVE_PATH} | awk ' NR==2 {print $5} ' | awk '{ print substr( $0, 1, length($0)-1 ) }') if [[ $UTILIZATION -gt ${ARCHIVE_LIMIT} ]]; then clean_up fi sleep 3600 done ================================================ FILE: postgresql/templates/bin/_readiness.sh.tpl ================================================ #!/usr/bin/env bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex pg_isready -U ${POSTGRES_USER} ================================================ FILE: postgresql/templates/bin/_remote_retrieve_postgresql.sh.tpl ================================================ #!/bin/bash # Copyright 2018 The Openstack-Helm Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -x RESTORE_DIR=${POSTGRESQL_BACKUP_BASE_DIR}/db/${POSTGRESQL_POD_NAMESPACE}/postgres/restore ARCHIVE_DIR=${POSTGRESQL_BACKUP_BASE_DIR}/db/${POSTGRESQL_POD_NAMESPACE}/postgres/archive source /tmp/common_backup_restore.sh # Keep processing requests for the life of the pod. while true do # Wait until a restore request file is present on the disk echo "Waiting for a restore request..." NO_TIMEOUT=true wait_for_file $RESTORE_DIR/*_request $NO_TIMEOUT echo "Done waiting. Request received" CONTAINER_NAME={{ .Values.conf.backup.remote_backup.container_name }} if [[ -e $RESTORE_DIR/archive_listing_request ]] then # We've finished consuming the request, so delete the request file. rm -rf $RESTORE_DIR/*_request openstack container show $CONTAINER_NAME if [[ $? -eq 0 ]] then # Get the list, ensureing that we only pick up postgres backups from the # requested namespace openstack object list $CONTAINER_NAME | grep postgres | grep $POSTGRESQL_POD_NAMESPACE | awk '{print $2}' > $RESTORE_DIR/archive_list_response if [[ $? != 0 ]] then echo "Container object listing could not be obtained." >> $RESTORE_DIR/archive_list_error else echo "Archive listing successfully retrieved." fi else echo "Container $CONTAINER_NAME does not exist." >> $RESTORE_DIR/archive_list_error fi elif [[ -e $RESTORE_DIR/get_archive_request ]] then ARCHIVE=`cat $RESTORE_DIR/get_archive_request` echo "Request for archive $ARCHIVE received." # We've finished consuming the request, so delete the request file. rm -rf $RESTORE_DIR/*_request openstack object save --file $RESTORE_DIR/$ARCHIVE $CONTAINER_NAME $ARCHIVE if [[ $? != 0 ]] then echo "Archive $ARCHIVE could not be retrieved." >> $RESTORE_DIR/archive_error else echo "Archive $ARCHIVE successfully retrieved." fi # Signal to the other container that the archive is available. touch $RESTORE_DIR/archive_response else rm -rf $RESTORE_DIR/*_request echo "Invalid request received." fi sleep 5 done ================================================ FILE: postgresql/templates/bin/_remote_store_postgresql.sh.tpl ================================================ #!/bin/bash # Copyright 2018 The Openstack-Helm Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # Note: not using set -e because more elaborate error handling is required. set -x BACKUPS_DIR=${POSTGRESQL_BACKUP_BASE_DIR}/db/${POSTGRESQL_POD_NAMESPACE}/postgres/current # Create the working backups directory if the other container didn't already, # and if this container creates it first, ensure that permissions are writable # for the other container (running as "postgres" user) in the same "postgres" # group. mkdir -p $BACKUPS_DIR || log_backup_error_exit "Cannot create directory ${BACKUPS_DIR}!" 1 chmod 775 $BACKUPS_DIR source /tmp/common_backup_restore.sh #Send backup file to storage send_to_storage() { FILEPATH=$1 FILE=$2 CONTAINER_NAME={{ .Values.conf.backup.remote_backup.container_name }} # Grab the list of containers on the remote site RESULT=$(openstack container list 2>&1) if [[ $? == 0 ]] then echo $RESULT | grep $CONTAINER_NAME if [[ $? != 0 ]] then # Create the container openstack container create $CONTAINER_NAME || log ERROR postgresql_backup "Cannot create container ${CONTAINER_NAME}!" openstack container show $CONTAINER_NAME if [[ $? != 0 ]] then log ERROR postgresql_backup "Error retrieving container $CONTAINER_NAME after creation." return 1 fi fi else echo $RESULT | grep "HTTP 401" if [[ $? == 0 ]] then log ERROR postgresql_backup "Could not access keystone: HTTP 401" return 1 else echo $RESULT | grep "ConnectionError" if [[ $? == 0 ]] then log ERROR postgresql_backup "Could not access keystone: ConnectionError" # In this case, keystone or the site/node may be temporarily down. # Return slightly different error code so the calling code can retry return 2 else log ERROR postgresql_backup "Could not get container list: ${RESULT}" return 1 fi fi fi # Create an object to store the file openstack object create --name $FILE $CONTAINER_NAME $FILEPATH/$FILE || log ERROR postgresql_backup "Cannot create container object ${FILE}!" openstack object show $CONTAINER_NAME $FILE if [[ $? != 0 ]] then log ERROR postgresql_backup "Error retrieving container object $FILE after creation." return 1 fi log INFO postgresql_backup "Created file $FILE in container $CONTAINER_NAME successfully." return 0 } if {{ .Values.conf.backup.remote_backup.enabled }} then WAIT_FOR_BACKUP_TIMEOUT=1800 WAIT_FOR_RGW_AVAIL_TIMEOUT=1800 # Wait until a backup file is ready to ship to RGW, or until we time out. DONE=false TIMEOUT_EXP=$(( $(date +%s) + $WAIT_FOR_BACKUP_TIMEOUT )) while [[ $DONE == "false" ]] do log INFO postgresql_backup "Waiting for a backup file to be written to the disk." sleep 5 DELTA=$(( TIMEOUT_EXP - $(date +%s) )) ls -l ${BACKUPS_DIR}/backup_completed if [[ $? -eq 0 ]] then DONE=true elif [[ $DELTA -lt 0 ]] then DONE=true fi done log INFO postgresql_backup "Done waiting." FILE_TO_SEND=$(ls $BACKUPS_DIR/*.tar.gz) ERROR_SEEN=false if [[ $FILE_TO_SEND != "" ]] then if [[ $(echo $FILE_TO_SEND | wc -w) -gt 1 ]] then # There should only be one backup file to send - this is an error log_backup_error_exit "More than one backup file found (${FILE_TO_SEND}) - can only handle 1!" 1 fi # Get just the filename from the file (strip the path) FILE=$(basename $FILE_TO_SEND) log INFO postgresql_backup "Backup file ${BACKUPS_DIR}/${FILE} found." DONE=false TIMEOUT_EXP=$(( $(date +%s) + $WAIT_FOR_RGW_AVAIL_TIMEOUT )) while [[ $DONE == "false" ]] do # Store the new archive to the remote backup storage facility. send_to_storage $BACKUPS_DIR $FILE # Check if successful if [[ $? -eq 0 ]] then log INFO postgresql_backup "Backup file ${BACKUPS_DIR}/${FILE} successfully sent to RGW. Deleting from current backup directory." DONE=true elif [[ $? -eq 2 ]] then # Temporary failure occurred. We need to retry if we haven't timed out log WARN postgresql_backup "Backup file ${BACKUPS_DIR}/${FILE} could not be sent to RGW due to connection issue." DELTA=$(( TIMEOUT_EXP - $(date +%s) )) if [[ $DELTA -lt 0 ]] then DONE=true log ERROR postgresql_backup "Timed out waiting for RGW to become available." ERROR_SEEN=true else log INFO postgresql_backup "Sleeping 30 seconds waiting for RGW to become available..." sleep 30 log INFO postgresql_backup "Retrying..." fi else log ERROR postgresql_backup "Backup file ${BACKUPS_DIR}/${FILE} could not be sent to the RGW." ERROR_SEEN=true DONE=true fi done else log ERROR postgresql_backup "No backup file found in $BACKUPS_DIR." ERROR_SEEN=true fi if [[ $ERROR_SEEN == "true" ]] then log ERROR postgresql_backup "Errors encountered. Exiting." exit 1 fi # At this point, we should remove the files in current dir. # If an error occurred, then we need the file to remain there for future # container restarts, and maybe it will eventually succeed. rm -rf $BACKUPS_DIR/* #Only delete an old archive after a successful archive if [ "${POSTGRESQL_BACKUP_DAYS_TO_KEEP}" -gt 0 ] then log INFO postgresql_backup "Deleting backups older than ${POSTGRESQL_BACKUP_DAYS_TO_KEEP} days" BACKUP_FILES=/tmp/backup_files PG_BACKUP_FILES=/tmp/pg_backup_files openstack object list $CONTAINER_NAME > $BACKUP_FILES if [[ $? != 0 ]] then log_backup_error_exit "Could not obtain a list of current backup files in the RGW" 1 fi # Filter out other types of files like mariadb, etcd backupes etc.. cat $BACKUP_FILES | grep postgres | grep $POSTGRESQL_POD_NAMESPACE | awk '{print $2}' > $PG_BACKUP_FILES for ARCHIVE_FILE in $(cat $PG_BACKUP_FILES) do ARCHIVE_DATE=$( echo $ARCHIVE_FILE | awk -F/ '{print $NF}' | cut -d'.' -f 4) if [ "$(seconds_difference ${ARCHIVE_DATE})" -gt "$((${POSTGRESQL_BACKUP_DAYS_TO_KEEP}*86400))" ] then log INFO postgresql_backup "Deleting file ${ARCHIVE_FILE} from the RGW" openstack object delete $CONTAINER_NAME $ARCHIVE_FILE || log_backup_error_exit "Cannot delete container object ${ARCHIVE_FILE}!" 1 fi done fi else log INFO postgresql_backup "Remote backup is not enabled" exit 0 fi ================================================ FILE: postgresql/templates/bin/_restore_postgresql.sh.tpl ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # Capture the user's command line arguments ARGS=("$@") # This is needed to get the postgresql admin password # Note: xtracing should be off so it doesn't print the pw export PGPASSWORD=$(cat /etc/postgresql/admin_user.conf \ | grep postgres | awk -F: '{print $5}') source /tmp/restore_main.sh # Export the variables needed by the framework export DB_NAME="postgres" export DB_NAMESPACE=${POSTGRESQL_POD_NAMESPACE} export ARCHIVE_DIR=${POSTGRESQL_BACKUP_BASE_DIR}/db/${DB_NAMESPACE}/${DB_NAME}/archive # Define variables needed in this file POSTGRESQL_HOST=$(cat /etc/postgresql/admin_user.conf | cut -d: -f 1) export PSQL="psql -U $POSTGRESQL_ADMIN_USER -h $POSTGRESQL_HOST" export LOG_FILE=/tmp/dbrestore.log # Extract all databases from an archive and put them in the requested # file. get_databases() { TMP_DIR=$1 DB_FILE=$2 SQL_FILE=$TMP_DIR/postgres.$POSTGRESQL_POD_NAMESPACE.*.sql if [ -f $SQL_FILE ]; then grep 'CREATE DATABASE' $SQL_FILE | awk '{ print $3 }' > $DB_FILE else # Error, cannot report the databases echo "No SQL file found - cannot extract the databases" return 1 fi } # Extract all tables of a database from an archive and put them in the requested # file. get_tables() { DATABASE=$1 TMP_DIR=$2 TABLE_FILE=$3 SQL_FILE=$TMP_DIR/postgres.$POSTGRESQL_POD_NAMESPACE.*.sql if [ -f $SQL_FILE ]; then cat $SQL_FILE | sed -n /'\\connect '$DATABASE/,/'\\connect'/p | grep "CREATE TABLE" | awk -F'[. ]' '{print $4}' > $TABLE_FILE else # Error, cannot report the tables echo "No SQL file found - cannot extract the tables" return 1 fi } # Extract all rows in the given table of a database from an archive and put them in the requested # file. get_rows() { DATABASE=$1 TABLE=$2 TMP_DIR=$3 ROW_FILE=$4 SQL_FILE=$TMP_DIR/postgres.$POSTGRESQL_POD_NAMESPACE.*.sql if [ -f $SQL_FILE ]; then cat $SQL_FILE | sed -n /'\\connect '${DATABASE}/,/'\\connect'/p > /tmp/db.sql cat /tmp/db.sql | grep "INSERT INTO public.${TABLE} VALUES" > $ROW_FILE rm /tmp/db.sql else # Error, cannot report the rows echo "No SQL file found - cannot extract the rows" return 1 fi } # Extract the schema for the given table in the given database belonging to the archive file # found in the TMP_DIR. get_schema() { DATABASE=$1 TABLE=$2 TMP_DIR=$3 SCHEMA_FILE=$4 SQL_FILE=$TMP_DIR/postgres.$POSTGRESQL_POD_NAMESPACE.*.sql if [ -f $SQL_FILE ]; then DB_FILE=$(mktemp -p /tmp) cat $SQL_FILE | sed -n /'\\connect '${DATABASE}/,/'\\connect'/p > ${DB_FILE} cat ${DB_FILE} | sed -n /'CREATE TABLE public.'${TABLE}' ('/,/'--'/p > ${SCHEMA_FILE} cat ${DB_FILE} | sed -n /'CREATE SEQUENCE public.'${TABLE}/,/'--'/p >> ${SCHEMA_FILE} cat ${DB_FILE} | sed -n /'ALTER TABLE public.'${TABLE}/,/'--'/p >> ${SCHEMA_FILE} cat ${DB_FILE} | sed -n /'ALTER TABLE ONLY public.'${TABLE}/,/'--'/p >> ${SCHEMA_FILE} cat ${DB_FILE} | sed -n /'ALTER SEQUENCE public.'${TABLE}/,/'--'/p >> ${SCHEMA_FILE} cat ${DB_FILE} | sed -n /'SELECT pg_catalog.*public.'${TABLE}/,/'--'/p >> ${SCHEMA_FILE} cat ${DB_FILE} | sed -n /'CREATE INDEX.*public.'${TABLE}' USING'/,/'--'/p >> ${SCHEMA_FILE} cat ${DB_FILE} | sed -n /'GRANT.*public.'${TABLE}' TO'/,/'--'/p >> ${SCHEMA_FILE} rm -f ${DB_FILE} else # Error, cannot report the rows echo "No SQL file found - cannot extract the schema" return 1 fi } # Extract Single Database SQL Dump from pg_dumpall dump file extract_single_db_dump() { ARCHIVE=$1 DATABASE=$2 DIR=$3 sed -n '/\\connect'" ${DATABASE}/,/PostgreSQL database dump complete/p" ${ARCHIVE} > ${DIR}/${DATABASE}.sql } # Re-enable connections to a database reenable_connections() { SINGLE_DB_NAME=$1 # First make sure this is not the main postgres database or either of the # two template databases that should not be touched. if [[ ${SINGLE_DB_NAME} == "postgres" || ${SINGLE_DB_NAME} == "template0" || ${SINGLE_DB_NAME} == "template1" ]]; then echo "Cannot re-enable connections on an postgres internal db ${SINGLE_DB_NAME}" return 1 fi # Re-enable connections to the DB $PSQL -tc "UPDATE pg_database SET datallowconn = 'true' WHERE datname = '${SINGLE_DB_NAME}';" > /dev/null 2>&1 if [[ "$?" -ne 0 ]]; then echo "Could not re-enable connections for database ${SINGLE_DB_NAME}" return 1 fi return 0 } # Drop connections from a database drop_connections() { SINGLE_DB_NAME=$1 # First make sure this is not the main postgres database or either of the # two template databases that should not be touched. if [[ ${SINGLE_DB_NAME} == "postgres" || ${SINGLE_DB_NAME} == "template0" || ${SINGLE_DB_NAME} == "template1" ]]; then echo "Cannot drop connections on an postgres internal db ${SINGLE_DB_NAME}" return 1 fi # First, prevent any new connections from happening on this database. $PSQL -tc "UPDATE pg_database SET datallowconn = 'false' WHERE datname = '${SINGLE_DB_NAME}';" > /dev/null 2>&1 if [[ "$?" -ne 0 ]]; then echo "Could not prevent new connections before restoring database ${SINGLE_DB_NAME}." return 1 fi # Next, force disconnection of all clients currently connected to this database. $PSQL -tc "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${SINGLE_DB_NAME}';" > /dev/null 2>&1 if [[ "$?" -ne 0 ]]; then echo "Could not drop existing connections before restoring database ${SINGLE_DB_NAME}." reenable_connections ${SINGLE_DB_NAME} return 1 fi return 0 } # Re-enable connections for all of the databases within Postgresql reenable_connections_on_all_dbs() { # Get a list of the databases DB_LIST=$($PSQL -tc "\l" | grep "| postgres |" | awk '{print $1}') RET=0 # Re-enable the connections for each of the databases. for DB in $DB_LIST; do if [[ ${DB} != "postgres" && ${DB} != "template0" && ${DB} != "template1" ]]; then reenable_connections $DB if [[ "$?" -ne 0 ]]; then RET=1 fi fi done return $RET } # Drop connections in all of the databases within Postgresql drop_connections_on_all_dbs() { # Get a list of the databases DB_LIST=$($PSQL -tc "\l" | grep "| postgres |" | awk '{print $1}') RET=0 # Drop the connections for each of the databases. for DB in $DB_LIST; do # Make sure this is not the main postgres database or either of the # two template databases that should not be touched. if [[ ${DB} != "postgres" && ${DB} != "template0" && ${DB} != "template1" ]]; then drop_connections $DB if [[ "$?" -ne 0 ]]; then RET=1 fi fi done # If there was a failure to drop any connections, go ahead and re-enable # them all to prevent a lock-out condition if [[ $RET -ne 0 ]]; then reenable_connections_on_all_dbs fi return $RET } # Restore a single database dump from pg_dumpall sql dumpfile. restore_single_db() { SINGLE_DB_NAME=$1 TMP_DIR=$2 # Reset the logfile incase there was some older log there rm -rf ${LOG_FILE} touch ${LOG_FILE} # First make sure this is not the main postgres database or either of the # two template databases that should not be touched. if [[ ${SINGLE_DB_NAME} == "postgres" || ${SINGLE_DB_NAME} == "template0" || ${SINGLE_DB_NAME} == "template1" ]]; then echo "Cannot restore an postgres internal db ${SINGLE_DB_NAME}" return 1 fi SQL_FILE=$TMP_DIR/postgres.$POSTGRESQL_POD_NAMESPACE.*.sql if [ -f $SQL_FILE ]; then extract_single_db_dump $SQL_FILE $SINGLE_DB_NAME $TMP_DIR if [[ -f $TMP_DIR/$SINGLE_DB_NAME.sql && -s $TMP_DIR/$SINGLE_DB_NAME.sql ]]; then # Drop connections first drop_connections ${SINGLE_DB_NAME} if [[ "$?" -ne 0 ]]; then return 1 fi # Next, drop the database $PSQL -tc "DROP DATABASE $SINGLE_DB_NAME;" if [[ "$?" -ne 0 ]]; then echo "Could not drop the old ${SINGLE_DB_NAME} database before restoring it." reenable_connections ${SINGLE_DB_NAME} return 1 fi # Postgresql does not have the concept of creating database if condition. # This next command creates the database in case it does not exist. $PSQL -tc "SELECT 1 FROM pg_database WHERE datname = '$SINGLE_DB_NAME'" | grep -q 1 || \ $PSQL -c "CREATE DATABASE $SINGLE_DB_NAME" if [[ "$?" -ne 0 ]]; then echo "Could not create the single database being restored: ${SINGLE_DB_NAME}." reenable_connections ${SINGLE_DB_NAME} return 1 fi $PSQL -d $SINGLE_DB_NAME -f ${TMP_DIR}/${SINGLE_DB_NAME}.sql 2>>$LOG_FILE >> $LOG_FILE if [[ "$?" -eq 0 ]]; then if grep "ERROR:" ${LOG_FILE} > /dev/null 2>&1; then cat $LOG_FILE echo "Errors occurred during the restore of database ${SINGLE_DB_NAME}" reenable_connections ${SINGLE_DB_NAME} return 1 else echo "Database restore Successful." fi else # Dump out the log file for debugging cat $LOG_FILE echo -e "\nDatabase restore Failed." reenable_connections ${SINGLE_DB_NAME} return 1 fi # Re-enable connections to the DB reenable_connections ${SINGLE_DB_NAME} if [[ "$?" -ne 0 ]]; then return 1 fi else echo "Database dump For $SINGLE_DB_NAME is empty or not available." return 1 fi else echo "No database file available to restore from." return 1 fi return 0 } # Restore all the databases from the pg_dumpall sql file. restore_all_dbs() { TMP_DIR=$1 # Reset the logfile incase there was some older log there rm -rf ${LOG_FILE} touch ${LOG_FILE} SQL_FILE=$TMP_DIR/postgres.$POSTGRESQL_POD_NAMESPACE.*.sql if [ -f $SQL_FILE ]; then # Check the scope of the archive. SCOPE=$(echo ${SQL_FILE} | awk -F'.' '{print $(NF-1)}') if [[ "${SCOPE}" != "all" ]]; then # This is just a single database backup. The user should # instead use the single database restore option. echo "Cannot use the restore all option for an archive containing only a single database." echo "Please use the single database restore option." return 1 fi # First drop all connections on all databases drop_connections_on_all_dbs if [[ "$?" -ne 0 ]]; then return 1 fi $PSQL postgres -f $SQL_FILE 2>>$LOG_FILE >> $LOG_FILE if [[ "$?" -eq 0 ]]; then if grep "ERROR:" ${LOG_FILE} > /dev/null 2>&1; then cat ${LOG_FILE} echo "Errors occurred during the restore of the databases." reenable_connections_on_all_dbs return 1 else echo "Database Restore Successful." fi else # Dump out the log file for debugging cat ${LOG_FILE} echo -e "\nDatabase Restore failed." reenable_connections_on_all_dbs return 1 fi # Re-enable connections on all databases reenable_connections_on_all_dbs if [[ "$?" -ne 0 ]]; then return 1 fi else echo "There is no database file available to restore from." return 1 fi return 0 } # Call the CLI interpreter, providing the archive directory path and the # user arguments passed in cli_main ${ARGS[@]} ================================================ FILE: postgresql/templates/bin/_start.sh.tpl ================================================ #!/usr/bin/env bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # Disable echo mode while setting the password # unless we are in debug mode {{- if .Values.conf.debug }} set -x {{- end }} set -e POSTGRES_DB=${POSTGRES_DB:-"postgres"} # Check if the Postgres data directory exists before attempting to # set the password if [[ -d "$PGDATA" && -s "$PGDATA/PG_VERSION" ]] then postgres --single -D "$PGDATA" "$POSTGRES_DB" < /var/lib/archive/%f' cluster_name: 'postgresql' datestyle: 'iso, mdy' external_pid_file: '/tmp/postgres.pid' fsync: 'on' listen_addresses: '0.0.0.0' log_checkpoints: 'on' log_connections: 'on' log_disconnections: 'on' log_line_prefix: 'postgresql: %t [%p]: [%l-1] %c %x %d %u %a %h %m ' log_lock_waits: 'on' log_temp_files: '0' log_timezone: 'UTC' max_connections: '1000' max_locks_per_transaction: '64' max_prepared_transactions: '0' max_wal_senders: '16' max_worker_processes: '10' port: '5432' shared_buffers: '2GB' ssl: 'off' ssl_cert_file: '/server_certs/tls.crt' ssl_ca_file: '/server_certs/ca.crt' ssl_key_file: '/server_certs/tls.key' ssl_ciphers: 'TLSv1.2:!aNULL' tcp_keepalives_idle: '900' tcp_keepalives_interval: '100' timezone: 'UTC' track_commit_timestamp: 'on' track_functions: 'all' wal_keep_size: '256' wal_level: 'hot_standby' wal_log_hints: 'on' hba_file: '/tmp/pg_hba.conf' ident_file: '/tmp/pg_ident.conf' backup: enabled: false base_path: /var/backup days_to_keep: 3 pg_dumpall_options: '--inserts --clean' remote_backup: enabled: false container_name: postgresql days_to_keep: 14 storage_policy: default-placement number_of_retries: 5 delay_range: min: 30 max: 60 throttle_backups: enabled: false sessions_limit: 480 lock_expire_after: 7200 retry_after: 3600 container_name: throttle-backups-manager primary_user_class: postgresql failover_user_class: postgresql_failover exporter: queries: pg_postmaster: query: "SELECT pg_postmaster_start_time as start_time_seconds from pg_postmaster_start_time()" master: true metrics: - start_time_seconds: usage: "GAUGE" description: "Time at which postmaster started" secrets: oci_image_registry: postgresql: postgresql-oci-image-registry-key postgresql: admin: postgresql-admin exporter: postgresql-exporter audit: postgresql-audit backup_restore: postgresql-backup-restore tls: server: internal: postgresql-tls-direct identity: admin: keystone-admin-user postgresql: postgresql-backup-user endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false postresql: username: postresql password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null postgresql: auth: admin: username: postgres password: password exporter: username: psql_exporter password: psql_exp_pass audit: username: audit password: password hosts: default: postgresql host_fqdn_override: default: null path: null scheme: postgresql port: postgresql: default: 5432 postgresql_restapi: hosts: default: postgresql-restapi host_fqdn_override: default: null path: null scheme: postgresql port: restapi: default: 8008 prometheus_postgresql_exporter: namespace: null hosts: default: postgresql-exporter host_fqdn_override: default: null path: default: /metrics scheme: default: 'http' port: metrics: default: 9187 identity: name: backup-storage-auth namespace: openstack auth: admin: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default postgresql: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null role: admin region_name: RegionOne username: postgresql-backup-user password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 manifests: certificates: false configmap_bin: true configmap_etc: true job_image_repo_sync: true network_policy: false job_ks_user: false secret_admin: true secret_etc: true secret_audit: true secret_backup_restore: false secret_registry: true service: true statefulset: true cron_job_postgresql_backup: false pvc_backup: false monitoring: prometheus: configmap_bin: true configmap_etc: true deployment_exporter: true job_user_create: true secret_etc: true service_exporter: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: powerdns/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v4.1.10 description: OpenStack-Helm PowerDNS name: powerdns version: 2025.2.0 home: https://www.powerdns.com/ maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: powerdns/templates/bin/_powerdns-mysql-sync.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex MYSQLCMD='mysql -r -N' if [ $(echo 'show tables' | $MYSQLCMD | wc -c) -eq 0 ]; then $MYSQLCMD < /etc/pdns/schema.sql fi ================================================ FILE: powerdns/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: powerdns-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} powerdns-mysql-sync.sh: | {{ tuple "bin/_powerdns-mysql-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: powerdns/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "powerdns.configmap.etc" -}} {{- range $key, $value := . }} {{ $key | replace "_" "-" }} = {{ $value }} {{- end }} {{- end -}} {{- if .Values.manifests.configmap_etc }} {{- $mysql := .Values.conf.mysql.client }} {{- if empty $mysql.host -}} {{- $_ := tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.endpoint_host_lookup" | set $mysql "host" -}} {{- $_ := $mysql.host | set .Values.conf.powerdns "gmysql_host" -}} {{- end -}} {{- if empty $mysql.port -}} {{- $_ := tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $mysql "port" -}} {{- $_ := $mysql.port | set .Values.conf.powerdns "gmysql_port" -}} {{- end -}} {{- if empty $mysql.user -}} {{- $_ := .Values.endpoints.oslo_db.auth.powerdns.username | set $mysql "user" -}} {{- $_ := $mysql.user | set .Values.conf.powerdns "gmysql_user" -}} {{- end -}} {{- if empty $mysql.password -}} {{- $_ := .Values.endpoints.oslo_db.auth.powerdns.password | set $mysql "password" -}} {{- $_ := $mysql.password | set .Values.conf.powerdns "gmysql_password" -}} {{- end -}} {{- if empty .Values.conf.powerdns.api_key -}} {{- $_ := tuple "powerdns" "service" . | include "helm-toolkit.endpoints.endpoint_token_lookup" | set .Values.conf.powerdns "api_key" -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: powerdns-etc type: Opaque data: pdns.conf: {{ include "powerdns.configmap.etc" .Values.conf.powerdns | b64enc }} my.cnf: {{ include "helm-toolkit.utils.to_ini" .Values.conf.mysql | b64enc }} {{- end }} ================================================ FILE: powerdns/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $serviceAccountName := "powerdns" }} {{ tuple $envAll "powerdns" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: powerdns annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "powerdns" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.server }} selector: matchLabels: {{ tuple $envAll "powerdns" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "powerdns" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "powerdns" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.powerdns.node_selector_key }}: {{ .Values.labels.powerdns.node_selector_value | quote }} initContainers: {{ tuple $envAll "powerdns" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: powerdns {{ tuple $envAll "powerdns" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - pdns_server ports: - containerPort: {{ tuple "powerdns" "internal" "powerdns" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: pdns-udp protocol: UDP - containerPort: {{ tuple "powerdns" "internal" "powerdns_tcp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: pdns-tcp - containerPort: {{ tuple "powerdns" "internal" "powerdns_api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: pdns-api readinessProbe: tcpSocket: port: {{ tuple "powerdns" "internal" "powerdns_tcp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: powerdns-etc mountPath: /etc/pdns/conf.d/pdns.conf subPath: pdns.conf readOnly: true volumes: - name: powerdns-etc secret: secretName: powerdns-etc defaultMode: 0444 {{- end }} ================================================ FILE: powerdns/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: powerdns/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_init }} {{- $dbToInit := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.powerdns -}} {{- $dbInitJob := dict "envAll" . "serviceName" "powerdns" "dbToInit" $dbToInit -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: powerdns/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_sync }} {{- $envAll := . }} {{- $serviceAccountName := "powerdns-db-sync" }} {{ tuple $envAll "db_sync" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ $serviceAccountName }} labels: {{ tuple $envAll "powerdns" "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "powerdns" "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "db_sync" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: powerdns-db-sync {{ tuple $envAll "db_sync" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/powerdns-mysql-sync.sh volumeMounts: - name: powerdns-bin mountPath: /tmp/powerdns-mysql-sync.sh subPath: powerdns-mysql-sync.sh readOnly: true - name: powerdns-etc mountPath: /etc/mysql/my.cnf subPath: my.cnf readOnly: true volumes: - name: powerdns-bin configMap: name: powerdns-bin defaultMode: 0555 - name: powerdns-etc secret: secretName: powerdns-etc defaultMode: 0444 {{- end }} ================================================ FILE: powerdns/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "powerdns" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: powerdns/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "powerdns" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: DB_CONNECTION: {{ tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc -}} {{- end }} {{- end }} ================================================ FILE: powerdns/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: powerdns/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_dns }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "powerdns" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - port: {{ tuple "powerdns" "internal" "powerdns" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: pdns-udp protocol: UDP - port: {{ tuple "powerdns" "internal" "powerdns_tcp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: pdns-tcp {{- if .Values.manifests.service_api }} - port: {{ tuple "powerdns" "internal" "powerdns_api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: pdns-api {{- end }} selector: {{ tuple $envAll "powerdns" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if .Values.network.node_port_enabled }} {{/* Set Type=NodePort to get output packets from cluster internal IP of the POD instead of container one. */}} type: NodePort {{- if .Values.network.external_policy_local }} externalTrafficPolicy: Local {{- end }} {{- end }} {{- end }} ================================================ FILE: powerdns/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for powerdns. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- images: tags: powerdns: docker.io/psitrax/powerdns:4.1.10 db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_sync: docker.io/psitrax/powerdns:4.1.10 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: server: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 resources: enabled: false server: limits: memory: "128Mi" cpu: "500m" requests: memory: "128Mi" cpu: "500m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" labels: powerdns: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled dependencies: dynamic: common: local_image_registry: jobs: - powerdns-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry powerdns: jobs: - powerdns-db-init - powerdns-db-sync services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - powerdns-db-init services: - service: oslo_db endpoint: internal network: node_port_enabled: true external_policy_local: true endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false powerdns: username: powerdns password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null powerdns: auth: service: token: chiave_segreta hosts: default: powerdns host_fqdn_override: default: null port: powerdns_api: default: 8081 powerdns_tcp: default: 53 powerdns: default: 53 protocol: UDP oslo_db: auth: admin: username: root password: password powerdns: username: powerdns password: password hosts: default: mariadb host_fqdn_override: default: null path: /powerdns scheme: mysql+pymysql port: mysql: default: 3306 secrets: oci_image_registry: powerdns: powerdns-oci-image-registry-key oslo_db: admin: powerdns-db-admin powerdns: powerdns-db-user conf: powerdns: slave: true dnsupdate: true api: true cache_ttl: 0 query_cache_ttl: 0 negquery_cache_ttl: 0 out_of_zone_additional_processing: no webserver: true webserver_address: 0.0.0.0 webserver_allow_from: 0.0.0.0/0 gmysql_dbname: powerdns gmysql_dnssec: yes mysql: client: database: powerdns manifests: configmap_bin: true configmap_etc: true deployment: true job_db_init: true job_db_sync: true secret_db: true secret_registry: true service_dns: true service_api: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v2.25.0 description: OpenStack-Helm Prometheus name: prometheus version: 2025.2.0 home: https://prometheus.io/ sources: - https://github.com/prometheus/prometheus - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus/templates/bin/_apache.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ev COMMAND="${@:-start}" function start () { if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/httpd/apache2/envvars fi # Apache gets grumpy about PID files pre-existing rm -f /etc/httpd/logs/httpd.pid if [ -f /usr/local/apache2/conf/.htpasswd ]; then htpasswd -b /usr/local/apache2/conf/.htpasswd "$PROMETHEUS_ADMIN_USERNAME" "$PROMETHEUS_ADMIN_PASSWORD" else htpasswd -cb /usr/local/apache2/conf/.htpasswd "$PROMETHEUS_ADMIN_USERNAME" "$PROMETHEUS_ADMIN_PASSWORD" fi if [ -n "$PROMETHEUS_FEDERATE_USERNAME" ]; then htpasswd -b /usr/local/apache2/conf/.htpasswd "$PROMETHEUS_FEDERATE_USERNAME" "$PROMETHEUS_FEDERATE_PASSWORD" fi #Launch Apache on Foreground exec httpd -DFOREGROUND } function stop () { apachectl -k graceful-stop } $COMMAND ================================================ FILE: prometheus/templates/bin/_helm-tests.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex function endpoints_up () { endpoints_result=$(curl ${CACERT_OPTION} -K- <<< "--user ${PROMETHEUS_ADMIN_USERNAME}:${PROMETHEUS_ADMIN_PASSWORD}" \ "${PROMETHEUS_ENDPOINT}/api/v1/query?query=up" \ | python -c "import sys, json; print(json.load(sys.stdin)['status'])") if [ "$endpoints_result" = "success" ]; then echo "PASS: Endpoints successfully queried!" else echo "FAIL: Endpoints not queried!"; exit 1; fi } function get_targets () { targets_result=$(curl ${CACERT_OPTION} -K- <<< "--user ${PROMETHEUS_ADMIN_USERNAME}:${PROMETHEUS_ADMIN_PASSWORD}" \ "${PROMETHEUS_ENDPOINT}/api/v1/targets" \ | python -c "import sys, json; print(json.load(sys.stdin)['status'])") if [ "$targets_result" = "success" ]; then echo "PASS: Targets successfully queried!" else echo "FAIL: Endpoints not queried!"; exit 1; fi } function get_alertmanagers () { alertmanager=$(curl ${CACERT_OPTION} -K- <<< "--user ${PROMETHEUS_ADMIN_USERNAME}:${PROMETHEUS_ADMIN_PASSWORD}" \ "${PROMETHEUS_ENDPOINT}/api/v1/alertmanagers" \ | python -c "import sys, json; print(json.load(sys.stdin)['status'])") if [ "$alertmanager" = "success" ]; then echo "PASS: Alertmanager successfully queried!" else echo "FAIL: Alertmanager not queried!"; exit 1; fi } endpoints_up get_targets get_alertmanagers ================================================ FILE: prometheus/templates/bin/_prometheus.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # Two ways how to launch init process in container: by default and custom (defined in override values). {{ $deflaunch := .Values.proc_launch.prometheus.default }} if [ "{{ $deflaunch }}" = true ] then COMMAND="${@:-start}" function start () { {{ $flags := include "prometheus.utils.command_line_flags" .Values.conf.prometheus.command_line_flags }} exec /bin/prometheus --config.file=/etc/config/prometheus.yml {{ $flags }} } function stop () { kill -TERM 1 } $COMMAND else {{ tpl (.Values.proc_launch.prometheus.custom_launch) . }} fi ================================================ FILE: prometheus/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "monitoring" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: prometheus/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.Release.Name "prometheus-bin" | quote }} data: apache.sh: | {{ tuple "bin/_apache.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} prometheus.sh: | {{ tuple "bin/_prometheus.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} helm-tests.sh: | {{ tuple "bin/_helm-tests.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: prometheus/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "prometheus-etc" | quote }} type: Opaque data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.prometheus.scrape_configs.template "key" "prometheus.yml" "format" "Secret") | indent 2 }} {{ range $key, $value := .Values.conf.prometheus.rules }} {{ $key }}.rules: {{ toYaml $value | b64enc }} {{ end }} # NOTE(srwilkers): this must be last, to work round helm ~2.7 bug. {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.httpd "key" "httpd.conf" "format" "Secret") | indent 2 }} {{- end }} ================================================ FILE: prometheus/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus/templates/ingress-prometheus.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.prometheus.ingress.public }} {{- $envAll := . -}} {{- $port := tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "prometheus" "backendServiceType" "monitoring" "backendPort" $port -}} {{- $secretName := $envAll.Values.secrets.tls.monitoring.prometheus.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.monitoring.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: prometheus/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "prometheus" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: prometheus/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "prometheus" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: prometheus/templates/pod-helm-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.helm_tests }} {{- $envAll := . }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.Release.Name}}-test" labels: {{ tuple $envAll "prometheus" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "prometheus-test" "containerNames" (list "init" "prometheus-helm-tests") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} "helm.sh/hook": test-success spec: {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: prometheus-helm-tests {{ tuple $envAll "helm_tests" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "prometheus_helm_tests" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} command: - /tmp/helm-tests.sh env: - name: PROMETHEUS_ADMIN_USERNAME valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: PROMETHEUS_ADMIN_USERNAME - name: PROMETHEUS_ADMIN_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: PROMETHEUS_ADMIN_PASSWORD {{- if .Values.manifests.certificates }} - name: CACERT_OPTION value: "--cacert /etc/prometheus/certs/ca.crt" {{- end }} - name: PROMETHEUS_ENDPOINT value: {{ printf "%s://%s" (tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup") (tuple "monitoring" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: prometheus-bin mountPath: /tmp/helm-tests.sh subPath: helm-tests.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.monitoring.prometheus.internal "path" "/etc/prometheus/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} volumes: - name: pod-tmp emptyDir: {} - name: prometheus-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "prometheus-bin" | quote }} defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.monitoring.prometheus.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} ================================================ FILE: prometheus/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "monitoring" "backendService" "prometheus" ) }} {{- end }} ================================================ FILE: prometheus/templates/secret-prometheus.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_prometheus }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} type: Opaque data: PROMETHEUS_ADMIN_USERNAME: {{ .Values.endpoints.monitoring.auth.admin.username | b64enc }} PROMETHEUS_ADMIN_PASSWORD: {{ .Values.endpoints.monitoring.auth.admin.password | b64enc }} PROMETHEUS_FEDERATE_USERNAME: {{ .Values.endpoints.monitoring.auth.federate.username | b64enc }} PROMETHEUS_FEDERATE_PASSWORD: {{ .Values.endpoints.monitoring.auth.federate.password | b64enc }} {{- end }} ================================================ FILE: prometheus/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: prometheus/templates/secret-tls-configs.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.tls_configs }} --- apiVersion: v1 kind: Secret metadata: name: {{ .Release.Name }}-tls-configs data: {{- range $k, $v := .Values.tls_configs }} {{- range $f, $c := $v }} {{ $k }}.{{ $f }}: {{ $c | b64enc }} {{- end }} {{- end }} {{- end }} ================================================ FILE: prometheus/templates/service-ingress-prometheus.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.prometheus.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "monitoring" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: prometheus/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.prometheus }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "monitoring" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "prometheus" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: ports: - name: {{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} port: {{ tuple "monitoring" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "monitoring" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.prometheus.node_port.enabled }} nodePort: {{ .Values.network.prometheus.node_port.port }} {{ end }} selector: {{ tuple $envAll "prometheus" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.prometheus.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: prometheus/templates/statefulset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "probeTemplate" }} {{- $probePort := tuple "monitoring" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $probeUser := .Values.endpoints.monitoring.auth.admin.username }} {{- $probePass := .Values.endpoints.monitoring.auth.admin.password }} {{- $authHeader := printf "%s:%s" $probeUser $probePass | b64enc }} httpGet: path: /-/ready scheme: {{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} port: {{ $probePort }} httpHeaders: - name: Authorization value: Basic {{ $authHeader }} {{- end }} {{- if .Values.manifests.statefulset_prometheus }} {{- $envAll := . }} {{- $mounts_prometheus := .Values.pod.mounts.prometheus.prometheus }} {{- $mounts_prometheus_init := .Values.pod.mounts.prometheus.init_container }} {{- $rcControllerName := printf "%s-%s" $envAll.Release.Name "prometheus" }} {{ tuple $envAll "prometheus" $rcControllerName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ $rcControllerName | quote }} rules: - apiGroups: - "" resources: - nodes - nodes/proxy - services - endpoints - pods verbs: - get - list - watch - apiGroups: - "" resources: - configmaps verbs: - get - nonResourceURLs: - "/metrics" verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $rcControllerName | quote }} subjects: - kind: ServiceAccount name: {{ $rcControllerName | quote }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: {{ $rcControllerName | quote }} apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ $rcControllerName | quote }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "prometheus" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: {{ tuple "monitoring" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} podManagementPolicy: "Parallel" replicas: {{ .Values.pod.replicas.prometheus }} selector: matchLabels: {{ tuple $envAll "prometheus" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "prometheus" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "prometheus" "containerNames" (list "prometheus" "prometheus-perms" "apache-proxy" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "api" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $rcControllerName | quote }} affinity: {{ tuple $envAll "prometheus" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.prometheus.node_selector_key }}: {{ .Values.labels.prometheus.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.prometheus.timeout | default "30" }} initContainers: {{ tuple $envAll "prometheus" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: prometheus-perms {{ tuple $envAll "prometheus" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "api" "container" "prometheus_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - "nobody:" - /var/lib/prometheus/data volumeMounts: - name: pod-tmp mountPath: /tmp - name: storage mountPath: /var/lib/prometheus/data containers: - name: apache-proxy {{ tuple $envAll "apache_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.apache_proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "api" "container" "apache_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/apache.sh - start ports: - name: {{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} containerPort: {{ tuple "monitoring" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: PROMETHEUS_PORT value: {{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: PROMETHEUS_ADMIN_USERNAME valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: PROMETHEUS_ADMIN_USERNAME - name: PROMETHEUS_ADMIN_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: PROMETHEUS_ADMIN_PASSWORD - name: PROMETHEUS_FEDERATE_USERNAME valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: PROMETHEUS_FEDERATE_USERNAME - name: PROMETHEUS_FEDERATE_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: PROMETHEUS_FEDERATE_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: prometheus-bin mountPath: /tmp/apache.sh subPath: apache.sh readOnly: true - name: prometheus-etc mountPath: /usr/local/apache2/conf/httpd.conf subPath: httpd.conf readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.monitoring.prometheus.internal "path" "/etc/prometheus/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} - name: prometheus {{ tuple $envAll "prometheus" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "api" "container" "prometheus" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/prometheus.sh - start lifecycle: preStop: exec: command: - /tmp/prometheus.sh - stop ports: - name: prom-metrics containerPort: {{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" . "component" "prometheus" "container" "prometheus" "type" "readiness" "probeTemplate" (include "probeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" . "component" "prometheus" "container" "prometheus" "type" "liveness" "probeTemplate" (include "probeTemplate" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} env: {{- if .Values.pod.env.prometheus }} {{ include "helm-toolkit.utils.to_k8s_env_vars" .Values.pod.env.prometheus | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: etcprometheus mountPath: /etc/config - name: rulesprometheus mountPath: /etc/config/rules {{- range $key, $value := .Values.conf.prometheus.rules }} - name: prometheus-etc mountPath: /etc/config/rules/{{ $key }}.rules subPath: {{ $key }}.rules readOnly: true {{- end }} - name: prometheus-etc mountPath: /etc/config/prometheus.yml subPath: prometheus.yml readOnly: true - name: prometheus-bin mountPath: /tmp/prometheus.sh subPath: prometheus.sh readOnly: true - name: storage mountPath: /var/lib/prometheus/data {{- if .Values.tls_configs }} - name: tls-configs mountPath: /tls_configs {{- end }} {{ if $mounts_prometheus.volumeMounts }}{{ toYaml $mounts_prometheus.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etcprometheus emptyDir: {} - name: rulesprometheus emptyDir: {} - name: prometheus-etc secret: secretName: {{ printf "%s-%s" $envAll.Release.Name "prometheus-etc" | quote }} defaultMode: 0444 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.monitoring.prometheus.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} - name: prometheus-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "prometheus-bin" | quote }} defaultMode: 0555 {{- if .Values.tls_configs }} - name: tls-configs secret: secretName: {{ printf "%s-%s" $envAll.Release.Name "tls-configs" | quote }} defaultMode: 0444 {{- end }} {{ if $mounts_prometheus.volumes }}{{ toYaml $mounts_prometheus.volumes | indent 8 }}{{ end }} {{- if not .Values.storage.enabled }} {{- if .Values.storage.use_local_path.enabled }} - name: storage hostPath: path: {{ .Values.storage.use_local_path.host_path }} type: DirectoryOrCreate {{- else }} - name: storage emptyDir: {} {{- end }} {{- else }} volumeClaimTemplates: - metadata: name: storage spec: accessModes: {{ .Values.storage.pvc.access_mode }} resources: requests: storage: {{ .Values.storage.requests.storage }} storageClassName: {{ .Values.storage.storage_class }} {{- end }} {{- end }} ================================================ FILE: prometheus/templates/utils/_command_line_flags.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function generates the command line flags passed to Prometheus at time of # execution. This allows the Prometheus service configuration to be flexible, as # the only way to define Prometheus's configuration is via command line flags. # The yaml definition for these flags uses the full yaml path as the key, and # replaces underscores with hyphens to match the syntax required for the flags # generated (This is required due to Go's yaml parsing capabilities). # For example: # # conf: # prometheus: # command_line_flags: # storage.tsdb.max_block_duration: 2h # # Will generate the following flag: # --storage.tsdb.max-block-duration=2h # # Prometheus's command flags can be found by either running 'prometheus -h' or # 'prometheus --help-man' {{- define "prometheus.utils.command_line_flags" -}} {{- range $flag, $value := . -}} {{- $flag := $flag | replace "_" "-" }} {{- if eq $flag "web.enable-admin-api" "web.enable-lifecycle" "storage.tsdb.wal-compression" -}} {{- if $value }} {{- printf " --%s " $flag -}} {{- end -}} {{- else -}} {{- $value := $value | toString }} {{- printf " --%s=%s " $flag $value }} {{- end -}} {{- end -}} {{- end -}} ================================================ FILE: prometheus/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for prometheus. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- images: tags: apache_proxy: docker.io/library/httpd:2.4 prometheus: docker.io/prom/prometheus:v2.25.0 helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync labels: prometheus: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled pod: env: prometheus: null security_context: api: pod: runAsUser: 65534 container: prometheus_perms: runAsUser: 0 readOnlyRootFilesystem: false apache_proxy: runAsUser: 0 readOnlyRootFilesystem: false prometheus: allowPrivilegeEscalation: false readOnlyRootFilesystem: true test: pod: runAsUser: 65534 container: prometheus_helm_tests: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: prometheus: prometheus: init_container: null replicas: prometheus: 1 lifecycle: upgrades: statefulsets: pod_replacement_strategy: RollingUpdate termination_grace_period: prometheus: timeout: 30 resources: enabled: false prometheus: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" probes: prometheus: prometheus: readiness: enabled: true params: initialDelaySeconds: 30 timeoutSeconds: 30 liveness: enabled: false params: initialDelaySeconds: 120 timeoutSeconds: 30 endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false prometheus: username: prometheus password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null monitoring: name: prometheus namespace: null auth: admin: username: admin password: changeme federate: username: federate password: changeme hosts: default: prom-metrics public: prometheus host_fqdn_override: default: null # NOTE(srwilkers): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: 'http' port: api: default: 9090 http: default: 80 alertmanager: name: prometheus-alertmanager namespace: null hosts: default: alerts-engine public: prometheus-alertmanager discovery: prometheus-alertmanager-discovery host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9093 public: 80 mesh: default: 9094 ldap: hosts: default: ldap auth: admin: bind: "cn=admin,dc=cluster,dc=local" password: password host_fqdn_override: default: null path: default: "/ou=People,dc=cluster,dc=local" scheme: default: ldap port: ldap: default: 389 dependencies: dynamic: common: local_image_registry: jobs: - prometheus-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry prometheus: services: null tests: services: - endpoint: internal service: monitoring monitoring: prometheus: enabled: true prometheus: scrape: true network: prometheus: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/affinity: cookie nginx.ingress.kubernetes.io/session-cookie-name: kube-ingress-session-prometheus nginx.ingress.kubernetes.io/session-cookie-hash: sha1 nginx.ingress.kubernetes.io/session-cookie-expires: "600" nginx.ingress.kubernetes.io/session-cookie-max-age: "600" haproxy.org/path-rewrite: / haproxy.org/cookie-persistence: "kube-ingress-session-prometheus" node_port: enabled: false port: 30900 network_policy: prometheus: ingress: - {} egress: - {} proc_launch: prometheus: default: true custom_launch: | while true do echo "If 'proc_launch.prometheus.default: false'." echo "Your custom shell script code you can put here." sleep 10 done secrets: oci_image_registry: prometheus: prometheus-oci-image-registry-key tls: monitoring: prometheus: public: prometheus-tls-public internal: prometheus-tls-api tls_configs: # If client certificates are required to connect to metrics endpoints, they # can be configured here. They will be mounted in the pod under /tls_configs # and can be referenced in scrape configs. # The filenames will be the key and subkey concatenanted with a ".", e.g.: # /tls_configs/kubernetes-etcd.ca.pem # /tls_configs/kubernetes-etcd.crt.pem # /tls_configs/kubernetes-etcd.key.pem # From the following: # kubernetes-etcd: # ca.pem: | # -----BEGIN CERTIFICATE----- # -----END CERTIFICATE----- # crt.pem: | # -----BEGIN CERTIFICATE----- # -----END CERTIFICATE----- # key.pem: | # -----BEGIN RSA PRIVATE KEY----- # -----END RSA PRIVATE KEY----- storage: enabled: true pvc: name: prometheus-pvc access_mode: ["ReadWriteOnce"] requests: storage: 5Gi storage_class: general use_local_path: enabled: false host_path: /var/lib/prometheus-data manifests: certificates: false configmap_bin: true configmap_etc: true ingress: true helm_tests: true job_image_repo_sync: true network_policy: true secret_ingress_tls: true secret_prometheus: true secret_registry: true service_ingress: true service: true statefulset_prometheus: true conf: httpd: | ServerRoot "/usr/local/apache2" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule slotmem_shm_module modules/mod_slotmem_shm.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so User daemon Group daemon AllowOverride none Require all denied Require all denied ErrorLog /dev/stderr LogLevel warn LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout common CustomLog /dev/stdout combined CustomLog /dev/stdout proxy env=forwarded AllowOverride None Options None Require all granted RequestHeader unset Proxy early Include conf/extra/proxy-html.conf # Expose metrics to all users, as this is not sensitive information and # circumvents the inability of Prometheus to interpolate environment vars # in its configuration file ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics Satisfy Any Allow from all # Expose the /federate endpoint to all users, as this is also not # sensitive information and circumvents the inability of Prometheus to # interpolate environment vars in its configuration file ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics Satisfy Any Allow from all # Restrict general user (LDAP) access to the /graph endpoint, as general trusted # users should only be able to query Prometheus for metrics and not have access # to information like targets, configuration, flags or build info for Prometheus ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ AuthName "Prometheus" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/graph ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/graph AuthName "Prometheus" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user # Restrict access to the /config (dashboard) and /api/v1/status/config (http) endpoints # to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/config ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/config AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/config ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/config AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /flags (dashboard) and /api/v1/status/flags (http) endpoints # to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/flags ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/flags AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/flags ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/flags AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /status (dashboard) endpoint to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/status ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/status AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /rules (dashboard) endpoint to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/rules ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/rules AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /targets (dashboard) and /api/v1/targets (http) endpoints # to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/targets ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/targets AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/targets ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/targets AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /api/v1/admin/tsdb/ endpoints (http) to the admin user. # These endpoints are disabled by default, but are included here to ensure only # an admin user has access to these endpoints when enabled ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/admin/tsdb/ ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/admin/tsdb/ AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user prometheus: # Consumed by a prometheus helper function to generate the command line flags # for configuring the prometheus service command_line_flags: log.level: info query.max_concurrency: 20 query.timeout: 2m storage.tsdb.path: /var/lib/prometheus/data storage.tsdb.retention.time: 7d # NOTE(srwilkers): These settings default to false, but they are # exposed here to allow enabling if desired. Please note the security # impacts of enabling these flags. More information regarding the impacts # can be found here: https://prometheus.io/docs/operating/security/ # # If set to true, all administrative functionality is exposed via the http # /api/*/admin/ path web.enable_admin_api: false # If set to true, allows for http reloads and shutdown of Prometheus web.enable_lifecycle: false scrape_configs: template: | {{- $promHost := tuple "monitoring" "public" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- if not (empty .Values.conf.prometheus.rules)}} rule_files: {{- $rulesKeys := keys .Values.conf.prometheus.rules -}} {{- range $rule := $rulesKeys }} {{ printf "- /etc/config/rules/%s.rules" $rule }} {{- end }} {{- end }} global: scrape_interval: 60s evaluation_interval: 60s external_labels: prometheus_host: {{$promHost}} scrape_configs: - job_name: kubelet scheme: https # This TLS & bearer token file config is used to connect to the actual scrape # endpoints for cluster components. This is separate to discovery auth # configuration because discovery & scraping are two separate concerns in # Prometheus. The discovery auth config is automatic if Prometheus runs inside # the cluster. Otherwise, more config options have to be provided within the # . tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token kubernetes_sd_configs: - role: node scrape_interval: 45s relabel_configs: - action: labelmap regex: __meta_kubernetes_node_label_(.+) - target_label: __address__ replacement: kubernetes.default.svc:443 - source_labels: - __meta_kubernetes_node_name regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/${1}/proxy/metrics - source_labels: - __meta_kubernetes_node_name action: replace target_label: kubernetes_io_hostname # Scrape config for Kubelet cAdvisor. # # This is required for Kubernetes 1.7.3 and later, where cAdvisor metrics # (those whose names begin with 'container_') have been removed from the # Kubelet metrics endpoint. This job scrapes the cAdvisor endpoint to # retrieve those metrics. # # In Kubernetes 1.7.0-1.7.2, these metrics are only exposed on the cAdvisor # HTTP endpoint; use "replacement: /api/v1/nodes/${1}:4194/proxy/metrics" # in that case (and ensure cAdvisor's HTTP server hasn't been disabled with # the --cadvisor-port=0 Kubelet flag). # # This job is not necessary and should be removed in Kubernetes 1.6 and # earlier versions, or it will cause the metrics to be scraped twice. - job_name: 'kubernetes-cadvisor' # Default to scraping over https. If required, just disable this or change to # `http`. scheme: https # This TLS & bearer token file config is used to connect to the actual scrape # endpoints for cluster components. This is separate to discovery auth # configuration because discovery & scraping are two separate concerns in # Prometheus. The discovery auth config is automatic if Prometheus runs inside # the cluster. Otherwise, more config options have to be provided within the # . tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token kubernetes_sd_configs: - role: node relabel_configs: - action: labelmap regex: __meta_kubernetes_node_label_(.+) - target_label: __address__ replacement: kubernetes.default.svc:443 - source_labels: - __meta_kubernetes_node_name regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor metric_relabel_configs: - source_labels: - __name__ regex: 'container_network_tcp_usage_total' action: drop - source_labels: - __name__ regex: 'container_tasks_state' action: drop - source_labels: - __name__ regex: 'container_network_udp_usage_total' action: drop - source_labels: - __name__ regex: 'container_memory_failures_total' action: drop - source_labels: - __name__ regex: 'container_cpu_load_average_10s' action: drop - source_labels: - __name__ regex: 'container_cpu_system_seconds_total' action: drop - source_labels: - __name__ regex: 'container_cpu_user_seconds_total' action: drop - source_labels: - __name__ regex: 'container_fs_inodes_free' action: drop - source_labels: - __name__ regex: 'container_fs_inodes_total' action: drop - source_labels: - __name__ regex: 'container_fs_io_current' action: drop - source_labels: - __name__ regex: 'container_fs_io_time_seconds_total' action: drop - source_labels: - __name__ regex: 'container_fs_io_time_weighted_seconds_total' action: drop - source_labels: - __name__ regex: 'container_fs_read_seconds_total' action: drop - source_labels: - __name__ regex: 'container_fs_reads_merged_total' action: drop - source_labels: - __name__ regex: 'container_fs_reads_merged_total' action: drop - source_labels: - __name__ regex: 'container_fs_reads_total' action: drop - source_labels: - __name__ regex: 'container_fs_sector_reads_total' action: drop - source_labels: - __name__ regex: 'container_fs_sector_writes_total' action: drop - source_labels: - __name__ regex: 'container_fs_write_seconds_total' action: drop - source_labels: - __name__ regex: 'container_fs_writes_bytes_total' action: drop - source_labels: - __name__ regex: 'container_fs_writes_merged_total' action: drop - source_labels: - __name__ regex: 'container_fs_writes_total' action: drop - source_labels: - __name__ regex: 'container_last_seen' action: drop - source_labels: - __name__ regex: 'container_memory_cache' action: drop - source_labels: - __name__ regex: 'container_memory_failcnt' action: drop - source_labels: - __name__ regex: 'container_memory_max_usage_bytes' action: drop - source_labels: - __name__ regex: 'container_memory_rss' action: drop - source_labels: - __name__ regex: 'container_memory_swap' action: drop - source_labels: - __name__ regex: 'container_memory_usage_bytes' action: drop - source_labels: - __name__ regex: 'container_network_receive_errors_total' action: drop - source_labels: - __name__ regex: 'container_network_receive_packets_dropped_total' action: drop - source_labels: - __name__ regex: 'container_network_receive_packets_total' action: drop - source_labels: - __name__ regex: 'container_network_transmit_errors_total' action: drop - source_labels: - __name__ regex: 'container_network_transmit_packets_dropped_total' action: drop - source_labels: - __name__ regex: 'container_network_transmit_packets_total' action: drop - source_labels: - __name__ regex: 'container_spec_cpu_period' action: drop - source_labels: - __name__ regex: 'container_spec_cpu_shares' action: drop - source_labels: - __name__ regex: 'container_spec_memory_limit_bytes' action: drop - source_labels: - __name__ regex: 'container_spec_memory_reservation_limit_bytes' action: drop - source_labels: - __name__ regex: 'container_spec_memory_swap_limit_bytes' action: drop - source_labels: - __name__ regex: 'container_start_time_seconds' action: drop # Scrape config for API servers. # # Kubernetes exposes API servers as endpoints to the default/kubernetes # service so this uses `endpoints` role and uses relabelling to only keep # the endpoints associated with the default/kubernetes service using the # default named port `https`. This works for single API server deployments as # well as HA API server deployments. - job_name: 'apiserver' kubernetes_sd_configs: - role: endpoints scrape_interval: 45s # Default to scraping over https. If required, just disable this or change to # `http`. scheme: https # This TLS & bearer token file config is used to connect to the actual scrape # endpoints for cluster components. This is separate to discovery auth # configuration because discovery & scraping are two separate concerns in # Prometheus. The discovery auth config is automatic if Prometheus runs inside # the cluster. Otherwise, more config options have to be provided within the # . tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt # If your node certificates are self-signed or use a different CA to the # master CA, then disable certificate verification below. Note that # certificate verification is an integral part of a secure infrastructure # so this should only be disabled in a controlled environment. You can # disable certificate verification by uncommenting the line below. # # insecure_skip_verify: true bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token # Keep only the default/kubernetes service endpoints for the https port. This # will add targets for each API server which Kubernetes adds an endpoint to # the default/kubernetes service. relabel_configs: - source_labels: - __meta_kubernetes_namespace - __meta_kubernetes_service_name - __meta_kubernetes_endpoint_port_name action: keep regex: default;kubernetes;https metric_relabel_configs: - source_labels: - __name__ regex: 'apiserver_admission_controller_admission_latencies_seconds_bucket' action: drop - source_labels: - __name__ regex: 'rest_client_request_latency_seconds_bucket' action: drop - source_labels: - __name__ regex: 'apiserver_response_sizes_bucket' action: drop - source_labels: - __name__ regex: 'apiserver_admission_step_admission_latencies_seconds_bucket' action: drop - source_labels: - __name__ regex: 'apiserver_admission_controller_admission_latencies_seconds_count' action: drop - source_labels: - __name__ regex: 'apiserver_admission_controller_admission_latencies_seconds_sum' action: drop - source_labels: - __name__ regex: 'apiserver_request_latencies_summary' action: drop # Scrape config for service endpoints. # # The relabeling allows the actual service scrape endpoint to be configured # via the following annotations: # # * `prometheus.io/scrape`: Only scrape services that have a value of `true` # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need # to set this to `https` & most likely set the `tls_config` of the scrape config. # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. # * `prometheus.io/port`: If the metrics are exposed on a different port to the # service then set this appropriately. - job_name: 'openstack-exporter' kubernetes_sd_configs: - role: endpoints scrape_interval: 60s relabel_configs: - source_labels: - __meta_kubernetes_service_name action: keep regex: "openstack-metrics" - source_labels: - __meta_kubernetes_service_annotation_prometheus_io_scrape action: keep regex: true - source_labels: - __meta_kubernetes_service_annotation_prometheus_io_scheme action: replace target_label: __scheme__ regex: (https?) - source_labels: - __meta_kubernetes_service_annotation_prometheus_io_path action: replace target_label: __metrics_path__ regex: (.+) - source_labels: - __address__ - __meta_kubernetes_service_annotation_prometheus_io_port action: replace target_label: __address__ regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:$2 - action: labelmap regex: __meta_kubernetes_service_label_(.+) - source_labels: - __meta_kubernetes_namespace action: replace target_label: kubernetes_namespace - source_labels: - __meta_kubernetes_service_name action: replace target_label: instance - source_labels: - __meta_kubernetes_service_name action: replace target_label: kubernetes_name - source_labels: - __meta_kubernetes_service_name target_label: job replacement: ${1} - job_name: 'node-exporter' kubernetes_sd_configs: - role: endpoints scrape_interval: 60s relabel_configs: - source_labels: - __meta_kubernetes_service_name action: keep regex: 'node-exporter' - source_labels: - __meta_kubernetes_pod_node_name action: replace target_label: hostname - job_name: 'kubernetes-service-endpoints' kubernetes_sd_configs: - role: endpoints scrape_interval: 60s relabel_configs: - source_labels: - __meta_kubernetes_service_name action: drop regex: '(openstack-metrics|prom-metrics|ceph-mgr|node-exporter)' - source_labels: - __meta_kubernetes_service_annotation_prometheus_io_scrape action: keep regex: true - source_labels: - __meta_kubernetes_service_annotation_prometheus_io_scheme action: replace target_label: __scheme__ regex: (https?) - source_labels: - __meta_kubernetes_service_annotation_prometheus_io_path action: replace target_label: __metrics_path__ regex: (.+) - source_labels: - __address__ - __meta_kubernetes_service_annotation_prometheus_io_port action: replace target_label: __address__ regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:$2 - action: labelmap regex: __meta_kubernetes_service_label_(.+) - source_labels: - __meta_kubernetes_namespace action: replace target_label: kubernetes_namespace - source_labels: - __meta_kubernetes_service_name action: replace target_label: kubernetes_name - source_labels: - __meta_kubernetes_service_name target_label: job replacement: ${1} # Example scrape config for pods # # The relabeling allows the actual pod scrape endpoint to be configured via the # following annotations: # # * `prometheus.io/scrape`: Only scrape pods that have a value of `true` # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the # pod's declared ports (default is a port-free target if none are declared). - job_name: 'kubernetes-pods' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] action: replace regex: ([^:]+)(?::\d+)?;(\d+) replacement: $1:$2 target_label: __address__ - action: labelmap regex: __meta_kubernetes_pod_label_(.+) - source_labels: [__meta_kubernetes_namespace] action: replace target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_pod_name] action: replace target_label: kubernetes_pod_name - job_name: calico-etcd kubernetes_sd_configs: - role: service scrape_interval: 20s relabel_configs: - action: labelmap regex: __meta_kubernetes_service_label_(.+) - action: keep source_labels: - __meta_kubernetes_service_name regex: "calico-etcd" - action: keep source_labels: - __meta_kubernetes_namespace regex: kube-system target_label: namespace - source_labels: - __meta_kubernetes_pod_name target_label: pod - source_labels: - __meta_kubernetes_service_name target_label: service - source_labels: - __meta_kubernetes_service_name target_label: job replacement: ${1} - source_labels: - __meta_kubernetes_service_label target_label: job regex: calico-etcd replacement: ${1} - target_label: endpoint replacement: "calico-etcd" - job_name: ceph-mgr kubernetes_sd_configs: - role: service scrape_interval: 20s relabel_configs: - action: labelmap regex: __meta_kubernetes_service_label_(.+) - action: keep source_labels: - __meta_kubernetes_service_name regex: "ceph-mgr" - source_labels: - __meta_kubernetes_service_port_name action: drop regex: 'ceph-mgr' - action: keep source_labels: - __meta_kubernetes_namespace regex: ceph target_label: namespace - source_labels: - __meta_kubernetes_pod_name target_label: pod - source_labels: - __meta_kubernetes_service_name target_label: service - source_labels: - __meta_kubernetes_service_name target_label: job replacement: ${1} - source_labels: - __meta_kubernetes_service_label target_label: job regex: ceph-mgr replacement: ${1} - target_label: endpoint replacement: "ceph-mgr" alerting: alertmanagers: - kubernetes_sd_configs: - role: pod tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - source_labels: [__meta_kubernetes_pod_label_application] regex: prometheus-alertmanager action: keep - source_labels: [__meta_kubernetes_pod_container_port_name] regex: alerts-api action: keep - source_labels: [__meta_kubernetes_pod_container_port_name] regex: peer-mesh action: drop rules: [] # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus-alertmanager/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v0.20.0 description: OpenStack-Helm Alertmanager for Prometheus name: prometheus-alertmanager version: 2025.2.0 home: https://prometheus.io/docs/alerting/alertmanager/ sources: - https://github.com/prometheus/alertmanager - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus-alertmanager/templates/bin/_alertmanager.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec /bin/alertmanager \ --config.file=/etc/alertmanager/config.yml \ {{- range $flag, $value := .Values.conf.command_flags.alertmanager }} {{- $flag := $flag | replace "_" "-" }} {{ printf "--%s=%s" $flag $value | indent 4 }} \ {{- end }} $(generate_peers) } function generate_peers () { final_pod_suffix=$(( {{ .Values.pod.replicas.alertmanager }}-1 )) for pod_suffix in `seq 0 "$final_pod_suffix"` do echo --cluster.peer=prometheus-alertmanager-$pod_suffix.$DISCOVERY_SVC:$MESH_PORT done } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: prometheus-alertmanager/templates/bin/_apache.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -exv COMMAND="${@:-start}" function start () { if [ -f /etc/apache2/envvars ]; then # Loading Apache2 ENV variables source /etc/httpd/apache2/envvars fi # Apache gets grumpy about PID files pre-existing rm -f /etc/httpd/logs/httpd.pid if [ -f /usr/local/apache2/conf/.htpasswd ]; then htpasswd -b /usr/local/apache2/conf/.htpasswd "$ALERTMANAGER_USERNAME" "$ALERTMANAGER_PASSWORD" else htpasswd -cb /usr/local/apache2/conf/.htpasswd "$ALERTMANAGER_USERNAME" "$ALERTMANAGER_PASSWORD" fi #Launch Apache on Foreground exec httpd -DFOREGROUND } function stop () { apachectl -k graceful-stop } $COMMAND ================================================ FILE: prometheus-alertmanager/templates/clusterrolebinding.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.clusterrolebinding }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s" "prometheus-alertmanager" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: run-alertmanager subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io {{- end }} ================================================ FILE: prometheus-alertmanager/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.Release.Name "alertmanager-bin" | quote }} data: apache.sh: | {{ tuple "bin/_apache.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} alertmanager.sh: | {{ tuple "bin/_alertmanager.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "alertmanager-etc" | quote }} data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.alertmanager "key" "config.yml" "format" "Secret") | indent 2 }} {{- if .Values.conf.alert_templates }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.alert_templates "key" "alert-templates.tmpl" "format" "Secret") | indent 2 }} {{- end }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.httpd "key" "httpd.conf" "format" "Secret") | indent 2 }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus-alertmanager/templates/ingress-alertmanager.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.alertmanager.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendService" "alertmanager" "backendServiceType" "alertmanager" "backendPort" "http" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "alertmanager" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "alertmanager" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: prometheus-alertmanager/templates/secret-admin-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_admin_user }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} type: Opaque data: ALERTMANAGER_USERNAME: {{ .Values.endpoints.alertmanager.auth.admin.username | b64enc }} ALERTMANAGER_PASSWORD: {{ .Values.endpoints.alertmanager.auth.admin.password | b64enc }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "alertmanager" "backendService" "alertmanager") }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/service-discovery.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_discovery }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "alertmanager" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: type: ClusterIP clusterIP: None ports: - name: peer-mesh port: {{ tuple "alertmanager" "internal" "mesh" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "prometheus-alertmanager" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/service-ingress-alertmanager.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.alertmanager.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "alertmanager" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.prometheus }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "alertmanager" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: ports: - name: http port: {{ tuple "alertmanager" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.alertmanager.node_port.enabled }} nodePort: {{ .Values.network.alertmanager.node_port.port }} {{ end }} selector: {{ tuple $envAll "prometheus-alertmanager" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.alertmanager.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: prometheus-alertmanager/templates/statefulset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset }} {{- $envAll := . }} {{- $mounts_alertmanager := .Values.pod.mounts.alertmanager.alertmanager }} {{- $mounts_alertmanager_init := .Values.pod.mounts.alertmanager.init_container }} {{- $serviceAccountName := "prometheus-alertmanager" }} {{ tuple $envAll "prometheus-alertmanager" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: prometheus-alertmanager annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "prometheus-alertmanager" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: {{ tuple "alertmanager" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} podManagementPolicy: "Parallel" replicas: {{ .Values.pod.replicas.alertmanager }} selector: matchLabels: {{ tuple $envAll "prometheus-alertmanager" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "prometheus-alertmanager" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" $serviceAccountName "containerNames" (list "prometheus-alertmanager" "prometheus-alertmanager-perms" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "server" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "prometheus-alertmanager" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.alertmanager.node_selector_key }}: {{ .Values.labels.alertmanager.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.alertmanager.timeout | default "30" }} initContainers: {{ tuple $envAll "alertmanager" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: prometheus-alertmanager-perms {{ tuple $envAll "prometheus-alertmanager" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.alertmanager | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "prometheus_alertmanager_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - "nobody:" - /var/lib/alertmanager/data volumeMounts: - name: pod-tmp mountPath: /tmp - name: alertmanager-data mountPath: /var/lib/alertmanager/data containers: - name: apache-proxy {{ tuple $envAll "apache_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.apache_proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "apache_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/apache.sh - start ports: - name: http containerPort: 80 env: - name: ALERTMANAGER_PORT value: {{ tuple "alertmanager" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: ALERTMANAGER_USERNAME valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: ALERTMANAGER_USERNAME - name: ALERTMANAGER_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.Release.Name "admin-user" | quote }} key: ALERTMANAGER_PASSWORD volumeMounts: - name: pod-tmp mountPath: /tmp - name: alertmanager-bin mountPath: /tmp/apache.sh subPath: apache.sh readOnly: true - name: alertmanager-etc mountPath: /usr/local/apache2/conf/httpd.conf subPath: httpd.conf readOnly: true - name: prometheus-alertmanager {{ tuple $envAll "prometheus-alertmanager" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.alertmanager | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "prometheus_alertmanager" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/alertmanager.sh - start lifecycle: preStop: exec: command: - /tmp/alertmanager.sh - stop env: - name: DISCOVERY_SVC value: {{ tuple "alertmanager" "discovery" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} - name: MESH_PORT value: {{ tuple "alertmanager" "internal" "mesh" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} ports: - name: alerts-api containerPort: {{ tuple "alertmanager" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - name: peer-mesh containerPort: {{ tuple "alertmanager" "internal" "mesh" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: path: /#/status port: {{ tuple "alertmanager" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 30 timeoutSeconds: 30 volumeMounts: - name: pod-tmp mountPath: /tmp - name: etc-alertmanager mountPath: /etc/config {{- if .Values.conf.alert_templates }} - name: alertmanager-etc mountPath: /etc/alertmanager/template/alert-templates.tmpl subPath: alert-templates.tmpl readOnly: true {{- end }} - name: alertmanager-etc mountPath: /etc/alertmanager/config.yml subPath: config.yml readOnly: true - name: alertmanager-bin mountPath: /tmp/alertmanager.sh subPath: alertmanager.sh readOnly: true - name: alertmanager-data mountPath: /var/lib/alertmanager/data {{ if $mounts_alertmanager.volumeMounts }}{{ toYaml $mounts_alertmanager.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: etc-alertmanager emptyDir: {} - name: alertmanager-etc secret: secretName: {{ printf "%s-%s" $envAll.Release.Name "alertmanager-etc" | quote }} defaultMode: 0444 - name: alertmanager-bin configMap: name: {{ printf "%s-%s" $envAll.Release.Name "alertmanager-bin" | quote }} defaultMode: 0555 {{ if $mounts_alertmanager.volumes }}{{ toYaml $mounts_alertmanager.volumes | indent 8 }}{{ end }} {{- if not .Values.storage.alertmanager.enabled }} {{- if .Values.storage.alertmanager.use_local_path.enabled }} - name: alertmanager-data hostPath: path: {{ .Values.storage.alertmanager.use_local_path.host_path }} type: DirectoryOrCreate {{- else }} - name: alertmanager-data emptyDir: {} {{- end }} {{- else }} volumeClaimTemplates: - metadata: name: alertmanager-data spec: accessModes: {{ .Values.storage.alertmanager.pvc.access_mode }} resources: requests: storage: {{ .Values.storage.alertmanager.requests.storage }} storageClassName: {{ .Values.storage.alertmanager.storage_class }} {{- end }} {{- end }} ================================================ FILE: prometheus-alertmanager/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for alertmanager. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- images: tags: apache_proxy: docker.io/library/httpd:2.4 prometheus-alertmanager: docker.io/prom/alertmanager:v0.20.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync labels: alertmanager: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled pod: security_context: server: pod: runAsUser: 65534 container: prometheus_alertmanager_perms: runAsUser: 0 readOnlyRootFilesystem: true apache_proxy: runAsUser: 0 readOnlyRootFilesystem: false prometheus_alertmanager: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: alertmanager: alertmanager: init_container: null replicas: alertmanager: 1 lifecycle: upgrades: deployment: pod_replacement_strategy: RollingUpdate statefulsets: pod_replacement_strategy: RollingUpdate termination_grace_period: alertmanager: timeout: 30 resources: enabled: false apache_proxy: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" alertmanager: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false prometheus-alertmanager: username: prometheus-alertmanager password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null alertmanager: name: prometheus-alertmanager namespace: null auth: admin: username: admin password: changeme hosts: default: alerts-engine public: prometheus-alertmanager discovery: prometheus-alertmanager-discovery host_fqdn_override: default: null # NOTE(srwilkers): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: 'http' port: api: default: 9093 public: 80 mesh: default: 9094 http: default: 80 ldap: hosts: default: ldap auth: admin: bind: "cn=admin,dc=cluster,dc=local" password: password host_fqdn_override: default: null path: default: "/ou=People,dc=cluster,dc=local" scheme: default: ldap port: ldap: default: 389 dependencies: dynamic: common: local_image_registry: jobs: - alertmanager-image-repo-sync services: - endpoint: node service: local_image_registry static: alertmanager: services: null image_repo_sync: services: - endpoint: internal service: local_image_registry network: alertmanager: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 30903 secrets: oci_image_registry: prometheus-alertmanager: prometheus-alertmanager-oci-image-registry-key tls: alertmanager: alertmanager: public: alerts-tls-public storage: alertmanager: enabled: true pvc: access_mode: ["ReadWriteOnce"] requests: storage: 5Gi storage_class: general use_local_path: enabled: false host_path: /var/lib/prometheus-alertmanager-data manifests: clusterrolebinding: true configmap_bin: true configmap_etc: true ingress: true job_image_repo_sync: true network_policy: false secret_admin_user: true secret_ingress_tls: true secret_registry: true service: true service_discovery: true service_ingress: true statefulset: true network_policy: alertmanager: ingress: - {} egress: - {} monitoring: prometheus: enabled: true prometheus: scrape: true conf: httpd: | ServerRoot "/usr/local/apache2" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule remoteip_module modules/mod_remoteip.so LoadModule slotmem_shm_module modules/mod_slotmem_shm.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so User daemon Group daemon AllowOverride none Require all denied Require all denied ErrorLog /dev/stderr LogLevel warn LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout common CustomLog /dev/stdout combined CustomLog /dev/stdout proxy env=forwarded AllowOverride None Options None Require all granted RequestHeader unset Proxy early Include conf/extra/proxy-html.conf RemoteIPHeader X-Original-Forwarded-For ProxyPass http://localhost:{{ tuple "alertmanager" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ ProxyPassReverse http://localhost:{{ tuple "alertmanager" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ AuthName "Alertmanager" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user command_flags: alertmanager: storage.path: /var/lib/alertmanager/data cluster.listen_address: "0.0.0.0:9094" alertmanager: | global: # The smarthost and SMTP sender used for mail notifications. smtp_smarthost: 'localhost:25' smtp_from: 'alertmanager@example.org' smtp_auth_username: 'alertmanager' smtp_auth_password: 'password' # The auth token for Hipchat. hipchat_auth_token: '1234556789' # Alternative host for Hipchat. hipchat_api_url: 'https://hipchat.foobar.org/' # The directory from which notification templates are read. templates: - '/etc/alertmanager/template/*.tmpl' # The root route on which each incoming alert enters. route: # The labels by which incoming alerts are grouped together. For example, # multiple alerts coming in for cluster=A and alertname=LatencyHigh would # be batched into a single group. group_by: - alertname - cluster - service # When a new group of alerts is created by an incoming alert, wait at # least 'group_wait' to send the initial notification. # This way ensures that you get multiple alerts for the same group that start # firing shortly after another are batched together on the first # notification. group_wait: 30s # When the first notification was sent, wait 'group_interval' to send a batch # of new alerts that started firing for that group. group_interval: 5m # If an alert has successfully been sent, wait 'repeat_interval' to # resend them. repeat_interval: 3h # A default receiver # receiver: team-X-mails receiver: 'team-X-mails' # All the above attributes are inherited by all child routes and can # overwritten on each. # The child route trees. routes: # This routes performs a regular expression match on alert # labels to catch alerts that are related to a list of # services. - receiver: 'team-X-mails' continue: true - match_re: service: ^(foo1|foo2|baz)$ receiver: team-X-mails # The service has a sub-route for critical alerts, any alerts # that do not match, i.e. severity != critical, fall-back to the # parent node and are sent to 'team-X-mails' routes: - match: severity: critical receiver: team-X-pager - match: service: files receiver: team-Y-mails routes: - match: severity: critical receiver: team-Y-pager # This route handles all alerts coming from a database service. If there's # no team to handle it, it defaults to the DB team. - match: service: database receiver: team-DB-pager # Also group alerts by affected database. group_by: - alertname - cluster - database routes: - match: owner: team-X receiver: team-X-pager - match: owner: team-Y receiver: team-Y-pager # Inhibition rules allow to mute a set of alerts given that another alert is # firing. # We use this to mute any warning-level notifications if the same alert is # already critical. inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' # Apply inhibition if the alertname is the same. equal: - alertname - cluster - service receivers: - name: 'team-X-mails' email_configs: - to: 'team-X+alerts@example.org' - name: 'team-X-pager' email_configs: - to: 'team-X+alerts-critical@example.org' pagerduty_configs: - service_key: - name: 'team-Y-mails' email_configs: - to: 'team-Y+alerts@example.org' - name: 'team-Y-pager' pagerduty_configs: - service_key: - name: 'team-DB-pager' pagerduty_configs: - service_key: - name: 'team-X-hipchat' hipchat_configs: - auth_token: room_id: 85 message_format: html notify: false alert_templates: null # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus-blackbox-exporter/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v0.16.0 description: OpenStack-Helm blackbox exporter for Prometheus name: prometheus-blackbox-exporter version: 2025.2.0 home: https://github.com/prometheus/blackbox_exporter sources: - https://opendev.org/openstack/openstack-helm - https://github.com/prometheus/blackbox_exporter maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus-blackbox-exporter/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} --- apiVersion: apps/v1 kind: Deployment metadata: name: prometheus-blackbox-exporter annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "prometheus-blackbox-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.prometheus_blackbox_exporter }} selector: matchLabels: {{ tuple $envAll "prometheus-blackbox-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "prometheus-blackbox-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "prometheus-blackbox-exporter" "containerNames" (list "blackbox-exporter") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "prometheus_blackbox_exporter" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} nodeSelector: {{ .Values.labels.blackbox_exporter.node_selector_key }}: {{ .Values.labels.blackbox_exporter.node_selector_value | quote }} containers: - name: blackbox-exporter {{ tuple $envAll "blackbox_exporter" | include "helm-toolkit.snippets.image" | indent 8 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus_blackbox_exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 8 }} {{ dict "envAll" $envAll "application" "prometheus_blackbox_exporter" "container" "blackbox_exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 8 }} args: - "--config.file=/config/blackbox.yaml" ports: - name: metrics containerPort: {{ tuple "prometheus_blackbox_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} livenessProbe: httpGet: path: /health port: {{ tuple "prometheus_blackbox_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 30 periodSeconds: 30 readinessProbe: httpGet: path: /health port: {{ tuple "prometheus_blackbox_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 30 volumeMounts: - mountPath: /config/blackbox.yaml name: config subPath: blackbox.yaml volumes: - name: config secret: secretName: prometheus-blackbox-exporter-etc ================================================ FILE: prometheus-blackbox-exporter/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus-blackbox-exporter/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: prometheus-blackbox-exporter/templates/secret.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} apiVersion: v1 kind: Secret metadata: name: prometheus-blackbox-exporter-etc labels: {{ tuple $envAll "prometheus-blackbox-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} data: {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.config.blackbox "key" "blackbox.yaml" "format" "Secret") | indent 2 }} ================================================ FILE: prometheus-blackbox-exporter/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- $envAll := . }} apiVersion: v1 kind: Service metadata: name: {{ tuple "prometheus_blackbox_exporter" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: metrics port: {{ tuple "prometheus_blackbox_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "prometheus-blackbox-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} ================================================ FILE: prometheus-blackbox-exporter/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for kube-state-metrics. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: blackbox_exporter: docker.io/prom/blackbox-exporter:v0.16.0 pull_policy: IfNotPresent local_registry: active: false labels: blackbox_exporter: node_selector_key: openstack-control-plane node_selector_value: enabled service: annotations: {} port: 9115 secrets: oci_image_registry: prometheus-blackbox-exporter: prometheus-blackbox-exporter-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false prometheus-blackbox-exporter: username: prometheus-blackbox-exporter password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null prometheus_blackbox_exporter: namespace: null hosts: default: prometheus-blackbox-exporter host_fqdn_override: default: null path: default: null scheme: default: 'http' port: metrics: default: 9115 pod: security_context: prometheus_blackbox_exporter: pod: runAsUser: 65534 container: blackbox_exporter: allowPrivilegeEscalation: false readOnlyRootFilesystem: true replicas: prometheus_blackbox_exporter: 1 annotations: prometheus.io/scrape: 'true' prometheus.io/port: "9115" affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: prometheus_blackbox_exporter: timeout: 30 resources: enabled: true prometheus_blackbox_exporter: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - prometheus-openstack-exporter-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry prometheus_blackbox_exporter: jobs: - prometheus-openstack-exporter-ks-user services: - endpoint: internal service: identity config: blackbox: modules: http_2xx: prober: http timeout: 10s http: valid_http_versions: ["HTTP/1.1", "HTTP/2.0"] no_follow_redirects: false preferred_ip_protocol: "ip4" manifests: secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus-kube-state-metrics/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.3.1 description: OpenStack-Helm Kube-State-Metrics for Prometheus name: prometheus-kube-state-metrics version: 2025.2.0 home: https://github.com/kubernetes/kube-state-metrics sources: - https://github.com/kubernetes/kube-state-metrics - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus-kube-state-metrics/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: kube-state-metrics-bin data: image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: prometheus-kube-state-metrics/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "kubeMetricsReadinessProbe" }} httpGet: path: /metrics port: {{ tuple "kube_state_metrics" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "kube-state-metrics" }} {{ tuple $envAll "kube_state_metrics" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: {{ $serviceAccountName }} rules: - apiGroups: - "*" resources: - "*" verbs: - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: {{ $serviceAccountName }} subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ $envAll.Release.Namespace }} roleRef: kind: ClusterRole name: {{ $serviceAccountName }} apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: Deployment metadata: name: kube-state-metrics annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "kube-state-metrics" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.kube_state_metrics }} selector: matchLabels: {{ tuple $envAll "kube-state-metrics" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "kube-state-metrics" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "kube-state-metrics" "containerNames" (list "kube-state-metrics" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "exporter" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "kube-state-metrics" "exporter" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.kube_state_metrics.node_selector_key }}: {{ .Values.labels.kube_state_metrics.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.kube_state_metrics.timeout | default "30" }} initContainers: {{ tuple $envAll "kube_state_metrics" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: kube-state-metrics {{ tuple $envAll "kube_state_metrics" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.kube_state_metrics | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "exporter" "container" "kube_state_metrics" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} ports: - name: metrics containerPort: {{ tuple "kube_state_metrics" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" . "component" "server" "container" "kube_metrics" "type" "readiness" "probeTemplate" (include "kubeMetricsReadinessProbe" . | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp volumes: - name: pod-tmp emptyDir: {} {{- end }} ================================================ FILE: prometheus-kube-state-metrics/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus-kube-state-metrics/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "kube-state-metrics" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: prometheus-kube-state-metrics/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "kube-state-metrics" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: prometheus-kube-state-metrics/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: prometheus-kube-state-metrics/templates/service-controller-manager.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_controller_manager }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.kube_controller_manager }} --- apiVersion: v1 kind: Service metadata: name: kube-controller-manager-discovery labels: {{ tuple $envAll "controller-manager" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: selector: component: kube-controller-manager type: ClusterIP clusterIP: None ports: - name: http-metrics port: {{ tuple "kube_controller_manager" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "kube_controller_manager" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP {{- end }} ================================================ FILE: prometheus-kube-state-metrics/templates/service-kube-state-metrics.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_kube_state_metrics }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.kube_state_metrics }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "kube_state_metrics" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "kube-state-metrics" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: ports: - name: http port: {{ tuple "kube_state_metrics" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "kube_state_metrics" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "kube-state-metrics" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: prometheus-kube-state-metrics/templates/service-scheduler.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_scheduler }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.kube_scheduler }} --- apiVersion: v1 kind: Service metadata: name: kube-scheduler-discovery labels: {{ tuple $envAll "kube-scheduler" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: selector: component: kube-scheduler type: ClusterIP clusterIP: None ports: - name: http-metrics port: {{ tuple "kube_scheduler" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "kube_scheduler" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP {{- end }} ================================================ FILE: prometheus-kube-state-metrics/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for kube-state-metrics. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: kube_state_metrics: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.16.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync labels: kube_state_metrics: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled pod: probes: server: kube_metrics: readiness: enabled: true params: initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 10 security_context: exporter: pod: runAsUser: 65534 container: kube_state_metrics: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: kube_state_metrics: kube_state_metrics: init_container: null replicas: kube_state_metrics: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: kube_state_metrics: timeout: 30 resources: enabled: false kube_state_metrics: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - kube-metrics-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry kube_state_metrics: services: null secrets: oci_image_registry: prometheus-kube-state-metrics: prometheus-kube-state-metrics-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false prometheus-kube-state-metrics: username: prometheus-kube-state-metrics password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null kube_state_metrics: namespace: null hosts: default: kube-state-metrics host_fqdn_override: default: null path: default: null scheme: default: 'http' port: http: default: 8080 kube_scheduler: scheme: default: 'http' path: default: /metrics port: metrics: default: 10251 kube_controller_manager: scheme: default: 'http' path: default: /metrics port: metrics: default: 10252 network_policy: kube-state-metrics: ingress: - {} egress: - {} monitoring: prometheus: enabled: true kube_state_metrics: scrape: true kube_scheduler: scrape: true kube_controller_manager: scrape: true manifests: configmap_bin: true deployment: true job_image_repo_sync: true network_policy: false secret_registry: true service_kube_state_metrics: true service_controller_manager: true service_scheduler: true serviceaccount: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus-mysql-exporter/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *~ # Various IDEs .project .idea/ *.tmproj ================================================ FILE: prometheus-mysql-exporter/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v0.12.1 description: OpenStack-Helm Prometheus mysql-exporter name: prometheus-mysql-exporter version: 2025.2.0 home: https://mariadb.com/kb/en/ icon: http://badges.mariadb.org/mariadb-badge-180x60.png sources: - https://github.com/MariaDB/server - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus-mysql-exporter/README.rst ================================================ openstack-helm/mariadb ====================== By default, this chart creates a 3-member mariadb galera cluster. This chart depends on mariadb-operator chart. The StatefulSets all leverage PVCs to provide stateful storage to ``/var/lib/mysql``. You must ensure that your control nodes that should receive mariadb instances are labeled with ``openstack-control-plane=enabled``, or whatever you have configured in values.yaml for the label configuration: :: kubectl label nodes openstack-control-plane=enabled --all ================================================ FILE: prometheus-mysql-exporter/templates/bin/_create-mysql-user.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e # SLAVE MONITOR # Grants ability to SHOW SLAVE STATUS, SHOW REPLICA STATUS, # SHOW ALL SLAVES STATUS, SHOW ALL REPLICAS STATUS, SHOW RELAYLOG EVENTS. # New privilege added in MariaDB Enterprise Server 10.5.8-5. Alias for REPLICA MONITOR. # # REPLICATION CLIENT # Grants ability to SHOW MASTER STATUS, SHOW SLAVE STATUS, SHOW BINARY LOGS. In ES10.5, # is an alias for BINLOG MONITOR and the capabilities have changed. BINLOG MONITOR grants # ability to SHOW MASTER STATUS, SHOW BINARY LOGS, SHOW BINLOG EVENTS, and SHOW BINLOG STATUS. mariadb_version=$(mysql --defaults-file=/etc/mysql/admin_user.cnf -e "status" | grep -E '^Server\s+version:') echo "Current database ${mariadb_version}" if [[ ! -z ${mariadb_version} && -z $(grep -E '10.2|10.3|10.4' <<< ${mariadb_version}) ]]; then # In case MariaDB version is 10.2.x-10.4.x - we use old privileges definitions if ! mysql --defaults-file=/etc/mysql/admin_user.cnf -e \ "CREATE OR REPLACE USER '${EXPORTER_USER}'@'%' IDENTIFIED BY '${EXPORTER_PASSWORD}'; \ GRANT PROCESS, BINLOG MONITOR, SLAVE MONITOR, SELECT ON *.* TO '${EXPORTER_USER}'@'%' ${MARIADB_X509}; \ FLUSH PRIVILEGES;" ; then echo "ERROR: Could not create user: ${EXPORTER_USER}" exit 1 fi else # here we use new MariaDB privileges definitions defines since version 10.5 if ! mysql --defaults-file=/etc/mysql/admin_user.cnf -e \ "CREATE OR REPLACE USER '${EXPORTER_USER}'@'%' IDENTIFIED BY '${EXPORTER_PASSWORD}'; \ GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO '${EXPORTER_USER}'@'%' ${MARIADB_X509}; \ FLUSH PRIVILEGES;" ; then echo "ERROR: Could not create user: ${EXPORTER_USER}" exit 1 fi fi ================================================ FILE: prometheus-mysql-exporter/templates/bin/_mysqld-exporter.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex compareVersions() { echo $1 $2 | \ awk '{ split($1, a, "."); split($2, b, "."); res = -1; for (i = 1; i <= 3; i++){ if (a[i] < b[i]) { res =-1; break; } else if (a[i] > b[i]) { res = 1; break; } else if (a[i] == b[i]) { if (i == 3) { res = 0; break; } else { continue; } } } print res; }' } MYSQL_EXPORTER_VER=`/bin/mysqld_exporter --version 2>&1 | grep "mysqld_exporter" | awk '{print $3}'` #in versions greater than 0.10.0 different configuration flags are used: #https://github.com/prometheus/mysqld_exporter/commit/66c41ac7eb90a74518a6ecf6c6bb06464eb68db8 compverResult=`compareVersions "${MYSQL_EXPORTER_VER}" "0.10.0"` CONFIG_FLAG_PREFIX='-' if [ ${compverResult} -gt 0 ]; then CONFIG_FLAG_PREFIX='--' fi exec /bin/mysqld_exporter \ ${CONFIG_FLAG_PREFIX}config.my-cnf=/etc/mysql/mysql_user.cnf \ ${CONFIG_FLAG_PREFIX}web.listen-address="${POD_IP}:${LISTEN_PORT}" \ ${CONFIG_FLAG_PREFIX}web.telemetry-path="$TELEMETRY_PATH" ================================================ FILE: prometheus-mysql-exporter/templates/exporter-configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.configmap_bin .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: mysql-exporter-bin data: create-mysql-user.sh: | {{ tuple "bin/_create-mysql-user.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} mysqld-exporter.sh: | {{ tuple "bin/_mysqld-exporter.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: prometheus-mysql-exporter/templates/exporter-deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.deployment_exporter .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "prometheus-mysql-exporter" }} {{ tuple $envAll "prometheus_mysql_exporter" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: prometheus-mysql-exporter labels: {{ tuple $envAll "prometheus-mysql-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.prometheus_mysql_exporter }} selector: matchLabels: {{ tuple $envAll "prometheus-mysql-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "prometheus-mysql-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} namespace: {{ .Values.endpoints.prometheus_mysql_exporter.namespace }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "prometheus-mysql-exporter" "containerNames" (list "init" "mysql-exporter") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "prometheus_mysql_exporter" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} nodeSelector: {{ .Values.labels.prometheus_mysql_exporter.node_selector_key }}: {{ .Values.labels.prometheus_mysql_exporter.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.prometheus_mysql_exporter.timeout | default "30" }} initContainers: {{ tuple $envAll "prometheus_mysql_exporter" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: mysql-exporter {{ tuple $envAll "prometheus_mysql_exporter" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "prometheus_mysql_exporter" "container" "exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus_mysql_exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/mysqld-exporter.sh ports: - name: metrics containerPort: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} env: - name: EXPORTER_USER valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_USER - name: EXPORTER_PASSWORD valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_PASSWORD - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: LISTEN_PORT value: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: TELEMETRY_PATH value: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" | quote }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: mysql-exporter-secrets mountPath: /etc/mysql/mysql_user.cnf subPath: mysql_user.cnf readOnly: true - name: mysql-exporter-bin mountPath: /tmp/mysqld-exporter.sh subPath: mysqld-exporter.sh readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: mysql-exporter-secrets secret: secretName: mysql-exporter-secrets defaultMode: 0444 - name: mysql-exporter-bin configMap: name: mysql-exporter-bin defaultMode: 0555 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: prometheus-mysql-exporter/templates/exporter-job-create-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.job_user_create .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $serviceAccountName := "exporter-create-sql-user" }} {{ tuple $envAll "prometheus_create_mysql_user" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: exporter-create-sql-user labels: {{ tuple $envAll "prometheus-mysql-exporter" "create-sql-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": "post-install,post-upgrade" "helm.sh/hook-weight": "5" "helm.sh/hook-delete-policy": "before-hook-creation" spec: backoffLimit: {{ .Values.jobs.exporter_create_sql_user.backoffLimit }} template: metadata: labels: {{ tuple $envAll "prometheus-mysql-exporter" "create-sql-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} {{ dict "envAll" $envAll "podName" "create-sql-user" "containerNames" (list "init" "exporter-create-sql-user") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: shareProcessNamespace: true serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "prometheus_create_mysql_user" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} activeDeadlineSeconds: {{ .Values.jobs.exporter_create_sql_user.activeDeadlineSeconds }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.prometheus_mysql_exporter.node_selector_key }}: {{ .Values.labels.prometheus_mysql_exporter.node_selector_value }} initContainers: {{ tuple $envAll "prometheus_create_mysql_user" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: exporter-create-sql-user {{ tuple $envAll "prometheus_create_mysql_user" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "prometheus_create_mysql_user" "container" "main" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.prometheus_create_mysql_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/create-mysql-user.sh env: - name: EXPORTER_USER valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_USER - name: EXPORTER_PASSWORD valueFrom: secretKeyRef: name: mysql-exporter-secrets key: EXPORTER_PASSWORD {{- if $envAll.Values.manifests.certificates }} - name: MARIADB_X509 value: "REQUIRE X509" {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: mysql-exporter-bin mountPath: /tmp/create-mysql-user.sh subPath: create-mysql-user.sh readOnly: true - name: mariadb-secrets mountPath: /etc/mysql/admin_user.cnf subPath: admin_user.cnf readOnly: true {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: mysql-exporter-bin configMap: name: mysql-exporter-bin defaultMode: 0555 - name: mariadb-secrets secret: secretName: mariadb-secrets defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_db.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: prometheus-mysql-exporter/templates/exporter-network-policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.network_policy_exporter .Values.monitoring.prometheus.enabled -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "prometheus-mysql-exporter" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: prometheus-mysql-exporter/templates/exporter-secrets-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.secret_etc .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $exporter_user := .Values.endpoints.oslo_db.auth.exporter.username }} {{- $exporter_password := .Values.endpoints.oslo_db.auth.exporter.password }} {{- $db_host := tuple "oslo_db" "direct" "mysql" $envAll | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} {{- $data_source_name := printf "%s:%s@(%s)/" $exporter_user $exporter_password $db_host }} --- apiVersion: v1 kind: Secret metadata: name: mysql-exporter-secrets type: Opaque data: DATA_SOURCE_NAME: {{ $data_source_name | b64enc }} EXPORTER_USER: {{ .Values.endpoints.oslo_db.auth.exporter.username | b64enc }} EXPORTER_PASSWORD: {{ .Values.endpoints.oslo_db.auth.exporter.password | b64enc }} mysql_user.cnf: {{ tuple "secrets/_exporter_user.cnf.tpl" . | include "helm-toolkit.utils.template" | b64enc }} {{- end }} ================================================ FILE: prometheus-mysql-exporter/templates/exporter-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.monitoring.prometheus.service_exporter .Values.monitoring.prometheus.enabled }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.mysqld_exporter }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "prometheus_mysql_exporter" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "prometheus-mysql-exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: ports: - name: metrics port: {{ tuple "prometheus_mysql_exporter" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "prometheus-mysql-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: prometheus-mysql-exporter/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus-mysql-exporter/templates/secrets/_exporter_user.cnf.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [client] user = {{ .Values.endpoints.oslo_db.auth.exporter.username }} password = {{ .Values.endpoints.oslo_db.auth.exporter.password }} host = {{ tuple "oslo_db" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} port = {{ tuple "oslo_db" "direct" "mysql" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.manifests.certificates }} ssl-ca = /etc/mysql/certs/ca.crt ssl-key = /etc/mysql/certs/tls.key ssl-cert = /etc/mysql/certs/tls.crt {{- end }} ================================================ FILE: prometheus-mysql-exporter/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for mariadb. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null images: tags: prometheus_create_mysql_user: docker.io/library/mariadb:10.5.9-focal prometheus_mysql_exporter: docker.io/prom/mysqld-exporter:v0.12.1 prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync labels: prometheus_mysql_exporter: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled pod: security_context: prometheus_mysql_exporter: pod: runAsUser: 99 container: exporter: runAsUser: 99 allowPrivilegeEscalation: false readOnlyRootFilesystem: true prometheus_create_mysql_user: pod: runAsUser: 0 container: main: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: prometheus_mysql_exporter: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: prometheus_mysql_exporter: timeout: 30 resources: enabled: false prometheus_mysql_exporter: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "500m" jobs: prometheus_create_mysql_user: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - mysql-exporter-image-repo-sync services: - endpoint: node service: local_image_registry static: prometheus_create_mysql_user: services: - endpoint: internal service: oslo_db prometheus_mysql_exporter: jobs: - exporter-create-sql-user services: - endpoint: internal service: oslo_db prometheus_mysql_exporter_tests: services: - endpoint: internal service: prometheus_mysql_exporter - endpoint: internal service: monitoring image_repo_sync: services: - endpoint: internal service: local_image_registry jobs: exporter_create_sql_user: backoffLimit: 87600 activeDeadlineSeconds: 3600 monitoring: prometheus: enabled: false mysqld_exporter: scrape: true secrets: identity: admin: keystone-admin-user oci_image_registry: mariadb: mariadb-oci-image-registry-key tls: oslo_db: server: public: mariadb-tls-server internal: mariadb-tls-direct # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false mariadb: username: mariadb password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null monitoring: name: prometheus namespace: null hosts: default: prom-metrics public: prometheus host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9090 public: 80 prometheus_mysql_exporter: namespace: null hosts: default: mysql-exporter host_fqdn_override: default: null path: default: /metrics scheme: default: 'http' port: metrics: default: 9104 oslo_db: namespace: null auth: admin: username: root password: password sst: username: sst password: password audit: username: audit password: password exporter: username: exporter password: password hosts: default: mariadb-server-primary direct: mariadb-server-internal discovery: mariadb-discovery server: mariadb-server host_fqdn_override: default: null path: null scheme: mysql+pymysql port: mysql: default: 3306 wsrep: default: 4567 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns_tcp: default: 53 dns: default: 53 protocol: UDP identity: name: backup-storage-auth namespace: openstack auth: admin: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default mariadb-server: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: null role: admin region_name: RegionOne username: mariadb-backup-user password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 network_policy: prometheus-mysql-exporter: ingress: - {} egress: - {} manifests: certificates: false job_image_repo_sync: true monitoring: prometheus: configmap_bin: false deployment_exporter: false job_user_create: false secret_etc: false service_exporter: false network_policy_exporter: false network_policy: false secret_etc: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus-node-exporter/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v0.18.1 description: OpenStack-Helm Node Exporter for Prometheus name: prometheus-node-exporter version: 2025.2.0 home: https://github.com/prometheus/node_exporter sources: - https://github.com/prometheus/node_exporter - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus-node-exporter/templates/bin/_node-exporter.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec /bin/node_exporter \ {{- if .Values.conf.collectors.enable }} {{ tuple "--collector." .Values.conf.collectors.enable | include "helm-toolkit.utils.joinListWithPrefix" }} \ {{- end }} {{- if .Values.conf.collectors.disable }} {{ tuple "--no-collector." .Values.conf.collectors.disable | include "helm-toolkit.utils.joinListWithPrefix" }} \ {{- end }} {{- if .Values.conf.collectors.textfile.directory }} --collector.textfile.directory={{.Values.conf.collectors.textfile.directory }} \ {{- end }} {{- if .Values.conf.collectors.filesystem.ignored_mount_points }} --collector.filesystem.ignored-mount-points={{ .Values.conf.collectors.filesystem.ignored_mount_points }} \ {{- end }} {{- if .Values.conf.collectors.filesystem.rootfs_mount_point }} --path.rootfs={{ .Values.conf.collectors.filesystem.rootfs_mount_point }} \ {{- end }} --collector.ntp.server={{ .Values.conf.ntp_server_ip }} ================================================ FILE: prometheus-node-exporter/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: node-exporter-bin data: node-exporter.sh: | {{ tuple "bin/_node-exporter.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ================================================ FILE: prometheus-node-exporter/templates/daemonset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $mounts_node_exporter := .Values.pod.mounts.node_exporter.node_exporter}} {{- $serviceAccountName := printf "%s-%s" .Release.Name "node-exporter" }} {{ tuple $envAll "node_exporter" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: run-node-exporter subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "node_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "node_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "node_exporter" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "node_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "node-exporter" "containerNames" (list "node-exporter" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: {{ dict "envAll" $envAll "application" "metrics" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if .Values.pod.tolerations.node_exporter.enabled }} {{ tuple $envAll "node_exporter" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ else }} nodeSelector: {{ .Values.labels.node_exporter.node_selector_key }}: {{ .Values.labels.node_exporter.node_selector_value | quote }} {{ end }} hostNetwork: true hostPID: true initContainers: {{ tuple $envAll "node_exporter" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: node-exporter {{ tuple $envAll "node_exporter" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.node_exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "metrics" "container" "node_exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/node-exporter.sh ports: - name: metrics containerPort: {{ tuple "node_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} hostPort: {{ tuple "node_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: port: {{ tuple "node_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 volumeMounts: - name: pod-tmp mountPath: /tmp - name: proc mountPath: /host/proc readOnly: true - name: sys mountPath: /host/sys readOnly: true {{ if .Values.conf.collectors.textfile.directory }} - name: stats-out mountPath: {{.Values.conf.collectors.textfile.directory }} readOnly: true {{ end }} - name: node-exporter-bin mountPath: /tmp/node-exporter.sh subPath: node-exporter.sh readOnly: true {{ if $mounts_node_exporter.volumeMounts }}{{ toYaml $mounts_node_exporter.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: proc hostPath: path: /proc - name: sys hostPath: path: /sys {{ if .Values.conf.collectors.textfile.directory }} - name: stats-out hostPath: path: {{.Values.conf.collectors.textfile.directory }} {{ end }} - name: node-exporter-bin configMap: name: node-exporter-bin defaultMode: 0555 {{ if $mounts_node_exporter.volumes }}{{ toYaml $mounts_node_exporter.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: prometheus-node-exporter/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus-node-exporter/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "node-exporter" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: prometheus-node-exporter/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: prometheus-node-exporter/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.node_exporter }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "node_metrics" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "node_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: type: ClusterIP clusterIP: None ports: - name: metrics port: {{ tuple "node_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "node_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "node_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: prometheus-node-exporter/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for node-exporter. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: node_exporter: docker.io/prom/node-exporter:v0.18.1 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync labels: node_exporter: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled pod: security_context: metrics: pod: runAsUser: 65534 container: node_exporter: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname mounts: node_exporter: node_exporter: init_container: null lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate node_exporter: enabled: true min_ready_seconds: 0 max_unavailable: 1 termination_grace_period: node_exporter: timeout: 30 resources: enabled: false node_exporter: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tolerations: node_exporter: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/control-plane operator: Exists - key: node-role.kubernetes.io/node operator: Exists dependencies: dynamic: common: local_image_registry: jobs: - node-exporter-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry node_exporter: services: null monitoring: prometheus: enabled: true node_exporter: scrape: true secrets: oci_image_registry: prometheus-node-exporter: prometheus-node-exporter-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false prometheus-node-exporter: username: prometheus-node-exporter password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null node_metrics: namespace: null hosts: default: node-exporter host_fqdn_override: default: null path: default: null scheme: default: 'http' port: metrics: default: 9100 manifests: configmap_bin: true daemonset: true job_image_repo_sync: true secret_registry: true service: true conf: ntp_server_ip: 127.0.0.1 collectors: enable: - ntp - meminfo_numa - bonding - mountstats disable: textfile: directory: /var/log/node-exporter-vfstats filesystem: ignored_mount_points: rootfs_mount_point: # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus-openstack-exporter/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack Metrics Exporter for Prometheus name: prometheus-openstack-exporter version: 2025.2.0 home: https://opendev.org/openstack/openstack-helm sources: - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus-openstack-exporter/templates/bin/_prometheus-openstack-exporter.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec python3 /usr/local/bin/exporter/main.py } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: prometheus-openstack-exporter/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: prometheus-openstack-exporter-bin data: image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} prometheus-openstack-exporter.sh: | {{ tuple "bin/_prometheus-openstack-exporter.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: prometheus-openstack-exporter/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $ksUserSecret := .Values.secrets.identity.user }} {{- $serviceAccountName := "prometheus-openstack-exporter" }} {{ tuple $envAll "prometheus_openstack_exporter" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: prometheus-openstack-exporter annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "prometheus-openstack-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.prometheus_openstack_exporter }} selector: matchLabels: {{ tuple $envAll "prometheus-openstack-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "prometheus-openstack-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} secret-keystone-hash: {{ tuple "secret-keystone.yaml" . | include "helm-toolkit.utils.hash" }} secret-registry-hash: {{ tuple "secret-registry.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "prometheus-openstack-exporter" "containerNames" (list "openstack-metrics-exporter" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "exporter" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "prometheus-openstack-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.openstack_exporter.node_selector_key }}: {{ .Values.labels.openstack_exporter.node_selector_value | quote }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.prometheus_openstack_exporter.timeout | default "30" }} initContainers: {{ tuple $envAll "prometheus_openstack_exporter" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 | trim }} - name: clouds-yaml-gen {{ tuple $envAll "dep_check" | include "helm-toolkit.snippets.image" | nindent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.clouds_yaml_gen | include "helm-toolkit.snippets.kubernetes_resources" | nindent 10 }} {{ dict "envAll" $envAll "application" "clouds_yaml_gen" "container" "clouds_yaml_gen" | include "helm-toolkit.snippets.kubernetes_container_security_context" | nindent 10 }} command: - /bin/sh - -c - | cat < /etc/openstack/clouds.yaml clouds: default: auth: auth_url: "$OS_AUTH_URL" username: "$OS_USERNAME" password: "$OS_PASSWORD" project_name: "$OS_PROJECT_NAME" user_domain_name: "$OS_USER_DOMAIN_NAME" project_domain_name: "$OS_PROJECT_DOMAIN_NAME" region_name: "$OS_REGION_NAME" interface: "$OS_INTERFACE" identity_api_version: "$OS_IDENTITY_API_VERSION" {{- if .Values.manifests.certificates }} cacert: "/etc/ssl/certs/openstack-helm.crt" {{- end }} EOF env: - name: OS_AUTH_URL valueFrom: secretKeyRef: key: OS_AUTH_URL name: {{ .Values.secrets.identity.user | quote }} - name: OS_USERNAME valueFrom: secretKeyRef: key: OS_USERNAME name: {{ .Values.secrets.identity.user | quote }} - name: OS_PASSWORD valueFrom: secretKeyRef: key: OS_PASSWORD name: {{ .Values.secrets.identity.user | quote }} - name: OS_PROJECT_NAME valueFrom: secretKeyRef: key: OS_PROJECT_NAME name: {{ .Values.secrets.identity.user | quote }} - name: OS_USER_DOMAIN_NAME valueFrom: secretKeyRef: key: OS_USER_DOMAIN_NAME name: {{ .Values.secrets.identity.user | quote }} - name: OS_PROJECT_DOMAIN_NAME valueFrom: secretKeyRef: key: OS_PROJECT_DOMAIN_NAME name: {{ .Values.secrets.identity.user | quote }} - name: OS_REGION_NAME valueFrom: secretKeyRef: key: OS_REGION_NAME name: {{ .Values.secrets.identity.user | quote }} - name: OS_INTERFACE valueFrom: secretKeyRef: key: OS_INTERFACE name: {{ .Values.secrets.identity.user | quote }} - name: OS_IDENTITY_API_VERSION value: "3" volumeMounts: - name: clouds-yaml mountPath: /etc/openstack {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: false runAsUser: 65534 containers: - name: openstack-metrics-exporter {{ tuple $envAll "prometheus_openstack_exporter" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.prometheus_openstack_exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "exporter" "container" "openstack_metrics_exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/openstack-exporter args: - --web.listen-address=:{{ tuple "prometheus_openstack_exporter" "internal" "exporter" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - --os-client-config=/etc/openstack/clouds.yaml - default ports: - name: metrics containerPort: {{ tuple "prometheus_openstack_exporter" "internal" "exporter" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} livenessProbe: httpGet: path: /metrics port: {{ tuple "prometheus_openstack_exporter" "internal" "exporter" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 180 periodSeconds: 60 timeoutSeconds: 30 readinessProbe: httpGet: path: /metrics port: {{ tuple "prometheus_openstack_exporter" "internal" "exporter" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 30 env: - name: LISTEN_PORT value: {{ tuple "prometheus_openstack_exporter" "internal" "exporter" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} - name: OS_POLLING_INTERVAL value: {{ .Values.conf.prometheus_openstack_exporter.OS_POLLING_INTERVAL | quote }} - name: OS_RETRIES value: {{ .Values.conf.prometheus_openstack_exporter.OS_RETRIES | quote }} - name: TIMEOUT_SECONDS value: {{ .Values.conf.prometheus_openstack_exporter.TIMEOUT_SECONDS | quote }} - name: OS_IDENTITY_API_VERSION value: "3" volumeMounts: - name: pod-tmp mountPath: /tmp - name: clouds-yaml mountPath: /etc/openstack readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} workingDir: /tmp volumes: - name: pod-tmp emptyDir: {} - name: clouds-yaml emptyDir: {} {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: prometheus-openstack-exporter/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus-openstack-exporter/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "prometheus-openstack-exporter" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: prometheus-openstack-exporter/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user }} {{- $envAll := . }} {{- $serviceAccountName := "prometheus-openstack-exporter-ks-user" }} {{ tuple $envAll "ks_user" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: prometheus-openstack-exporter-ks-user labels: {{ tuple $envAll "prometheus-openstack-exporter" "ks-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "prometheus-openstack-exporter" "ks-user" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "prometheus-openstack-exporter-ks-user" "containerNames" (list "prometheus-openstack-exporter-ks-user" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "ks_user" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "ks_user" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: prometheus-openstack-exporter-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "ks_user" "container" "prometheus_openstack_exporter_ks_user" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/ks-user.sh {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: ks-user-sh mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "prometheus-openstack-exporter" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.user }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.user.role | quote }} volumes: - name: pod-tmp emptyDir: {} - name: ks-user-sh configMap: name: prometheus-openstack-exporter-bin defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: prometheus-openstack-exporter/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "prometheus-openstack-exporter" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: prometheus-openstack-exporter/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "user" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: prometheus-openstack-exporter/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: prometheus-openstack-exporter/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.openstack_exporter }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "prometheus_openstack_exporter" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "prometheus-openstack-exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: ports: - name: http port: {{ tuple "prometheus_openstack_exporter" "internal" "exporter" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "prometheus_openstack_exporter" "internal" "exporter" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "prometheus-openstack-exporter" "exporter" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: prometheus-openstack-exporter/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for prometheus-openstack-exporter. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: prometheus_openstack_exporter: ghcr.io/openstack-exporter/openstack-exporter:1.7.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync labels: openstack_exporter: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled pod: security_context: exporter: pod: runAsUser: 65534 container: openstack_metrics_exporter: readOnlyRootFilesystem: true allowPrivilegeEscalation: false ks_user: pod: runAsUser: 65534 container: prometheus_openstack_exporter_ks_user: readOnlyRootFilesystem: true allowPrivilegeEscalation: false clouds_yaml_gen: container: prometheus_openstack_exporter_ks_user: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname mounts: prometheus_openstack_exporter: prometheus_openstack_exporter: init_container: null replicas: prometheus_openstack_exporter: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 termination_grace_period: prometheus_openstack_exporter: timeout: 30 resources: enabled: false prometheus_openstack_exporter: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" clouds_yaml_gen: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - prometheus-openstack-exporter-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry ks_user: services: - endpoint: internal service: identity prometheus_openstack_exporter: jobs: - prometheus-openstack-exporter-ks-user services: - endpoint: internal service: identity conf: prometheus_openstack_exporter: OS_POLLING_INTERVAL: 30 TIMEOUT_SECONDS: 20 OS_RETRIES: 1 secrets: identity: admin: prometheus-openstack-exporter-keystone-admin user: prometheus-openstack-exporter-keystone-user oci_image_registry: prometheus-openstack-exporter: prometheus-openstack-exporter-oci-image-registry-key tls: identity: api: # This name should be same as in keystone. Keystone # secret will be used in these charts # internal: keystone-tls-api endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false prometheus-openstack-exporter: username: prometheus-openstack-exporter password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null prometheus_openstack_exporter: namespace: null hosts: default: openstack-metrics host_fqdn_override: default: null path: default: null scheme: default: 'http' port: exporter: default: 9180 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default user: role: admin region_name: RegionOne username: prometheus-openstack-exporter password: password project_name: service user_domain_name: default project_domain_name: default hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: 'http' port: api: default: 80 internal: 5000 monitoring: prometheus: enabled: true openstack_exporter: scrape: true network: openstack_metrics_exporter: port: 9180 network_policy: prometheus-openstack-exporter: ingress: - {} egress: - {} manifests: certificates: false configmap_bin: true deployment: true job_image_repo_sync: true job_ks_user: true network_policy: false secret_keystone: true secret_registry: true service: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: prometheus-process-exporter/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v0.2.11 description: OpenStack-Helm Process Exporter for Prometheus name: prometheus-process-exporter version: 2025.2.0 home: https://opendev.org/openstack/openstack-helm sources: - https://github.com/ncabatoff/process-exporter - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: prometheus-process-exporter/templates/daemonset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset }} {{- $envAll := . }} {{- $serviceAccountName := printf "%s-%s" .Release.Name "process-exporter" }} {{ tuple $envAll "process_exporter" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: run-process-exporter subjects: - kind: ServiceAccount name: {{ $serviceAccountName }} namespace: {{ .Release.Namespace }} roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io --- apiVersion: apps/v1 kind: DaemonSet metadata: name: process-exporter annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "process_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "process_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "process_exporter" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "process_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ dict "envAll" $envAll "podName" "process-exporter" "containerNames" (list "process-exporter" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "metrics" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ if .Values.pod.tolerations.process_exporter.enabled }} {{ tuple $envAll "process_exporter" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ else }} nodeSelector: {{ .Values.labels.process_exporter.node_selector_key }}: {{ .Values.labels.process_exporter.node_selector_value }} {{ end }} hostNetwork: true hostPID: true initContainers: {{ tuple $envAll "process_exporter" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: process-exporter {{ tuple $envAll "process_exporter" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.process_exporter | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "metrics" "container" "process_exporter" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} args: {{- if hasKey .Values.conf "children" }} - -children={{ .Values.conf.children }} {{- end }} - -procnames - {{ .Values.conf.processes }} ports: - name: metrics containerPort: {{ tuple "process_exporter_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} hostPort: {{ tuple "process_exporter_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: tcpSocket: port: {{ tuple "process_exporter_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 20 periodSeconds: 10 volumeMounts: - name: pod-tmp mountPath: /tmp - name: proc mountPath: /host/proc readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: proc hostPath: path: /proc {{- end }} ================================================ FILE: prometheus-process-exporter/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: prometheus-process-exporter/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "process-exporter" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: prometheus-process-exporter/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "process_exporter" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: prometheus-process-exporter/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: prometheus-process-exporter/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.process_exporter }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "process_exporter_metrics" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "process_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if .Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: type: ClusterIP clusterIP: None ports: - name: metrics port: {{ tuple "process_exporter_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} targetPort: {{ tuple "process_exporter_metrics" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "process_exporter" "metrics" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: prometheus-process-exporter/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for process-exporter. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: process_exporter: docker.io/ncabatoff/process-exporter:0.2.11 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync labels: process_exporter: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled pod: security_context: metrics: pod: runAsUser: 65534 container: process_exporter: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: process_exporter: process_exporter: init_container: null lifecycle: upgrades: daemonsets: pod_replacement_strategy: RollingUpdate process_exporter: enabled: true min_ready_seconds: 0 max_unavailable: 1 termination_grace_period: process_exporter: timeout: 30 resources: enabled: false process_exporter: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tolerations: process_exporter: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists - key: node-role.kubernetes.io/control-plane operator: Exists - key: node-role.kubernetes.io/node operator: Exists dependencies: dynamic: common: local_image_registry: jobs: - process-exporter-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry process_exporter: services: null monitoring: prometheus: enabled: true process_exporter: scrape: true secrets: oci_image_registry: prometheus-process-exporter: prometheus-process-exporter-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false prometheus-process-exporter: username: prometheus-process-exporter password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null process_exporter_metrics: namespace: null hosts: default: process-exporter host_fqdn_override: default: null path: default: null scheme: default: 'http' port: metrics: default: 9256 network_policy: process_exporter: ingress: - {} egress: - {} manifests: configmap_bin: true daemonset: true job_image_repo_sync: true secret_registry: true service: true conf: processes: dockerd,kubelet,kube-proxy,bgsagent,bgscollect,bgssd children: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: rabbitmq/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *~ # Various IDEs .project .idea/ *.tmproj ================================================ FILE: rabbitmq/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v3.12.0 description: OpenStack-Helm RabbitMQ name: rabbitmq version: 2025.2.0 home: https://github.com/rabbitmq/rabbitmq-server dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: rabbitmq/templates/bin/_rabbitmq-cookie.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex cp -vf /run/lib/rabbitmq/.erlang.cookie /var/lib/rabbitmq/.erlang.cookie chown "rabbitmq" /var/lib/rabbitmq/.erlang.cookie chmod 0600 /var/lib/rabbitmq/.erlang.cookie ================================================ FILE: rabbitmq/templates/bin/_rabbitmq-liveness.sh.tpl ================================================ #!/usr/bin/env bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e if [ -f /tmp/rabbit-disable-liveness-probe ]; then exit 0 else exec rabbitmqctl ping fi ================================================ FILE: rabbitmq/templates/bin/_rabbitmq-password-hash.py.tpl ================================================ #!/usr/bin/env python3 {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. See here for explanation: http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-May/012765.html */}} import base64 import json import os import hashlib import re user = os.environ['RABBITMQ_ADMIN_USERNAME'] password = os.environ['RABBITMQ_ADMIN_PASSWORD'] guest_password = os.environ['RABBITMQ_GUEST_PASSWORD'] output_file = os.environ['RABBITMQ_DEFINITION_FILE'] def hash_rabbit_password(password): salt = os.urandom(4) tmp0 = salt + password.encode('utf-8') tmp1 = hashlib.sha512(tmp0).digest() salted_hash = salt + tmp1 pass_hash = base64.b64encode(salted_hash) return pass_hash.decode("utf-8") output = { "users": [{ "name": user, "password_hash": hash_rabbit_password(password), "hashing_algorithm": "rabbit_password_hashing_sha512", "tags": "administrator" }, { "name": "guest", "password_hash": hash_rabbit_password(guest_password), "hashing_algorithm": "rabbit_password_hashing_sha512", "tags": "administrator" } ] } if 'RABBITMQ_USERS' in os.environ: output.update({'vhosts': []}) output.update({'permissions': []}) users_creds = json.loads(os.environ['RABBITMQ_USERS']) for user, creds in users_creds.items(): if 'auth' in creds: for auth_key, auth_val in creds['auth'].items(): username = auth_val['username'] password = auth_val['password'] user_struct = { "name": username, "password_hash": hash_rabbit_password(password), "hashing_algorithm": "rabbit_password_hashing_sha512", "tags": "" } output['users'].append(user_struct) if 'path' in creds: for path in ( creds["path"] if isinstance(creds["path"], list) else [creds["path"]] ): vhost = re.sub("^/", "", path) vhost_struct = {"name": vhost} perm_struct = { "user": username, "vhost": vhost, "configure": ".*", "write": ".*", "read": ".*" } output['vhosts'].append(vhost_struct) output['permissions'].append(perm_struct) if 'RABBITMQ_AUXILIARY_CONFIGURATION' in os.environ: aux_conf = json.loads(os.environ['RABBITMQ_AUXILIARY_CONFIGURATION']) if aux_conf.get('policies', []): output['policies'] = aux_conf['policies'] if aux_conf.get('bindings', []): output['bindings'] = aux_conf['bindings'] if aux_conf.get('queues', []): output['queues'] = aux_conf['queues'] if aux_conf.get('exchanges', []): output['exchanges'] = aux_conf['exchanges'] with open(output_file, 'w') as f: f.write(json.dumps(output)) f.close() ================================================ FILE: rabbitmq/templates/bin/_rabbitmq-readiness.sh.tpl ================================================ #!/usr/bin/env bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e if [ -f /tmp/rabbit-disable-readiness ]; then exit 1 else exec rabbitmqctl ping fi ================================================ FILE: rabbitmq/templates/bin/_rabbitmq-start.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex function check_if_open () { HOST=$1 PORT=$2 timeout 10 bash -c "true &>/dev/null /dev/null } get_node_name () { TARGET_POD=$1 POD_NAME_PREFIX="$(echo "${MY_POD_NAME}" | awk 'BEGIN{FS=OFS="-"}{NF--; print}')" echo "${RABBITMQ_NODENAME}" | awk -F "@${MY_POD_NAME}." "{ print \$1 \"@${POD_NAME_PREFIX}-${TARGET_POD}.\" \$2 }" } function check_rabbit_node_ready () { TARGET_POD=$1 CLUSTER_SEED_NAME="$(get_node_name ${TARGET_POD})" CLUSTER_SEED_HOST="$(echo "${CLUSTER_SEED_NAME}" | awk -F '@' '{ print $NF }')" check_rabbit_node_health "${CLUSTER_SEED_NAME}" && \ check_if_open "${CLUSTER_SEED_HOST}" "${PORT_HTTP}" && \ check_if_open "${CLUSTER_SEED_HOST}" "${PORT_AMPQ}" && \ check_if_open "${CLUSTER_SEED_HOST}" "${PORT_CLUSTERING}" } POD_INCREMENT=$(echo "${MY_POD_NAME}" | awk -F '-' '{print $NF}') if ! [ "${POD_INCREMENT}" -eq "0" ] && ! [ -d "/var/lib/rabbitmq/mnesia" ] ; then echo 'This is not the 1st rabbit pod & has not been initialised' # disable liveness probe as it may take some time for the pod to come online. touch /tmp/rabbit-disable-liveness-probe POD_NAME_PREFIX="$(echo "${MY_POD_NAME}" | awk 'BEGIN{FS=OFS="-"}{NF--; print}')" for TARGET_POD in $(seq 0 +1 $((POD_INCREMENT - 1 ))); do END=$(($(date +%s) + 900)) while ! check_rabbit_node_ready "${TARGET_POD}"; do sleep 5 if [ "$(date +%s)" -gt "$END" ]; then echo "RabbitMQ pod ${TARGET_POD} not ready in time" exit 1 fi done done function reset_rabbit () { rabbitmqctl shutdown || true find /var/lib/rabbitmq/* ! -name 'definitions.json' ! -name '.erlang.cookie' -exec rm -rf {} + exit 1 } # Start RabbitMQ, but disable readiness from being reported so the pod is not # marked as up prematurely. touch /tmp/rabbit-disable-readiness rabbitmq-server & # Wait for server to start, and reset if it does not END=$(($(date +%s) + 180)) while ! rabbitmqctl -q cluster_status; do sleep 5 NOW=$(date +%s) [ $NOW -gt $END ] && reset_rabbit done # Wait for server to join cluster, reset if it does not POD_INCREMENT=$(echo "${MY_POD_NAME}" | awk -F '-' '{print $NF}') END=$(($(date +%s) + 180)) while ! rabbitmqctl -l --node $(get_node_name 0) -q cluster_status | grep -q "$(get_node_name ${POD_INCREMENT})"; do sleep 5 NOW=$(date +%s) [ $NOW -gt $END ] && reset_rabbit done # Shutdown the inital server rabbitmqctl shutdown rm -fv /tmp/rabbit-disable-readiness /tmp/rabbit-disable-liveness-probe fi {{- if .Values.forceBoot.enabled }} if [ "${POD_INCREMENT}" -eq "0" ] && [ -d "/var/lib/rabbitmq/mnesia/${RABBITMQ_NODENAME}" ]; then rabbitmqctl force_boot; fi {{- end}} exec rabbitmq-server ================================================ FILE: rabbitmq/templates/bin/_rabbitmq-test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # Extract connection details RABBIT_HOSTNAME=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $2}' \ | awk -F'[:/]' '{print $1}'` RABBIT_PORT=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $2}' \ | awk -F'[:/]' '{print $2}'` set +x # Extract Admin User creadential RABBITMQ_ADMIN_USERNAME=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $1}' \ | awk -F'[//:]' '{print $4}'` RABBITMQ_ADMIN_PASSWORD=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $1}' \ | awk -F'[//:]' '{print $5}'` set -x function rabbitmqadmin_authed () { set +x rabbitmqadmin \ {{- if .Values.manifests.certificates }} --ssl \ --ssl-disable-hostname-verification \ --ssl-ca-cert-file="/etc/rabbitmq/certs/ca.crt" \ --ssl-cert-file="/etc/rabbitmq/certs/tls.crt" \ --ssl-key-file="/etc/rabbitmq/certs/tls.key" \ {{- end }} --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} set -x } function rabbit_check_node_count () { echo "Checking node count " NODES_IN_CLUSTER=$(rabbitmqadmin_authed list nodes -f bash | wc -w) if [ "$NODES_IN_CLUSTER" -eq "$RABBIT_REPLICA_COUNT" ]; then echo "Number of nodes in cluster ($NODES_IN_CLUSTER) match number of desired pods ($NODES_IN_CLUSTER)" else echo "Number of nodes in cluster ($NODES_IN_CLUSTER) does not match number of desired pods ($RABBIT_REPLICA_COUNT)" exit 1 fi } # Check node count rabbit_check_node_count function rabbit_find_partitions () { NODE_INFO=$(mktemp) rabbitmqadmin_authed list nodes -f pretty_json | tee "${NODE_INFO}" cat "${NODE_INFO}" | python3 -c " import json, sys, traceback print('Checking cluster partitions') obj=json.load(sys.stdin) for num, node in enumerate(obj): try: partition = node['partitions'] if partition: raise Exception('cluster partition found: %s' % partition) except KeyError: print('Error: partition key not found for node %s' % node) print('No cluster partitions found') " rm -vf "${NODE_INFO}" } rabbit_find_partitions function rabbit_check_users_match () { echo "Checking users match on all nodes" NODES=$(rabbitmqadmin_authed list nodes -f bash) USER_LIST=$(mktemp --directory) echo "Found the following nodes: ${NODES}" for NODE in ${NODES}; do echo "Checking Node: ${NODE#*@}" rabbitmqadmin_authed list users -f bash > ${USER_LIST}/${NODE#*@} done cd ${USER_LIST}; diff -q --from-file $(ls ${USER_LIST}) echo "User lists match for all nodes" } # Check users match on all nodes rabbit_check_users_match ================================================ FILE: rabbitmq/templates/bin/_rabbitmq-wait-for-cluster.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -e # Extract connection details RABBIT_HOSTNAME=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $2}' \ | awk -F'[:/]' '{print $1}'` RABBIT_PORT=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $2}' \ | awk -F'[:/]' '{print $2}'` # Extract Admin User creadential RABBITMQ_ADMIN_USERNAME=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $1}' \ | awk -F'[//:]' '{print $4}'` RABBITMQ_ADMIN_PASSWORD=`echo $RABBITMQ_ADMIN_CONNECTION | awk -F'[@]' '{print $1}' \ | awk -F'[//:]' '{print $5}'` set -ex function rabbitmqadmin_authed () { set +x rabbitmqadmin \ {{- if .Values.manifests.certificates }} --ssl \ --ssl-disable-hostname-verification \ --ssl-ca-cert-file="/etc/rabbitmq/certs/ca.crt" \ --ssl-cert-file="/etc/rabbitmq/certs/tls.crt" \ --ssl-key-file="/etc/rabbitmq/certs/tls.key" \ {{- end }} --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} set -x } function active_rabbit_nodes () { rabbitmqadmin_authed list nodes -f bash | wc -w } until test "$(active_rabbit_nodes)" -ge "$RABBIT_REPLICA_COUNT"; do echo "Waiting for number of nodes in cluster to meet or exceed number of desired pods ($RABBIT_REPLICA_COUNT)" sleep 10 done function sorted_node_list () { rabbitmqadmin_authed list nodes -f bash | tr ' ' '\n' | sort | tr '\n' ' ' } if test "$(active_rabbit_nodes)" -gt "$RABBIT_REPLICA_COUNT"; then echo "There are more nodes registed in the cluster than desired, pruning the cluster" PRIMARY_NODE="$(sorted_node_list | awk '{ print $1; exit }')" until rabbitmqctl -l -n "${PRIMARY_NODE}" cluster_status >/dev/null 2>&1 ; do echo "Waiting for primary node to return cluster status" sleep 10 done echo "Current cluster:" rabbitmqctl -l -n "${PRIMARY_NODE}" cluster_status NODES_TO_REMOVE="$(sorted_node_list | awk "{print substr(\$0, index(\$0,\$$((RABBIT_REPLICA_COUNT+1))))}")" for NODE in ${NODES_TO_REMOVE}; do rabbitmqctl -l -n "${NODE}" stop_app || true rabbitmqctl -l -n "${PRIMARY_NODE}" forget_cluster_node "${NODE}" done echo "Updated cluster:" rabbitmqctl -l -n "${PRIMARY_NODE}" cluster_status fi ================================================ FILE: rabbitmq/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "oslo_messaging" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: rabbitmq/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" .deployment_name "rabbitmq-bin" | quote }} data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} rabbitmq-test.sh: | {{ tuple "bin/_rabbitmq-test.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbitmq-liveness.sh: | {{ tuple "bin/_rabbitmq-liveness.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbitmq-readiness.sh: | {{ tuple "bin/_rabbitmq-readiness.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbitmq-start.sh: | {{ tuple "bin/_rabbitmq-start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbitmq-cookie.sh: | {{ tuple "bin/_rabbitmq-cookie.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbitmq-password-hash.py: | {{ tuple "bin/_rabbitmq-password-hash.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbitmq-wait-for-cluster.sh: | {{ tuple "bin/_rabbitmq-wait-for-cluster.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{ end }} ================================================ FILE: rabbitmq/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{/* (aostapenko) rounds cpu limit in any permissible format to integer value (min 1) "100m" -> 1 "1100m" -> 1 "10900m" -> 10 0.3 -> 1 5.4 -> 5 */}} {{- define "get_erlvm_scheduler_num" -}} {{- $val := . | toString -}} {{- if regexMatch "^[0-9]*m$" $val -}} {{- $val = div (float64 (trimSuffix "m" $val)) 1000 -}} {{- end -}} {{/* NOTE(aostapenko) String with floating number does not convert well to int*/}} {{- $val | float64 | int | default 1 -}} {{- end -}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty $envAll.Values.conf.rabbitmq.cluster_formation.k8s.host -}} {{- $_ := print "kubernetes.default.svc." $envAll.Values.endpoints.cluster_domain_suffix | set $envAll.Values.conf.rabbitmq.cluster_formation.k8s "host" -}} {{- end -}} {{- if .Values.manifests.certificates }} {{- $_ := print "none" | set $envAll.Values.conf.rabbitmq.listeners "tcp" -}} {{- $_ := tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $envAll.Values.conf.rabbitmq.listeners "ssl.1" -}} {{- $_ := tuple "oslo_messaging" "internal" "https" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $envAll.Values.conf.rabbitmq "management.ssl.port" -}} {{- else }} {{- $_ := print $envAll.Values.conf.bind_address ":" ( tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup") | set $envAll.Values.conf.rabbitmq.listeners.tcp "1" -}} {{- $_ := tuple "oslo_messaging" "internal" "http" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $envAll.Values.conf.rabbit_additonal_conf "management.listener.port" -}} {{- end }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ printf "%s-%s" $envAll.deployment_name "rabbitmq-etc" | quote }} data: enabled_plugins: | {{ tuple "etc/_enabled_plugins.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbitmq.conf: | {{ include "rabbitmq.utils.to_rabbit_config" $envAll.Values.conf.rabbitmq | indent 4 }} {{- if not .Values.manifests.certificates }} {{ include "rabbitmq.utils.to_rabbit_config" $envAll.Values.conf.rabbit_additonal_conf | indent 4 }} {{- end }} {{- if .Values.conf.rabbit_advanced_config.enabled }} advanced.config: | [ {rabbit, [ {default_consumer_prefetch, {false,{{ .Values.conf.rabbit_advanced_config.default_consumer_prefetch }}}} ] } ]. {{- end }} {{- $erlvm_scheduler_num := include "get_erlvm_scheduler_num" .Values.pod.resources.server.limits.cpu }} {{- $erlvm_scheduler_conf := printf "+S %s:%s" $erlvm_scheduler_num $erlvm_scheduler_num }} {{- if .Values.manifests.config_ipv6 }} rabbitmq-env.conf: | SERVER_ADDITIONAL_ERL_ARGS={{ printf "+A 128 -kernel inetrc '/etc/rabbitmq/erl_inetrc' -proto_dist inet6_tcp %s" $erlvm_scheduler_conf | quote }} CTL_ERL_ARGS="-proto_dist inet6_tcp" erl_inetrc: | {inet6, true}. {{- else }} rabbitmq-env.conf: | SERVER_ADDITIONAL_ERL_ARGS={{ $erlvm_scheduler_conf | quote }} {{- end }} {{ end }} ================================================ FILE: rabbitmq/templates/etc/_enabled_plugins.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} [{{ include "helm-toolkit.utils.joinListWithComma" .Values.conf.enabled_plugins }}]. ================================================ FILE: rabbitmq/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: rabbitmq/templates/ingress-management.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if and .Values.manifests.ingress_management .Values.network.management.ingress.public }} {{- $envAll := . }} {{- if empty $envAll.Values.endpoints.oslo_messaging.hosts.public }} {{- $service_public_name := .deployment_name | trunc 12 }} {{- $_ := set $envAll.Values.endpoints.oslo_messaging.hosts "public" ( printf "%s-%s-%s" $service_public_name "mgr" ( $service_public_name | sha256sum | trunc 6 )) }} {{- end }} {{- $ingressOpts := dict "envAll" . "backendService" "management" "backendServiceType" "oslo_messaging" "backendPort" "http" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: rabbitmq/templates/job-cluster-wait.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.job_cluster_wait }} {{- $envAll := . }} {{- $serviceAccountName := print .deployment_name "-cluster-wait" }} {{ tuple $envAll "cluster_wait" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $protocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $protocol = "https" }} {{- end }} --- apiVersion: batch/v1 kind: Job metadata: name: "{{.deployment_name}}-cluster-wait" labels: {{ tuple $envAll "rabbitmq" "cluster-wait" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} "helm.sh/hook": "post-install,post-upgrade" "helm.sh/hook-weight": "5" "helm.sh/hook-delete-policy": before-hook-creation spec: template: metadata: labels: {{ tuple $envAll "rabbitmq" "cluster-wait" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "rabbitmq-cluster-wait" "containerNames" (list "init" "rabbitmq-cookie" "rabbitmq-rabbitmq-cluster-wait" ) | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "cluster_wait" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.rabbitmq.enabled }} {{ tuple $envAll "rabbitmq" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ $envAll.Values.labels.jobs.node_selector_key }}: {{ $envAll.Values.labels.test.node_selector_value | quote }} initContainers: {{ tuple $envAll "cluster_wait" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: rabbitmq-cookie {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "cluster_wait" "container" "rabbitmq_cookie" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/rabbitmq-cookie.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbitmq-bin mountPath: /tmp/rabbitmq-cookie.sh subPath: rabbitmq-cookie.sh readOnly: true - name: rabbitmq-data mountPath: /var/lib/rabbitmq - name: rabbitmq-erlang-cookie mountPath: /var/run/lib/rabbitmq/.erlang.cookie subPath: erlang_cookie readOnly: true containers: - name: rabbitmq-rabbitmq-cluster-wait {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "cluster_wait" "container" "rabbitmq_cluster_wait" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: RABBITMQ_ADMIN_CONNECTION value: {{ tuple "oslo_messaging" "internal" "user" $protocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | quote }} - name: RABBIT_REPLICA_COUNT value: {{ $envAll.Values.pod.replicas.server | quote }} command: - /tmp/rabbitmq-wait-for-cluster.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbitmq-bin mountPath: /tmp/rabbitmq-wait-for-cluster.sh subPath: rabbitmq-wait-for-cluster.sh readOnly: true - name: rabbitmq-data mountPath: /var/lib/rabbitmq {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_messaging.server.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: rabbitmq-data emptyDir: {} - name: rabbitmq-bin configMap: name: {{ printf "%s-%s" $envAll.deployment_name "rabbitmq-bin" | quote }} defaultMode: 0555 - name: rabbitmq-erlang-cookie secret: secretName: {{ printf "%s-%s" $envAll.deployment_name "erlang-cookie" | quote }} defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_messaging.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: rabbitmq/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "rabbitmq" -}} {{- if .Values.pod.tolerations.rabbitmq.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: rabbitmq/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "rabbitmq" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: rabbitmq/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{ if kindIs "string" $envAll.Values.dependencies.static.tests.jobs }} {{ if eq $envAll.Values.dependencies.static.tests.jobs "cluster_wait" }} {{ $_ := set $envAll.Values.dependencies.static.tests "jobs" ( list ( print $envAll.deployment_name "-cluster-wait" ) ) }} {{ end }} {{ end }} {{- $serviceAccountName := print .deployment_name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $protocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $protocol = "https" }} {{- end }} --- apiVersion: v1 kind: Pod metadata: name: "{{.deployment_name}}-test" labels: {{ tuple $envAll "rabbitmq" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} "helm.sh/hook": test-success {{ dict "envAll" $envAll "podName" "rabbitmq-rabbitmq-test" "containerNames" (list "init" "rabbitmq-rabbitmq-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.rabbitmq.enabled }} {{ tuple $envAll "rabbitmq" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} nodeSelector: {{ $envAll.Values.labels.test.node_selector_key }}: {{ $envAll.Values.labels.test.node_selector_value | quote }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: rabbitmq-rabbitmq-test {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "rabbitmq_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: - name: RABBITMQ_ADMIN_CONNECTION value: {{ tuple "oslo_messaging" "internal" "user" $protocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | quote }} - name: RABBIT_REPLICA_COUNT value: {{ $envAll.Values.pod.replicas.server | quote }} command: - /tmp/rabbitmq-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbitmq-bin mountPath: /tmp/rabbitmq-test.sh subPath: rabbitmq-test.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.oslo_messaging.server.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} volumes: - name: pod-tmp emptyDir: {} - name: rabbitmq-bin configMap: name: {{ printf "%s-%s" $envAll.deployment_name "rabbitmq-bin" | quote }} defaultMode: 0555 {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.oslo_messaging.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{- end }} ================================================ FILE: rabbitmq/templates/secret-erlang-cookie.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.secret_erlang_cookie }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.deployment_name "erlang-cookie" | quote }} type: Opaque data: erlang_cookie: {{ $envAll.Values.endpoints.oslo_messaging.auth.erlang_cookie | b64enc -}} {{- end }} ================================================ FILE: rabbitmq/templates/secret-rabbit-admin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if .Values.manifests.secret_admin_user }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.deployment_name "admin-user" | quote }} type: Opaque data: RABBITMQ_ADMIN_USERNAME: {{ $envAll.Values.endpoints.oslo_messaging.auth.user.username | b64enc }} RABBITMQ_ADMIN_PASSWORD: {{ $envAll.Values.endpoints.oslo_messaging.auth.user.password | b64enc }} RABBITMQ_GUEST_PASSWORD: {{ $envAll.Values.endpoints.oslo_messaging.auth.guest.password | b64enc }} {{- end }} ================================================ FILE: rabbitmq/templates/secret-rabbitmq-users-credentials.yaml ================================================ {{/* Copyright 2019 Mirantis Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.conf.users }} {{- $envAll := . }} --- apiVersion: v1 kind: Secret metadata: name: {{ printf "%s-%s" $envAll.deployment_name "users-credentials" | quote }} labels: {{ tuple $envAll "rabbitmq" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} type: Opaque data: RABBITMQ_USERS: {{ toJson .Values.conf.users | b64enc }} {{- end }} ================================================ FILE: rabbitmq/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: rabbitmq/templates/service-ingress-management.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- if and .Values.manifests.service_ingress_management .Values.network.management.ingress.public }} {{- $envAll := . }} {{- if empty $envAll.Values.endpoints.oslo_messaging.hosts.public }} {{- $service_public_name := .deployment_name | trunc 12 }} {{- $_ := set $envAll.Values.endpoints.oslo_messaging.hosts "public" ( printf "%s-%s-%s" $service_public_name "mgr" ( $service_public_name | sha256sum | trunc 6 )) }} {{- end }} {{- $serviceIngressOpts := dict "envAll" . "backendService" "management" "backendServiceType" "oslo_messaging" "backendPort" "http" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: rabbitmq/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} {{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.rabbitmq }} {{- $protocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $protocol = "https" }} {{- end }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "oslo_messaging" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "rabbitmq" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{- if $envAll.Values.monitoring.prometheus.enabled }} {{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} {{- end }} spec: clusterIP: None ports: - port: {{ tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: amqp - port: {{ add (tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup") 20000 }} name: clustering - port: {{ tuple "oslo_messaging" "internal" $protocol . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} name: {{ printf "%s" $protocol }} - name: metrics port: {{ tuple "oslo_messaging" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} selector: {{ tuple $envAll "rabbitmq" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ end }} ================================================ FILE: rabbitmq/templates/statefulset.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- define "rabbitmqReadinessProbeTemplate" }} exec: command: - /tmp/rabbitmq-readiness.sh {{- end }} {{- define "rabbitmqLivenessProbeTemplate" }} exec: command: - /tmp/rabbitmq-liveness.sh {{- end }} {{/* (aostapenko) rounds cpu limit in any permissible format to integer value (min 1) "100m" -> 1 "1100m" -> 1 "10900m" -> 10 0.3 -> 1 5.4 -> 5 */}} {{- define "get_erlvm_scheduler_num" -}} {{- $val := . | toString -}} {{- if regexMatch "^[0-9]*m$" $val -}} {{- $val = div (float64 (trimSuffix "m" $val)) 1000 -}} {{- end -}} {{/* NOTE(aostapenko) String with floating number does not convert well to int */}} {{- $val | float64 | int | default 1 -}} {{- end -}} {{- if .Values.manifests.statefulset }} {{- $envAll := . }} {{- $rcControllerName := printf "%s-%s" $envAll.deployment_name "rabbitmq" }} {{ tuple $envAll "rabbitmq" $rcControllerName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $protocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $protocol = "https" }} {{- end }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ $rcControllerName | quote }} namespace: {{ .Release.Namespace }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ $rcControllerName | quote }} subjects: - kind: ServiceAccount name: {{ $rcControllerName | quote }} namespace: {{ .Release.Namespace }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ $rcControllerName | quote }} namespace: {{ .Release.Namespace }} rules: - apiGroups: - "" - extensions - batch - apps verbs: - get - list resources: - services - endpoints --- apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ $rcControllerName | quote }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "rabbitmq" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: {{ tuple "oslo_messaging" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} replicas: {{ $envAll.Values.pod.replicas.server }} podManagementPolicy: "Parallel" selector: matchLabels: {{ tuple $envAll "rabbitmq" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "rabbitmq" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} secret-rabbit-admin-hash: {{ tuple "secret-rabbit-admin.yaml" . | include "helm-toolkit.utils.hash" }} secret-erlang-cookie-hash: {{ tuple "secret-erlang-cookie.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "rabbitmq" "containerNames" (list "init" "rabbitmq-password" "rabbitmq-cookie" "rabbitmq-perms" "rabbitmq") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "server" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $rcControllerName | quote }} affinity: {{ tuple $envAll "rabbitmq" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.rabbitmq.enabled }} {{ tuple $envAll "rabbitmq" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ $envAll.Values.labels.server.node_selector_key }}: {{ $envAll.Values.labels.server.node_selector_value | quote }} initContainers: {{ tuple $envAll "rabbitmq" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: rabbitmq-password {{ tuple $envAll "rabbitmq_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "rabbitmq_password" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/rabbitmq-password-hash.py env: - name: RABBITMQ_ADMIN_USERNAME valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.deployment_name "admin-user" | quote }} key: RABBITMQ_ADMIN_USERNAME - name: RABBITMQ_ADMIN_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.deployment_name "admin-user" | quote }} key: RABBITMQ_ADMIN_PASSWORD - name: RABBITMQ_GUEST_PASSWORD valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.deployment_name "admin-user" | quote }} key: RABBITMQ_GUEST_PASSWORD - name: RABBITMQ_DEFINITION_FILE value: "{{ index $envAll.Values.conf.rabbitmq "management.load_definitions" }}" {{- if .Values.conf.users }} - name: RABBITMQ_USERS valueFrom: secretKeyRef: name: {{ printf "%s-%s" $envAll.deployment_name "users-credentials" | quote }} key: RABBITMQ_USERS {{- end }} {{- if .Values.conf.aux_conf }} - name: RABBITMQ_AUXILIARY_CONFIGURATION value: {{ toJson $envAll.Values.conf.aux_conf | quote }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbitmq-data mountPath: /var/lib/rabbitmq - name: rabbitmq-bin mountPath: /tmp/rabbitmq-password-hash.py subPath: rabbitmq-password-hash.py readOnly: true - name: rabbitmq-cookie {{ tuple $envAll "rabbitmq" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "rabbitmq_cookie" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/rabbitmq-cookie.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbitmq-bin mountPath: /tmp/rabbitmq-cookie.sh subPath: rabbitmq-cookie.sh readOnly: true - name: rabbitmq-data mountPath: /var/lib/rabbitmq - name: rabbitmq-erlang-cookie mountPath: /var/run/lib/rabbitmq/.erlang.cookie subPath: erlang_cookie readOnly: true {{- if $envAll.Values.volume.chown_on_start }} - name: rabbitmq-perms {{ tuple $envAll "rabbitmq" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "rabbitmq_perms" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - chown - -R - "{{ $envAll.Values.pod.security_context.server.pod.runAsUser }}" - /var/lib/rabbitmq volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbitmq-data mountPath: /var/lib/rabbitmq {{- end }} containers: - name: rabbitmq {{ tuple $envAll "rabbitmq" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "server" "container" "rabbitmq" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/rabbitmq-start.sh ports: - name: {{ printf "%s" $protocol }} protocol: TCP containerPort: {{ tuple "oslo_messaging" "internal" $protocol . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.network.host_namespace }} hostPort: {{ tuple "oslo_messaging" "internal" $protocol . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} - name: amqp protocol: TCP containerPort: {{ tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.network.host_namespace }} hostPort: {{ tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} - name: clustering protocol: TCP containerPort: {{ add (tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup") 20000 }} {{- if .Values.network.host_namespace }} hostPort: {{ add (tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup") 20000 }} {{- end }} - name: metrics containerPort: {{ tuple "oslo_messaging" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} protocol: TCP env: - name: MY_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: MY_POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: RABBITMQ_USE_LONGNAME value: "true" - name: RABBITMQ_NODENAME value: "rabbit@$(MY_POD_NAME).{{ tuple "oslo_messaging" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }}" - name: K8S_SERVICE_NAME value: {{ tuple "oslo_messaging" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} - name: K8S_HOSTNAME_SUFFIX value: ".{{ tuple "oslo_messaging" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }}" - name: RABBITMQ_ERLANG_COOKIE value: "{{ $envAll.Values.endpoints.oslo_messaging.auth.erlang_cookie }}" - name: PORT_HTTP value: "{{ tuple "oslo_messaging" "internal" $protocol . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" - name: PORT_AMPQ value: "{{ tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" - name: PORT_CLUSTERING value: "{{ add (tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.endpoints.endpoint_port_lookup") 20000 }}" {{- if ne (.Values.conf.feature_flags | default "") "default" }} - name: RABBITMQ_FEATURE_FLAGS value: "{{ .Values.conf.feature_flags }}" {{- end }} {{ dict "envAll" $envAll "component" "rabbitmq" "container" "rabbitmq" "type" "readiness" "probeTemplate" (include "rabbitmqReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} {{ dict "envAll" $envAll "component" "rabbitmq" "container" "rabbitmq" "type" "liveness" "probeTemplate" (include "rabbitmqLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | trim | indent 10 }} lifecycle: preStop: exec: command: - rabbitmqctl - stop_app volumeMounts: - name: pod-tmp mountPath: /tmp - name: rabbitmq-data mountPath: /var/lib/rabbitmq - name: rabbitmq-bin mountPath: /tmp/rabbitmq-start.sh subPath: rabbitmq-start.sh readOnly: true - name: rabbitmq-bin mountPath: /tmp/rabbitmq-readiness.sh subPath: rabbitmq-readiness.sh readOnly: true - name: rabbitmq-bin mountPath: /tmp/rabbitmq-liveness.sh subPath: rabbitmq-liveness.sh readOnly: true - name: rabbitmq-etc mountPath: /etc/rabbitmq/enabled_plugins subPath: enabled_plugins readOnly: true - name: rabbitmq-etc mountPath: /etc/rabbitmq/rabbitmq.conf subPath: rabbitmq.conf readOnly: true {{- if .Values.conf.rabbit_advanced_config.enabled }} - name: rabbitmq-etc mountPath: /etc/rabbitmq/advanced.config subPath: advanced.config readOnly: true {{- end }} - name: rabbitmq-etc mountPath: /etc/rabbitmq/rabbitmq-env.conf subPath: rabbitmq-env.conf readOnly: true {{- if .Values.manifests.config_ipv6 }} - name: rabbitmq-etc mountPath: /etc/rabbitmq/erl_inetrc subPath: erl_inetrc readOnly: true {{- end }} {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_messaging.server.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: rabbitmq-bin configMap: name: {{ printf "%s-%s" $envAll.deployment_name "rabbitmq-bin" | quote }} defaultMode: 0555 - name: rabbitmq-etc configMap: name: {{ printf "%s-%s" $envAll.deployment_name "rabbitmq-etc" | quote }} defaultMode: 0444 - name: rabbitmq-erlang-cookie secret: secretName: {{ printf "%s-%s" $envAll.deployment_name "erlang-cookie" | quote }} defaultMode: 0444 {{ dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.oslo_messaging.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- if not $envAll.Values.volume.enabled }} - name: rabbitmq-data {{- if .Values.volume.use_local_path.enabled }} hostPath: path: {{ .Values.volume.use_local_path.host_path }} type: DirectoryOrCreate {{- else }} emptyDir: {} {{- end }} {{- end }} {{- if $envAll.Values.volume.enabled }} volumeClaimTemplates: - metadata: name: rabbitmq-data spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: {{ $envAll.Values.volume.size }} {{- if ne .Values.volume.class_name "default" }} storageClassName: {{ $envAll.Values.volume.class_name }} {{- end }} {{- end }} {{ end }} ================================================ FILE: rabbitmq/templates/utils/_to_rabbit_config.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "rabbitmq.utils.to_rabbit_config" -}} {{- range $top_key, $top_value := . }} {{- if kindIs "map" $top_value -}} {{- range $second_key, $second_value := . }} {{- if kindIs "map" $second_value -}} {{- range $third_key, $third_value := . }} {{- if kindIs "map" $third_value -}} {{ $top_key }}.{{ $second_key }}.{{ $third_key }} = wow {{ else -}} {{ $top_key }}.{{ $second_key }}.{{ $third_key }} = {{ $third_value }} {{ end -}} {{- end -}} {{ else -}} {{ $top_key }}.{{ $second_key }} = {{ $second_value }} {{ end -}} {{- end -}} {{ else -}} {{ $top_key }} = {{ $top_value }} {{ end -}} {{- end -}} {{- end -}} ================================================ FILE: rabbitmq/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for rabbitmq. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled jobs: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: rabbitmq_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbitmq: quay.io/airshipit/rabbitmq:3.10.18 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy scripted_test: quay.io/airshipit/rabbitmq:3.10.18-management image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync # forceBoot: executes 'rabbitmqctl force_boot' to force boot on # cluster shut down unexpectedly in an unknown order. # ref: https://www.rabbitmq.com/rabbitmqctl.8.html#force_boot forceBoot: enabled: false pod: probes: rabbitmq: rabbitmq: readiness: enabled: true params: initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 10 successThreshold: 1 failureThreshold: 3 liveness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 10 successThreshold: 1 failureThreshold: 5 security_context: server: pod: runAsUser: 999 container: rabbitmq_password: runAsUser: 0 readOnlyRootFilesystem: true rabbitmq_cookie: runAsUser: 0 readOnlyRootFilesystem: true rabbitmq_perms: runAsUser: 0 readOnlyRootFilesystem: true rabbitmq: allowPrivilegeEscalation: false runAsUser: 999 readOnlyRootFilesystem: false cluster_wait: pod: runAsUser: 999 container: rabbitmq_cluster_wait: allowPrivilegeEscalation: false readOnlyRootFilesystem: true rabbitmq_cookie: allowPrivilegeEscalation: false readOnlyRootFilesystem: true test: pod: runAsUser: 999 container: rabbitmq_test: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: rabbitmq: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule replicas: server: 2 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: mariadb: min_available: 0 resources: enabled: false server: limits: memory: "128Mi" cpu: "500m" requests: memory: "128Mi" cpu: "500m" jobs: tests: limits: memory: "1024Mi" cpu: "2000m" requests: memory: "128Mi" cpu: "100m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conf: enabled_plugins: - rabbitmq_management - rabbitmq_peer_discovery_k8s - rabbitmq_prometheus # This IP could be IPv4/IPv6 and the tcp port will be appended to it and eventually it is set to rabbitmq.listeners.tcp.1 bind_address: "::" rabbitmq: listeners: tcp: # NOTE(portdirect): This is always defined via the endpoints section. 1: null cluster_formation: peer_discovery_backend: rabbit_peer_discovery_k8s k8s: address_type: hostname node_cleanup: interval: "10" only_log_warning: "true" cluster_partition_handling: autoheal queue_master_locator: min-masters loopback_users.guest: "false" management.load_definitions: "/var/lib/rabbitmq/definitions.json" rabbit_additonal_conf: # This confinguration is used for non TLS deployments management.listener.ip: "::" management.listener.port: null rabbit_advanced_config: enabled: false default_consumer_prefetch: 250 # Feature Flags is introduced in RabbitMQ 3.8.0 # To deploy with standard list of feature, leave as default # To deploy with specific feature, separate each feature with comma # To deploy with all features disabled, leave blank or empty feature_flags: default users: {} # define users in the section below which have to be # created by rabbitmq at start up stage through definitions.json # file and enable job_users_create manifest. # users: # keystone_service: # auth: # keystone_username: # username: keystone # password: password # path: /keystone aux_conf: {} # aux_conf can be used to pass additional options to definitions.json, allowed keys are: # - policies # - bindings # - parameters # - queues # - exchanges # vhosts,users and permissions are created in users section of values. # aux_conf: # policies: # - vhost: "keystone" # name: "ha_ttl_keystone" # definition: # #mirror messges to other nodes in rmq cluster # ha-mode: "all" # ha-sync-mode: "automatic" # #70s # message-ttl: 70000 # priority: 0 # apply-to: all # pattern: '^(?!amq\.).*' dependencies: dynamic: common: local_image_registry: jobs: - rabbitmq-image-repo-sync services: - endpoint: node service: local_image_registry static: rabbitmq: jobs: null tests: services: - endpoint: internal service: oslo_messaging # NOTE (portdirect): this key is somewhat special, if set to the string # `cluster_wait` then the job dep will be populated with a single value # containing the generated name for the `cluster_wait` job name. jobs: cluster_wait cluster_wait: services: - endpoint: internal service: oslo_messaging image_repo_sync: services: - endpoint: internal service: local_image_registry monitoring: prometheus: enabled: true rabbitmq: scrape: true network: host_namespace: false management: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / secrets: oci_image_registry: rabbitmq: rabbitmq-oci-image-registry-key tls: oslo_messaging: server: internal: rabbitmq-tls-direct # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false rabbitmq: username: rabbitmq password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null monitoring: name: prometheus namespace: null hosts: default: prom-metrics public: prometheus host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9090 public: 80 oslo_messaging: auth: erlang_cookie: openstack-cookie user: username: rabbitmq password: password guest: password: password hosts: default: rabbitmq # NOTE(portdirect): the public host is only used to the management WUI # If left empty, the release name sha suffixed with mgr, will be used to # produce an unique hostname. public: null host_fqdn_override: default: null path: / scheme: rabbit port: clustering: # NOTE(portdirect): the value for this port is driven by amqp+20000 # it should not be set manually. default: null amqp: default: 5672 http: default: 15672 public: 80 metrics: default: 15692 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns_tcp: default: 53 dns: default: 53 protocol: UDP network_policy: rabbitmq: ingress: - {} egress: - {} volume: use_local_path: enabled: false host_path: /var/lib/rabbitmq chown_on_start: true enabled: true class_name: general size: 768Mi manifests: certificates: false configmap_bin: true configmap_etc: true config_ipv6: false ingress_management: true job_cluster_wait: true job_image_repo_sync: true monitoring: prometheus: configmap_bin: false network_policy: false pod_test: true secret_admin_user: true secret_erlang_cookie: true secret_registry: true service_discovery: true service_ingress_management: true service: true statefulset: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: rally/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm rally name: rally version: 2025.2.0 home: https://docs.openstack.org/developer/rally icon: https://www.openstack.org/themes/openstack/images/project-mascots/rally/OpenStack_Project_rally_vertical.png sources: - https://opendev.org/openstack/rally - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: rally/README.rst ================================================ ===== Rally ===== This chart provides a benchmarking tool for OpenStack services that allows us to test our cloud at scale. This chart leverages the Kolla image for Rally and includes a templated configuration file that allows configuration overrides similar to other charts in OpenStack-Helm. You can choose which services to benchmark by changing the services listed in the ``values.yaml`` file under the ``enabled_tests`` key. Installation ------------ This chart can be deployed by running the following command: :: helm install --name=rally ./rally --namespace=openstack This will install Rally into your cluster appropriately. When you run this install command, the chart will bring up a few jobs that will complete the benchmarking of the OpenStack services that you have specified. ================================================ FILE: rally/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: rally/templates/bin/_manage-db.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex function create_or_update_db () { revisionResults=$(rally db revision) if [ $revisionResults = "None" ] then rally db create else rally db upgrade fi } create_or_update_db ================================================ FILE: rally/templates/bin/_run-task.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex : ${RALLY_ENV_NAME:="openstack-helm"} function run_rally () { CURRENT_TEST=$1 rally deployment use ${RALLY_ENV_NAME} rally deployment check rally task validate /tasks/rally/${CURRENT_TEST}.yaml rally task start /tasks/rally/${CURRENT_TEST}.yaml rally task list rally task report --out /var/lib/rally/data/${CURRENT_TEST}.html rally task sla-check } function create_deployment () { listResults=$(rally deployment list) if [ $(echo $listResults | awk '{print $1;}') = "There" ] then rally deployment create --fromenv --name ${RALLY_ENV_NAME} fi } create_deployment IFS=','; for TEST in $ENABLED_TESTS; do run_rally $TEST done exit 0 ================================================ FILE: rally/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: rally-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} manage-db.sh: | {{ tuple "bin/_manage-db.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} run-task.sh: | {{ tuple "bin/_run-task.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: rally/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.rally.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.rally.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.rally.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.rally.keystone_authtoken "region_name" .Values.endpoints.identity.auth.rally.region_name -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.rally.keystone_authtoken "project_name" .Values.endpoints.identity.auth.rally.project_name -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.rally.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.rally.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.rally.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.rally.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.username -}} {{- $_ := set .Values.conf.rally.keystone_authtoken "username" .Values.endpoints.identity.auth.rally.username -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.password -}} {{- $_ := set .Values.conf.rally.keystone_authtoken "password" .Values.endpoints.identity.auth.rally.password -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.rally.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.rally.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.rally.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.rally.database.connection)) (empty .Values.conf.rally.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "rally" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set .Values.conf.rally.database "connection" -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: rally-etc type: Opaque data: rally.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.rally | b64enc }} {{- end }} ================================================ FILE: rally/templates/configmap-tasks.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_tasks }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: rally-tasks data: authenticate.yaml: | {{ toYaml .Values.conf.rally_tasks.authenticate_task | indent 4 }} ceilometer.yaml: | {{ toYaml .Values.conf.rally_tasks.ceilometer_task | indent 4 }} cinder.yaml: | {{ toYaml .Values.conf.rally_tasks.cinder_task | indent 4 }} glance.yaml: | {{ toYaml .Values.conf.rally_tasks.glance_task | indent 4 }} heat.yaml: | {{ toYaml .Values.conf.rally_tasks.heat_task | indent 4 }} keystone.yaml: | {{ toYaml .Values.conf.rally_tasks.keystone_task | indent 4 }} magnum.yaml: | {{ toYaml .Values.conf.rally_tasks.magnum_task | indent 4 }} neutron.yaml: | {{ toYaml .Values.conf.rally_tasks.neutron_task | indent 4 }} nova.yaml: | {{ toYaml .Values.conf.rally_tasks.nova_task | indent 4 }} swift.yaml: | {{ toYaml .Values.conf.rally_tasks.swift_task | indent 4 }} {{- end }} ================================================ FILE: rally/templates/configmap-test-templates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_test_templates }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: heat-tasks-test-templates data: {{- range $key, $value := $envAll.Values.conf.rally_tasks.heat_tests }} {{- $file := printf "%s.%s" (replace "_" "-" $key) "yaml" }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" (index $envAll.Values.conf.rally_tasks.heat_tests $key ) "key" $file ) | indent 2 }} {{- end }} {{- end }} ================================================ FILE: rally/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: rally/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_bootstrap }} {{- $envAll := . }} {{- if .Values.bootstrap.enabled }} {{- $mounts_rally_bootstrap := .Values.pod.mounts.rally_bootstrap.rally_bootstrap }} {{- $mounts_rally_bootstrap_init := .Values.pod.mounts.rally_bootstrap.init_container }} {{- $serviceAccountName := "rally-bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} {{- $tlsSecret := "" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $tlsSecret = .Values.secrets.tls.identity.api.internal | default "" -}} {{- end -}} --- apiVersion: batch/v1 kind: Job metadata: name: rally-bootstrap annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "rally" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "bootstrap" $mounts_rally_bootstrap_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: rally-bootstrap {{ tuple $envAll "bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" (ne $tlsSecret "") }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: rally-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true {{ dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_rally_bootstrap.volumeMounts }}{{ toYaml $mounts_rally_bootstrap.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: rally-bin configMap: name: rally-bin defaultMode: 0555 {{- dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_rally_bootstrap.volumes }}{{ toYaml $mounts_rally_bootstrap.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} ================================================ FILE: rally/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "rally" -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: rally/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "rally" -}} {{- $_ := $imageRepoSyncJob "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) }} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: rally/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_endpoints }} {{- $envAll := . }} {{- $serviceAccountName := "rally-ks-endpoints" }} {{ tuple $envAll "ks_endpoints" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- {{- $tlsSecret := "" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $tlsSecret = .Values.secrets.tls.identity.api.internal | default "" -}} {{- end }} apiVersion: batch/v1 kind: Job metadata: name: rally-ks-endpoints annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" spec: template: metadata: labels: {{ tuple $envAll "rally" "ks-endpoints" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "ks_endpoints" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{- range $key1, $osServiceType := tuple "benchmark" }} {{- range $key2, $osServiceEndPoint := tuple "admin" "internal" "public" }} - name: {{ $osServiceType }}-ks-endpoints-{{ $osServiceEndPoint }} {{ tuple $envAll "ks_endpoints" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_endpoints | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/ks-endpoints.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ks-endpoints-sh mountPath: /tmp/ks-endpoints.sh subPath: ks-endpoints.sh readOnly: true {{ dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (ne $tlsSecret "") }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: OS_SVC_ENDPOINT value: {{ $osServiceEndPoint }} - name: OS_SERVICE_NAME value: {{ tuple $osServiceType $envAll | include "helm-toolkit.endpoints.keystone_endpoint_name_lookup" }} - name: OS_SERVICE_TYPE value: {{ $osServiceType }} - name: OS_SERVICE_ENDPOINT value: {{ tuple $osServiceType $osServiceEndPoint "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} {{- end }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: ks-endpoints-sh configMap: name: rally-bin defaultMode: 0555 {{- dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: rally/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_service }} {{- $envAll := . }} {{- $serviceAccountName := "rally-ks-service" }} {{ tuple $envAll "ks_service" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- {{- $tlsSecret := "" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $tlsSecret = .Values.secrets.tls.identity.api.internal | default "" -}} {{- end }} apiVersion: batch/v1 kind: Job metadata: name: rally-ks-service annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" spec: template: metadata: labels: {{ tuple $envAll "rally" "ks-service" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "ks_service" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: {{- range $key1, $osServiceType := tuple "benchmark" }} - name: {{ $osServiceType }}-ks-service-registration {{ tuple $envAll "ks_service" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_service | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/ks-service.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: ks-service-sh mountPath: /tmp/ks-service.sh subPath: ks-service.sh readOnly: true {{ dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: {{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" (ne $tlsSecret "") }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: OS_SERVICE_NAME value: {{ tuple $osServiceType $envAll | include "helm-toolkit.endpoints.keystone_endpoint_name_lookup" }} - name: OS_SERVICE_TYPE value: {{ $osServiceType }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: ks-service-sh configMap: name: rally-bin defaultMode: 0555 {{- dict "enabled" (ne $tlsSecret "") "name" $tlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: rally/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "rally" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.identity.api.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) }} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: rally/templates/job-manage-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_manage_db }} {{- $envAll := . }} {{- $serviceAccountName := "rally-manage-db" }} {{ tuple $envAll "manage_db" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: rally-manage-db annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "2" spec: template: metadata: labels: {{ tuple $envAll "rally" "manage-db" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "manage_db" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: rally-manage-db {{ tuple $envAll "rally_db_sync" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.manage_db | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/manage-db.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: rally-bin mountPath: /tmp/manage-db.sh subPath: manage-db.sh readOnly: true - name: etcrally mountPath: /etc/rally - name: rally-etc mountPath: /etc/rally/rally.conf subPath: rally.conf readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: etcrally emptyDir: {} - name: rally-etc secret: secretName: rally-etc defaultMode: 0444 - name: rally-bin configMap: name: rally-bin defaultMode: 0555 {{- end }} ================================================ FILE: rally/templates/job-run-task.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_run_task }} {{- $envAll := . }} {{- $serviceAccountName := "rally-run-task" }} {{ tuple $envAll "run_task" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: rally-run-task annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "3" spec: backoffLimit: {{ .Values.jobs.run_tasks.backoffLimit }} template: metadata: labels: {{ tuple $envAll "rally" "run-task" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: {{ .Values.jobs.run_tasks.restartPolicy }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "run_task" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: rally-run-task-init {{ tuple $envAll "run_task" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.run_task | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: 0 command: - chown - -R - "rally:" - /var/lib/rally/data volumeMounts: - name: pod-tmp mountPath: /tmp - name: rally-reports mountPath: /var/lib/rally/data containers: - name: rally-run-task {{ tuple $envAll "run_task" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.run_task | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/run-task.sh env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/rally/certs/ca.crt" {{- end }} - name: ENABLED_TESTS value: {{ include "helm-toolkit.utils.joinListWithComma" .Values.enabled_tasks }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: rally-bin mountPath: /tmp/run-task.sh subPath: run-task.sh readOnly: true - name: etcrally mountPath: /etc/rally - name: rally-etc mountPath: /etc/rally/rally.conf subPath: rally.conf readOnly: true - name: rally-tasks mountPath: /tasks/rally readOnly: true - name: heat-tasks-test-templates mountPath: /tmp/tasks/test-templates readOnly: true - name: rally-reports mountPath: /var/lib/rally/data {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.identity.api.internal "path" "/etc/rally/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: etcrally emptyDir: {} - name: rally-etc secret: secretName: rally-etc defaultMode: 0444 - name: rally-tasks configMap: name: rally-tasks defaultMode: 0444 - name: rally-bin configMap: name: rally-bin defaultMode: 0555 - name: heat-tasks-test-templates configMap: name: heat-tasks-test-templates - name: rally-reports persistentVolumeClaim: claimName: {{ .Values.pvc.name }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: rally/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: rally-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.rally.min_available }} selector: matchLabels: {{ tuple $envAll "rally" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: rally/templates/pvc-rally.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pvc_rally }} --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: {{ .Values.pvc.name }} spec: accessModes: - ReadWriteOnce resources: requests: storage: {{ .Values.pvc.requests.storage }} storageClassName: {{ .Values.pvc.storage_class }} {{- end }} ================================================ FILE: rally/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "rally" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: DB_CONNECTION: {{ tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc -}} {{- end }} {{- end }} ================================================ FILE: rally/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "rally" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: rally/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: rally/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for rally. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- release_group: null labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: bootstrap: docker.io/xrally/xrally-openstack:2.0.0 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: docker.io/xrally/xrally-openstack:2.0.0 rally_db_sync: docker.io/xrally/xrally-openstack:2.0.0 run_task: docker.io/xrally/xrally-openstack:2.0.0 ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync enabled_tasks: # NOTE(alraddarla): not enabled # - ceilometerNOTE(alraddarla): not enabled - cinder - glance - heat - keystone - magnum # NOTE(alraddarla): need a network setup in the gate to fully test # - neutron - nova # NOTE(alraddarla): not enabled # - swift pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 mounts: rally_api: init_container: null rally_api: volumeMounts: volumes: rally_bootstrap: init_container: null rally_bootstrap: volumeMounts: volumes: resources: enabled: false jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" manage_db: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" run_task: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" bootstrap: enabled: false script: | openstack token issue jobs: run_tasks: backoffLimit: 6 restartPolicy: OnFailure dependencies: dynamic: common: local_image_registry: jobs: - rally-image-repo-sync services: - endpoint: node service: local_image_registry static: db_init: services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - rally-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity manage_db: jobs: - rally-ks-user - rally-ks-endpoints - rally-db-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity run_task: jobs: - rally-manage-db services: - endpoint: internal service: oslo_db - endpoint: internal service: identity image_repo_sync: services: - endpoint: internal service: local_image_registry # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: rally-keystone-admin rally: rally-keystone-user oslo_db: admin: rally-db-admin rally: rally-db-user oci_image_registry: rally: rally-oci-image-registry tls: identity: api: public: keystone-tls-public internal: keystone-tls-api endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false rally: username: rally password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default rally: role: admin region_name: RegionOne username: rally password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 benchmark: name: rally hosts: default: rally-api public: rally host_fqdn_override: default: null path: default: /v1 scheme: default: http port: api: default: 9312 public: 80 oslo_db: auth: admin: username: root password: password rally: username: rally password: password hosts: default: mariadb host_fqdn_override: default: null path: /rally scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: keystone_authtoken: secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 pvc: name: pvc-rally requests: storage: 2Gi storage_class: general conf: rally: keystone_authtoken: auth_type: password auth_version: v3 rally_api: bind_port: 9312 database: # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" rally_tasks: heat_tests: autoscaling_group: heat_template_version: '2013-05-23' outputs: scaling_url: value: get_attr: - scaling_policy - alarm_url parameters: flavor: constraints: - custom_constraint: nova.flavor default: m1.tiny type: string image: constraints: - custom_constraint: glance.image default: cirros-0.3.4-x86_64-uec type: string max_size: constraints: - range: min: 1 default: 5 type: number scaling_adjustment: default: 1 type: number resources: asg: properties: desired_capacity: 3 max_size: get_param: max_size min_size: 1 resource: properties: flavor: get_param: flavor image: get_param: image type: 'OS::Nova::Server' type: 'OS::Heat::AutoScalingGroup' scaling_policy: properties: adjustment_type: change_in_capacity auto_scaling_group_id: get_resource: asg scaling_adjustment: get_param: scaling_adjustment type: 'OS::Heat::ScalingPolicy' autoscaling_policy: heat_template_version: '2013-05-23' resources: test_group: properties: desired_capacity: 0 max_size: 0 min_size: 0 resource: type: 'OS::Heat::RandomString' type: 'OS::Heat::AutoScalingGroup' test_policy: properties: adjustment_type: change_in_capacity auto_scaling_group_id: get_resource: test_group scaling_adjustment: 1 type: 'OS::Heat::ScalingPolicy' default: heat_template_version: '2014-10-16' random_strings: description: Test template for rally create-update-delete scenario heat_template_version: '2014-10-16' resources: test_string_one: properties: length: 20 type: 'OS::Heat::RandomString' test_string_two: properties: length: 20 type: 'OS::Heat::RandomString' resource_group: description: Test template for rally create-update-delete scenario heat_template_version: '2014-10-16' resources: test_group: properties: count: 2 resource_def: properties: length: 20 type: 'OS::Heat::RandomString' type: 'OS::Heat::ResourceGroup' resource_group_server_with_volume: description: | Test template that creates a resource group with servers and volumes. The template allows to create a lot of nested stacks with standard configuration: nova instance, cinder volume attached to that instance heat_template_version: '2014-10-16' parameters: instance_availability_zone: default: nova description: The Availability Zone to launch the instance. type: string instance_flavor: default: m1.tiny description: Type of the instance to be created. type: string instance_image: default: cirros-0.3.4-x86_64-uec type: string instance_volume_size: constraints: - range: max: 1024 min: 1 default: 1 description: Size of volume to attach to instance type: number num_instances: constraints: - range: min: 1 description: number of instances that should be created in resource group type: number resources: group_of_volumes: properties: count: get_param: num_instances resource_def: properties: availability_zone: get_param: instance_availability_zone flavor: get_param: instance_flavor image: get_param: instance_image volume_size: get_param: instance_volume_size type: templates/server-with-volume.yaml.template type: 'OS::Heat::ResourceGroup' resource_group_with_constraint: description: Template for testing caching. heat_template_version: '2013-05-23' parameters: count: default: 40 type: number delay: default: 0.1 type: number resources: rg: properties: count: get_param: count resource_def: properties: constraint_prop_secs: get_param: delay type: 'OS::Heat::TestResource' type: 'OS::Heat::ResourceGroup' resource_group_with_outputs: heat_template_version: '2013-05-23' outputs: val1: value: get_attr: - rg - resource.0.output val10: value: get_attr: - rg - resource.9.output val2: value: get_attr: - rg - resource.1.output val3: value: get_attr: - rg - resource.2.output val4: value: get_attr: - rg - resource.3.output val5: value: get_attr: - rg - resource.4.output val6: value: get_attr: - rg - resource.5.output val7: value: get_attr: - rg - resource.6.output val8: value: get_attr: - rg - resource.7.output val9: value: get_attr: - rg - resource.8.output parameters: attr_wait_secs: default: 0.5 type: number resources: rg: properties: count: 10 resource_def: properties: attr_wait_secs: get_param: attr_wait_secs type: 'OS::Heat::TestResource' type: 'OS::Heat::ResourceGroup' server_with_ports: heat_template_version: '2013-05-23' parameters: cidr: default: 11.11.11.0/24 type: string flavor: default: m1.tiny type: string image: default: cirros-0.3.4-x86_64-uec type: string public_net: default: public type: string resources: port_security_group: properties: description: | Default security group assigned to port. The neutron default group is not used because neutron creates several groups with the same name=default and nova cannot chooses which one should it use. name: default_port_security_group type: 'OS::Neutron::SecurityGroup' private_net: type: 'OS::Neutron::Net' private_subnet: properties: cidr: get_param: cidr network: get_resource: private_net type: 'OS::Neutron::Subnet' router: properties: external_gateway_info: network: get_param: public_net type: 'OS::Neutron::Router' router_interface: properties: router_id: get_resource: router subnet_id: get_resource: private_subnet type: 'OS::Neutron::RouterInterface' server: properties: flavor: get_param: flavor image: get_param: image networks: - port: get_resource: server_port type: 'OS::Nova::Server' server_port: properties: fixed_ips: - subnet: get_resource: private_subnet network: get_resource: private_net security_groups: - get_resource: port_security_group type: 'OS::Neutron::Port' server_with_volume: heat_template_version: '2013-05-23' parameters: availability_zone: default: nova description: The Availability Zone to launch the instance. type: string flavor: default: m1.tiny type: string image: default: cirros-0.3.4-x86_64-uec type: string volume_size: constraints: - description: must be between 1 and 1024 Gb. range: max: 1024 min: 1 default: 1 description: Size of the volume to be created. type: number resources: cinder_volume: properties: availability_zone: get_param: availability_zone size: get_param: volume_size type: 'OS::Cinder::Volume' server: properties: flavor: get_param: flavor image: get_param: image type: 'OS::Nova::Server' volume_attachment: properties: instance_uuid: get_resource: server mountpoint: /dev/vdc volume_id: get_resource: cinder_volume type: 'OS::Cinder::VolumeAttachment' updated_random_strings_add: description: | Test template for create-update-delete-stack scenario in rally. The template updates the stack defined by random-strings.yaml.template with additional resource. heat_template_version: '2014-10-16' resources: test_string_one: properties: length: 20 type: 'OS::Heat::RandomString' test_string_three: properties: length: 20 type: 'OS::Heat::RandomString' test_string_two: properties: length: 20 type: 'OS::Heat::RandomString' updated_random_strings_delete: description: | Test template for create-update-delete-stack scenario in rally. The template deletes one resource from the stack defined by random-strings.yaml.template. heat_template_version: '2014-10-16' resources: test_string_one: properties: length: 20 type: 'OS::Heat::RandomString' updated_random_strings_replace: description: | Test template for create-update-delete-stack scenario in rally. The template deletes one resource from the stack defined by random-strings.yaml.template and re-creates it with the updated parameters (so-called update-replace). That happens because some parameters cannot be changed without resource re-creation. The template allows to measure performance of update-replace operation. heat_template_version: '2014-10-16' resources: test_string_one: properties: length: 20 type: 'OS::Heat::RandomString' test_string_two: properties: length: 40 type: 'OS::Heat::RandomString' updated_resource_group_increase: description: | Test template for create-update-delete-stack scenario in rally. The template updates one resource from the stack defined by resource-group.yaml.template and adds children resources to that resource. heat_template_version: '2014-10-16' resources: test_group: properties: count: 3 resource_def: properties: length: 20 type: 'OS::Heat::RandomString' type: 'OS::Heat::ResourceGroup' updated_resource_group_reduce: description: | Test template for create-update-delete-stack scenario in rally. The template updates one resource from the stack defined by resource-group.yaml.template and deletes children resources from that resource. heat_template_version: '2014-10-16' resources: test_group: properties: count: 1 resource_def: properties: length: 20 type: 'OS::Heat::RandomString' type: 'OS::Heat::ResourceGroup' authenticate_task: Authenticate.keystone: - context: users: tenants: 3 users_per_tenant: 50 runner: concurrency: 5 times: 100 type: constant # NOTE(alraddarla): not enabled yet # Authenticate.validate_ceilometer: # - # args: # repetitions: 2 # context: # users: # tenants: 3 # users_per_tenant: 5 # runner: # concurrency: 5 # times: 10 # type: constant Authenticate.validate_cinder: - args: repetitions: 2 context: users: tenants: 3 users_per_tenant: 5 runner: concurrency: 5 times: 10 type: constant Authenticate.validate_glance: - args: repetitions: 2 context: users: tenants: 3 users_per_tenant: 5 runner: concurrency: 5 times: 10 type: constant Authenticate.validate_heat: - args: repetitions: 2 context: users: tenants: 3 users_per_tenant: 5 runner: concurrency: 5 times: 10 type: constant Authenticate.validate_neutron: - args: repetitions: 2 context: users: tenants: 3 users_per_tenant: 5 runner: concurrency: 5 times: 10 type: constant Authenticate.validate_nova: - args: repetitions: 2 context: users: tenants: 3 users_per_tenant: 5 runner: concurrency: 5 times: 10 type: constant ceilometer_task: CeilometerAlarms.create_alarm: - args: alarm_actions: - "http://localhost:8776/alarm" insufficient_data_actions: - "http://localhost:8776/notok" meter_name: ram_util ok_actions: - "http://localhost:8776/ok" statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerAlarms.create_alarm_and_get_history: - args: alarm_actions: - "http://localhost:8776/alarm" insufficient_data_actions: - "http://localhost:8776/notok" meter_name: ram_util ok_actions: - "http://localhost:8776/ok" state: ok statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 5 times: 10 type: constant CeilometerAlarms.create_and_delete_alarm: - args: alarm_actions: - "http://localhost:8776/alarm" insufficient_data_actions: - "http://localhost:8776/notok" meter_name: ram_util ok_actions: - "http://localhost:8776/ok" statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerAlarms.create_and_get_alarm: - args: alarm_actions: - "http://localhost:8776/alarm" insufficient_data_actions: - "http://localhost:8776/notok" meter_name: ram_util ok_actions: - "http://localhost:8776/ok" statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 CeilometerAlarms.create_and_list_alarm: - args: alarm_actions: - "http://localhost:8776/alarm" insufficient_data_actions: - "http://localhost:8776/notok" meter_name: ram_util ok_actions: - "http://localhost:8776/ok" statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerAlarms.create_and_update_alarm: - args: alarm_actions: - "http://localhost:8776/alarm" insufficient_data_actions: - "http://localhost:8776/notok" meter_name: ram_util ok_actions: - "http://localhost:8776/ok" statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerAlarms.list_alarms: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerEvents.create_user_and_get_event: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 10 type: constant CeilometerEvents.create_user_and_list_event_types: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 10 type: constant CeilometerEvents.create_user_and_list_events: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 10 type: constant CeilometerMeters.list_matched_meters: - args: filter_by_project_id: true filter_by_resource_id: true filter_by_user_id: true limit: 50 metadata_query: status: terminated context: ceilometer: counter_name: benchmark_meter counter_type: gauge counter_unit: "%" counter_volume: 100 metadata_list: - deleted: "false" name: "rally benchmark on" status: active - deleted: "true" name: "rally benchmark off" status: terminated resources_per_tenant: 100 samples_per_resource: 100 timestamp_interval: 10 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerMeters.list_meters: - args: limit: 50 metadata_query: status: terminated context: ceilometer: counter_name: benchmark_meter counter_type: gauge counter_unit: "%" counter_volume: 100 metadata_list: - deleted: "false" name: "rally benchmark on" status: active - deleted: "true" name: "rally benchmark off" status: terminated resources_per_tenant: 100 samples_per_resource: 100 timestamp_interval: 10 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerQueries.create_and_query_alarm_history: - args: alarm_actions: - "http://localhost:8776/alarm" insufficient_data_actions: - "http://localhost:8776/notok" limit: ~ meter_name: ram_util ok_actions: - "http://localhost:8776/ok" orderby: ~ statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 100 type: constant CeilometerQueries.create_and_query_alarms: - args: alarm_actions: - "http://localhost:8776/alarm" filter: and: - ? "!=" : state: dummy_state - ? "=" : type: threshold insufficient_data_actions: - "http://localhost:8776/notok" limit: 10 meter_name: ram_util ok_actions: - "http://localhost:8776/ok" orderby: ~ statistic: avg threshold: 10.0 type: threshold context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 100 type: constant CeilometerQueries.create_and_query_samples: - args: counter_name: cpu_util counter_type: gauge counter_unit: instance counter_volume: 1.0 filter: ? "=" : counter_unit: instance limit: 10 orderby: ~ resource_id: resource_id context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 100 type: constant CeilometerResource.get_tenant_resources: - context: ceilometer: counter_name: cpu_util counter_type: gauge counter_unit: instance counter_volume: 1.0 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 5 times: 10 type: constant CeilometerResource.list_matched_resources: - args: filter_by_project_id: true filter_by_user_id: true limit: 50 metadata_query: status: terminated context: ceilometer: counter_name: benchmark_meter counter_type: gauge counter_unit: "%" counter_volume: 100 metadata_list: - deleted: "false" name: "rally benchmark on" status: active - deleted: "true" name: "rally benchmark off" status: terminated resources_per_tenant: 100 samples_per_resource: 100 timestamp_interval: 10 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerResource.list_resources: - args: limit: 50 metadata_query: status: terminated context: ceilometer: counter_name: benchmark_meter counter_type: gauge counter_unit: "%" counter_volume: 100 metadata_list: - deleted: "false" name: "rally benchmark on" status: active - deleted: "true" name: "rally benchmark off" status: terminated resources_per_tenant: 100 samples_per_resource: 100 timestamp_interval: 10 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerSamples.list_matched_samples: - args: filter_by_project_id: true filter_by_resource_id: true filter_by_user_id: true limit: 50 metadata_query: status: not_active context: ceilometer: counter_name: cpu_util counter_type: gauge counter_unit: instance counter_volume: 1.0 metadata_list: - created_at: "2015-09-04T12:34:19.000000" deleted: "False" name: fake_resource status: active - created_at: "2015-09-10T06:55:12.000000" deleted: "False" name: fake_resource_1 status: not_active resources_per_tenant: 100 samples_per_resource: 100 timestamp_interval: 60 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant CeilometerSamples.list_samples: - args: limit: 50 metadata_query: status: not_active context: ceilometer: batch_size: 5 counter_name: cpu_util counter_type: gauge counter_unit: instance counter_volume: 1.0 metadata_list: - created_at: "2015-09-04T12:34:19.000000" deleted: "False" name: fake_resource status: active - created_at: "2015-09-10T06:55:12.000000" deleted: "False" name: fake_resource_1 status: not_active resources_per_tenant: 100 samples_per_resource: 100 timestamp_interval: 60 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant CeilometerStats.create_meter_and_get_stats: - args: counter_type: cumulative counter_unit: "" counter_volume: 1.0 resource_id: resource-id user_id: user-id context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 5 times: 200 type: constant CeilometerStats.get_stats: - args: filter_by_project_id: true filter_by_resource_id: true filter_by_user_id: true groupby: resource_id metadata_query: status: terminated meter_name: benchmark_meter period: 300 context: ceilometer: counter_name: benchmark_meter counter_type: gauge counter_unit: "%" counter_volume: 100 metadata_list: - deleted: "false" name: "rally benchmark on" status: active - deleted: "true" name: "rally benchmark off" status: terminated resources_per_tenant: 100 samples_per_resource: 100 timestamp_interval: 10 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant CeilometerTraits.create_user_and_list_trait_descriptions: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 10 type: constant CeilometerTraits.create_user_and_list_traits: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 10 times: 10 type: constant cinder_task: CinderVolumeTypes.create_and_delete_volume_type: - args: {} context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant sla: failure_rate: max: 0 CinderVolumeTypes.create_and_list_encryption_type: - args: specs: cipher: aes-xts-plain64 control_location: front-end key_size: 512 provider: LuksEncryptor context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 4 type: constant sla: failure_rate: max: 0 CinderVolumeTypes.create_volume_type_and_encryption_type: - args: specs: cipher: aes-xts-plain64 control_location: front-end key_size: 512 provider: LuksEncryptor context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant sla: failure_rate: max: 0 CinderVolumes.create_and_accept_transfer: - args: size: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 3 type: constant sla: failure_rate: max: 0 CinderVolumes.create_and_attach_volume: - args: create_volume_params: availability_zone: nova flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img size: 10 context: users: tenants: 2 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 5 type: constant - args: create_volume_params: availability_zone: nova flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img size: max: 5 min: 1 context: users: tenants: 2 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 5 type: constant CinderVolumes.create_and_delete_snapshot: - args: force: false context: users: tenants: 2 users_per_tenant: 2 volumes: size: 1 runner: concurrency: 2 times: 3 type: constant CinderVolumes.create_and_delete_volume: - args: image: name: cirros-0.6.2-x86_64-disk.img size: 1 context: users: tenants: 2 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 2 type: constant CinderVolumes.create_and_extend_volume: - args: new_size: 2 size: 1 context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 2 times: 2 type: constant - args: new_size: max: 10 min: 6 size: max: 5 min: 1 context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 2 times: 2 type: constant CinderVolumes.create_and_get_volume: - args: size: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant sla: failure_rate: max: 0 - args: size: max: 5 min: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant sla: failure_rate: max: 0 CinderVolumes.create_and_list_snapshots: - args: detailed: true force: false context: users: tenants: 1 users_per_tenant: 1 volumes: size: 1 runner: concurrency: 2 times: 2 type: constant CinderVolumes.create_and_list_volume: - args: detailed: true size: 1 context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 3 type: constant - args: detailed: true size: max: 5 min: 1 context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 3 type: constant CinderVolumes.create_and_list_volume_backups: - args: create_backup_kwargs: {} create_volume_kwargs: {} detailed: true do_delete: true size: 1 context: roles: - member users: tenants: 1 users_per_tenant: 1 runner: concurrency: 2 times: 2 type: constant CinderVolumes.create_and_restore_volume_backup: - args: create_backup_kwargs: {} create_volume_kwargs: {} do_delete: true size: 1 context: roles: - member users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 2 type: constant CinderVolumes.create_and_upload_volume_to_image: - args: container_format: bare disk_format: raw do_delete: true force: false image: name: cirros-0.6.2-x86_64-disk.img size: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 3 type: constant - args: container_format: bare disk_format: raw do_delete: true force: false image: name: cirros-0.6.2-x86_64-disk.img size: max: 5 min: 1 context: users: tenants: 2 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 3 type: constant CinderVolumes.create_from_volume_and_delete_volume: - args: size: 1 context: users: tenants: 1 users_per_tenant: 1 volumes: size: 1 runner: concurrency: 2 times: 2 type: constant - args: size: max: 5 min: 1 context: users: tenants: 1 users_per_tenant: 1 volumes: size: 1 runner: concurrency: 2 times: 2 type: constant CinderVolumes.create_nested_snapshots_and_attach_volume: - args: nested_level: 5 size: max: 5 min: 1 context: servers: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img servers_per_tenant: 2 users: tenants: 2 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant CinderVolumes.create_snapshot_and_attach_volume: - args: size: max: 5 min: 1 volume_type: false context: servers: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img servers_per_tenant: 2 users: tenants: 2 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 4 type: constant - args: size: max: 5 min: 1 volume_type: true context: servers: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img servers_per_tenant: 2 users: tenants: 2 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 4 type: constant CinderVolumes.create_volume_and_clone: - args: size: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 3 type: constant - args: nested_level: 3 size: max: 5 min: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 3 type: constant CinderVolumes.create_volume_backup: - args: create_backup_kwargs: {} create_volume_kwargs: {} do_delete: true size: 1 context: roles: - member users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 2 type: constant CinderVolumes.create_volume_from_snapshot: - args: do_delete: true context: users: tenants: 2 users_per_tenant: 2 volumes: size: 1 runner: concurrency: 2 times: 3 type: constant CinderVolumes.list_transfers: - args: detailed: true context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 3 type: constant sla: failure_rate: max: 0 CinderVolumes.list_volumes: - args: detailed: true context: users: tenants: 1 users_per_tenant: 1 volumes: size: 1 volumes_per_tenant: 4 runner: concurrency: 1 times: 100 type: constant CinderVolumes.modify_volume_metadata: - args: {} context: users: tenants: 2 users_per_tenant: 2 volumes: size: 1 runner: concurrency: 2 times: 10 type: constant CinderVolumeBackups.create_incremental_volume_backup: - args: create_backup_kwargs: {} create_volume_kwargs: {} size: 1 context: roles: - admin users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant sla: failure_rate: max: 0 CinderVolumes.create_and_update_volume: - args: create_volume_kwargs: {} size: 1 update_volume_kwargs: display_description: desc_updated display_name: name_updated context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 3 type: constant CinderVolumes.create_volume_and_update_readonly_flag: - args: read_only: true size: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 3 type: constant sla: failure_rate: max: 0 CinderVolumes.list_types: - args: is_public: true context: users: tenants: 2 users_per_tenant: 3 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 glance_task: GlanceImages.create_and_delete_image: - args: container_format: bare disk_format: qcow2 image_location: "http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img" context: users: tenants: 2 users_per_tenant: 3 runner: concurrency: 2 times: 10 type: constant GlanceImages.create_and_list_image: - args: container_format: bare disk_format: qcow2 image_location: "http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img" context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 10 type: constant GlanceImages.create_image_and_boot_instances: - args: container_format: bare disk_format: qcow2 flavor: name: m1.tiny image_location: "http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img" number_instances: 2 context: users: tenants: 3 users_per_tenant: 5 runner: concurrency: 2 times: 10 type: constant GlanceImages.list_images: - context: images: image_container: bare image_type: qcow2 image_url: "http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img" images_per_tenant: 4 users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 10 type: constant heat_task: HeatStacks.create_and_delete_stack: - args: template_path: /tmp/tasks/test-templates/server-with-ports.yaml context: users: tenants: 2 users_per_tenant: 3 runner: concurrency: 2 times: 10 type: constant HeatStacks.create_and_list_stack: - args: template_path: /tmp/tasks/test-templates/default.yaml context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 10 type: constant HeatStacks.create_check_delete_stack: - args: template_path: /tmp/tasks/test-templates/random-strings.yaml context: users: tenants: 2 users_per_tenant: 3 runner: concurrency: 2 times: 10 type: constant HeatStacks.create_snapshot_restore_delete_stack: - args: template_path: /tmp/tasks/test-templates/random-strings.yaml context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant HeatStacks.create_stack_and_list_output: - args: template_path: /tmp/tasks/test-templates/resource-group-with-outputs.yaml context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant HeatStacks.create_stack_and_list_output_via_API: - args: template_path: /tmp/tasks/test-templates/resource-group-with-outputs.yaml context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant HeatStacks.create_stack_and_scale: - args: delta: 1 output_key: scaling_url template_path: /tmp/tasks/test-templates/autoscaling-group.yaml context: users: tenants: 2 users_per_tenant: 1 runner: concurrency: 2 times: 3 type: constant HeatStacks.create_stack_and_show_output: - args: output_key: val1 template_path: /tmp/tasks/test-templates/resource-group-with-outputs.yaml context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 5 type: constant HeatStacks.create_stack_and_show_output_via_API: - args: output_key: val1 template_path: /tmp/tasks/test-templates/resource-group-with-outputs.yaml context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 1 times: 5 type: constant HeatStacks.create_suspend_resume_delete_stack: - args: template_path: /tmp/tasks/test-templates/random-strings.yaml context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant HeatStacks.create_update_delete_stack: - args: template_path: /tmp/tasks/test-templates/resource-group.yaml updated_template_path: /tmp/tasks/test-templates/updated-resource-group-reduce.yaml context: users: tenants: 2 users_per_tenant: 3 runner: concurrency: 2 times: 10 type: constant HeatStacks.list_stacks_and_events: - context: stacks: resources_per_stack: 10 stacks_per_tenant: 2 users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 10 type: constant HeatStacks.list_stacks_and_resources: - context: stacks: resources_per_stack: 10 stacks_per_tenant: 2 users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 10 type: constant keystone_task: KeystoneBasic.add_and_remove_user_role: - context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 10 times: 100 type: constant KeystoneBasic.authenticate_user_and_validate_token: - args: {} runner: concurrency: 5 times: 20 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_add_and_list_user_roles: - context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_and_delete_ec2credential: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 5 times: 10 type: constant KeystoneBasic.create_and_delete_role: - runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_and_delete_service: - args: description: test_description service_type: Rally_test_type runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_and_get_role: - args: {} context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 KeystoneBasic.create_and_list_ec2credentials: - context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 5 times: 10 type: constant KeystoneBasic.create_and_list_services: - args: description: test_description service_type: Rally_test_type runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_and_list_tenants: - args: {} runner: concurrency: 1 times: 10 type: constant KeystoneBasic.create_and_list_users: - args: {} runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_delete_user: - args: {} runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_tenant: - args: {} runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_tenant_with_users: - args: users_per_tenant: 10 runner: concurrency: 10 times: 10 type: constant KeystoneBasic.create_update_and_delete_tenant: - args: {} runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_user: - args: {} runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_user_set_enabled_and_delete: - args: enabled: true runner: concurrency: 10 times: 100 type: constant - args: enabled: false runner: concurrency: 10 times: 100 type: constant KeystoneBasic.create_user_update_password: - args: {} runner: concurrency: 10 times: 100 type: constant KeystoneBasic.get_entities: - runner: concurrency: 10 times: 100 type: constant magnum_task: MagnumClusterTemplates.list_cluster_templates: - context: cluster_templates: coe: kubernetes dns_nameserver: "8.8.8.8" docker_volume_size: 5 external_network_id: public flavor_id: m1.small image_id: fedora-atomic-latest network_driver: flannel users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant - context: cluster_templates: coe: swarm dns_nameserver: "8.8.8.8" docker_volume_size: 5 external_network_id: public flavor_id: m1.small image_id: fedora-atomic-latest network_driver: docker users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant - context: cluster_templates: coe: mesos dns_nameserver: "8.8.8.8" external_network_id: public flavor_id: m1.small image_id: ubuntu-mesos network_driver: docker users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant MagnumClusters.create_and_list_clusters: - args: node_count: 1 context: cluster_templates: coe: kubernetes dns_nameserver: "8.8.8.8" docker_volume_size: 5 external_network_id: public flavor_id: m1.small image_id: fedora-atomic-latest network_driver: flannel users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant - args: node_count: 1 context: cluster_templates: coe: swarm dns_nameserver: "8.8.8.8" docker_volume_size: 5 external_network_id: public flavor_id: m1.small image_id: fedora-atomic-latest network_driver: docker users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant - args: node_count: 1 context: cluster_templates: coe: mesos dns_nameserver: "8.8.8.8" external_network_id: public flavor_id: m1.small image_id: ubuntu-mesos network_driver: docker users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant MagnumClusters.list_clusters: - context: cluster_templates: coe: kubernetes dns_nameserver: "8.8.8.8" docker_volume_size: 5 external_network_id: public flavor_id: m1.small image_id: fedora-atomic-latest network_driver: flannel clusters: node_count: 2 users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant - context: cluster_templates: coe: swarm dns_nameserver: "8.8.8.8" docker_volume_size: 5 external_network_id: public flavor_id: m1.small image_id: fedora-atomic-latest network_driver: docker clusters: node_count: 2 users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant - context: cluster_templates: coe: mesos dns_nameserver: "8.8.8.8" external_network_id: public flavor_id: m1.small image_id: ubuntu-mesos network_driver: docker clusters: node_count: 2 users: tenants: 1 users_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant neutron_task: NeutronNetworks.create_and_delete_floating_ips: - args: floating_ip_args: {} floating_network: public context: quotas: neutron: floatingip: -1 users: tenants: 2 users_per_tenant: 3 runner: concurrency: 5 times: 10 type: constant NeutronNetworks.create_and_delete_networks: - args: network_create_args: {} context: quotas: neutron: network: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant NeutronNetworks.create_and_delete_ports: - args: network_create_args: {} port_create_args: {} ports_per_network: 10 context: network: {} quotas: neutron: network: -1 port: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant NeutronNetworks.create_and_delete_routers: - args: network_create_args: {} router_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 router: -1 subnet: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 30 type: constant NeutronNetworks.create_and_delete_subnets: - args: network_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 subnet: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant NeutronNetworks.create_and_list_floating_ips: - args: floating_ip_args: {} floating_network: public context: quotas: neutron: floatingip: -1 users: tenants: 2 users_per_tenant: 3 runner: concurrency: 5 times: 10 type: constant NeutronNetworks.create_and_list_networks: - args: network_create_args: {} context: quotas: neutron: network: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant sla: failure_rate: max: 0 - args: network_create_args: ? "provider:network_type" : vxlan context: quotas: neutron: network: -1 roles: - admin users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_list_ports: - args: network_create_args: {} port_create_args: {} ports_per_network: 10 context: network: {} quotas: neutron: network: -1 port: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant NeutronNetworks.create_and_list_routers: - args: network_create_args: {} router_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 router: -1 subnet: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant NeutronNetworks.create_and_list_subnets: - args: network_create_args: {} subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 subnet: -1 users: tenants: 2 users_per_tenant: 3 runner: concurrency: 5 times: 10 type: constant NeutronNetworks.create_and_show_network: - args: network_create_args: {} context: quotas: neutron: network: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NeutronNetworks.create_and_update_networks: - args: network_create_args: {} network_update_args: admin_state_up: false name: _updated context: quotas: neutron: network: -1 users: tenants: 2 users_per_tenant: 3 runner: concurrency: 5 times: 10 type: constant NeutronNetworks.create_and_update_ports: - args: network_create_args: {} port_create_args: {} port_update_args: admin_state_up: false device_id: dummy_id device_owner: dummy_owner name: _port_updated ports_per_network: 5 context: network: {} quotas: neutron: network: -1 port: -1 users: tenants: 2 users_per_tenant: 3 runner: concurrency: 5 times: 10 type: constant NeutronNetworks.create_and_update_routers: - args: network_create_args: {} router_create_args: {} router_update_args: admin_state_up: false name: _router_updated subnet_cidr_start: 1.1.0.0/30 subnet_create_args: {} subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 router: -1 subnet: -1 users: tenants: 2 users_per_tenant: 3 runner: concurrency: 5 times: 10 type: constant NeutronNetworks.create_and_update_subnets: - args: network_create_args: {} subnet_cidr_start: 1.4.0.0/16 subnet_create_args: {} subnet_update_args: enable_dhcp: false name: _subnet_updated subnets_per_network: 2 context: network: {} quotas: neutron: network: -1 subnet: -1 users: tenants: 2 users_per_tenant: 3 runner: concurrency: 5 times: 10 type: constant NeutronNetworks.list_agents: - args: agent_args: {} context: users: tenants: 2 users_per_tenant: 3 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NeutronSecurityGroup.create_and_delete_security_groups: - args: security_group_create_args: {} context: quotas: neutron: security_group: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant NeutronSecurityGroup.create_and_list_security_groups: - args: security_group_create_args: {} context: quotas: neutron: security_group: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant NeutronSecurityGroup.create_and_update_security_groups: - args: security_group_create_args: {} security_group_update_args: {} context: quotas: neutron: security_group: -1 users: tenants: 3 users_per_tenant: 3 runner: concurrency: 10 times: 100 type: constant nova_task: NovaAgents.list_agents: - runner: concurrency: 2 times: 10 type: constant NovaAggregates.create_aggregate_add_and_remove_host: - args: availability_zone: nova context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaAggregates.create_aggregate_add_host_and_boot_server: - args: availability_zone: nova boot_server_kwargs: {} disk: 1 image: name: cirros-0.6.2-x86_64-disk.img metadata: test_metadata: "true" ram: 512 vcpus: 1 context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaAggregates.create_and_delete_aggregate: - args: availability_zone: nova context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaAggregates.create_and_get_aggregate_details: - args: availability_zone: nova context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaAggregates.create_and_list_aggregates: - args: availability_zone: nova context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaAggregates.create_and_update_aggregate: - args: availability_zone: nova context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaAggregates.list_aggregates: - runner: concurrency: 2 times: 10 type: constant NovaAvailabilityZones.list_availability_zones: - args: detailed: true runner: concurrency: 2 times: 10 type: constant NovaFlavors.create_and_delete_flavor: - args: disk: 1 ram: 500 vcpus: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaFlavors.create_and_get_flavor: - args: disk: 1 ram: 500 vcpus: 1 context: users: tenants: 1 users_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaFlavors.create_and_list_flavor_access: - args: disk: 1 ram: 500 vcpus: 1 runner: concurrency: 2 times: 10 type: constant NovaFlavors.create_flavor: - args: disk: 1 ram: 500 vcpus: 1 runner: concurrency: 2 times: 10 type: constant NovaFlavors.create_flavor_and_add_tenant_access: - args: disk: 1 ram: 500 vcpus: 1 context: users: tenants: 2 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaFlavors.create_flavor_and_set_keys: - args: disk: 1 extra_specs: ? "quota:disk_read_bytes_sec" : 10240 ram: 500 vcpus: 1 context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant sla: failure_rate: max: 0 NovaFlavors.list_flavors: - args: detailed: true context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant NovaHypervisors.list_and_get_hypervisors: - args: detailed: true context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 2 type: constant sla: failure_rate: max: 0 NovaHypervisors.list_and_get_uptime_hypervisors: - args: detailed: true context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 2 type: constant sla: failure_rate: max: 0 NovaHypervisors.list_and_search_hypervisors: - args: detailed: true context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 2 type: constant sla: failure_rate: max: 0 NovaHypervisors.list_hypervisors: - args: detailed: true runner: concurrency: 2 times: 10 type: constant NovaHypervisors.statistics_hypervisors: - args: {} context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 2 type: constant sla: failure_rate: max: 0 NovaKeypair.boot_and_delete_server_with_keypair: - args: boot_server_kwargs: {} flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: network: start_cidr: 100.1.0.0/26 users: tenants: 2 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 5 type: constant NovaKeypair.create_and_delete_keypair: - context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant NovaKeypair.create_and_list_keypairs: - context: users: tenants: 3 users_per_tenant: 2 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_and_associate_floating_ip: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: network: {} users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant NovaServers.boot_and_bounce_server: - args: actions: - hard_reboot: 1 - soft_reboot: 1 - stop_start: 1 - rescue_unrescue: 1 flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_and_delete_multiple_servers: - args: count: 5 flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant NovaServers.boot_and_delete_server: - args: flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant - args: auto_assign_nic: true flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: network: networks_per_tenant: 2 start_cidr: 10.2.0.0/24 users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_and_get_console_output: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant NovaServers.boot_and_list_server: - args: detailed: true flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant NovaServers.boot_and_live_migrate_server: - args: block_migration: false flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_and_migrate_server: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_and_rebuild_server: - args: flavor: name: m1.tiny from_image: name: cirros-0.6.2-x86_64-disk.img to_image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 5 type: constant NovaServers.boot_and_show_server: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant NovaServers.boot_and_update_server: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_lock_unlock_and_delete: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_server: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_server_associate_and_dissociate_floating_ip: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img context: network: {} users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 5 type: constant sla: failure_rate: max: 0 NovaServers.boot_server_attach_created_volume_and_live_migrate: - args: block_migration: false boot_server_kwargs: {} create_volume_kwargs: {} flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img size: 10 context: users: tenants: 2 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 5 type: constant NovaServers.boot_server_attach_created_volume_and_resize: - args: boot_server_kwargs: {} confirm: true create_volume_kwargs: {} do_delete: true flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img to_flavor: name: m1.small volume_size: 1 context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_server_from_volume: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img volume_size: 10 volume_type: "" context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_server_from_volume_and_delete: - args: flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img volume_size: 10 volume_type: "" context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_server_from_volume_and_live_migrate: - args: block_migration: false flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img volume_size: 10 volume_type: "" context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_server_from_volume_and_resize: - args: boot_server_kwargs: {} confirm: true create_volume_kwargs: {} do_delete: true flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img to_flavor: name: m1.small volume_size: 1 context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.boot_server_from_volume_snapshot: - args: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img volume_size: 10 volume_type: "" context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.list_servers: - args: detailed: true context: servers: flavor: name: m1.tiny image: name: cirros-0.6.2-x86_64-disk.img servers_per_tenant: 2 users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 1 times: 1 type: constant NovaServers.pause_and_unpause_server: - args: flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.resize_server: - args: confirm: true flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img to_flavor: name: m1.small context: users: tenants: 1 users_per_tenant: 1 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 5 times: 10 type: constant NovaServers.shelve_and_unshelve_server: - args: flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.snapshot_server: - args: flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServers.suspend_and_resume_server: - args: flavor: name: m1.tiny force_delete: false image: name: cirros-0.6.2-x86_64-disk.img context: users: tenants: 3 users_per_tenant: 2 images: image_url: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" image_name: cirros-0.6.2-x86_64-disk.img image_type: qcow2 image_container: bare images_per_tenant: 1 runner: concurrency: 2 times: 10 type: constant NovaServices.list_services: - runner: concurrency: 2 times: 10 type: constant swift_task: SwiftObjects.create_container_and_object_then_delete_all: - args: object_size: 102400 objects_per_container: 5 context: roles: - admin users: tenants: 1 users_per_tenant: 1 runner: concurrency: 2 times: 4 type: constant SwiftObjects.create_container_and_object_then_download_object: - args: object_size: 1024 objects_per_container: 5 context: roles: - admin users: tenants: 1 users_per_tenant: 1 runner: concurrency: 3 times: 6 type: constant SwiftObjects.create_container_and_object_then_list_objects: - args: object_size: 5120 objects_per_container: 2 context: roles: - admin users: tenants: 1 users_per_tenant: 1 runner: concurrency: 2 times: 2 type: constant SwiftObjects.list_and_download_objects_in_containers: - context: roles: - admin swift_objects: containers_per_tenant: 2 object_size: 10240 objects_per_container: 5 users: tenants: 1 users_per_tenant: 1 runner: concurrency: 2 times: 2 type: constant SwiftObjects.list_objects_in_containers: - context: roles: - admin swift_objects: containers_per_tenant: 1 object_size: 1024 objects_per_container: 10 users: tenants: 1 users_per_tenant: 1 runner: concurrency: 3 times: 6 type: constant tls: identity: false manifests: configmap_bin: true configmap_etc: true configmap_tasks: true configmap_test_templates: true job_bootstrap: true job_db_init: true job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_manage_db: true job_run_task: true pvc_rally: true secret_db: true secret_keystone: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: redis/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v4.0.1 description: OpenStack-Helm Redis name: redis version: 2025.2.0 home: https://github.com/redis/redis dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: redis/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: redis-bin data: image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} redis-test.sh: | {{ tuple "test/_redis_test.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} python-tests.py: | {{ tuple "test/_python_redis_tests.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: redis/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $serviceAccountName := "redis" }} {{ tuple $envAll "redis" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: redis annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "redis" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.server }} selector: matchLabels: {{ tuple $envAll "redis" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "redis" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "redis" "server" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.redis.node_selector_key }}: {{ .Values.labels.redis.node_selector_value | quote }} initContainers: {{ tuple $envAll "redis" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: redis {{ tuple $envAll "redis" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - redis-server - --port - {{ .Values.network.port | quote }} ports: - containerPort: {{ .Values.network.port }} readinessProbe: tcpSocket: port: {{ .Values.network.port }} {{- end }} ================================================ FILE: redis/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: redis/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "redis" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: redis/templates/pod_test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.helm_tests }} {{- $envAll := . }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.Release.Name}}-test" labels: {{ tuple $envAll "redis" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never containers: - name: {{.Release.Name}}-helm-tests {{ tuple $envAll "helm_tests" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} command: - /tmp/redis-test.sh env: - name: REDIS_HOST value: "redis" - name: REDIS_PORT value: "{{ .Values.network.port }}" - name: REDIS_DB value: '0' volumeMounts: - name: pod-tmp mountPath: /tmp - name: redis-test mountPath: /tmp/redis-test.sh subPath: redis-test.sh - name: redis-python mountPath: /tmp/python-tests.py subPath: python-tests.py volumes: - name: pod-tmp emptyDir: {} - name: redis-test configMap: name: redis-bin defaultMode: 0555 - name: redis-python configMap: name: redis-bin defaultMode: 0555 {{- end }} ================================================ FILE: redis/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: redis/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: redis spec: clusterIP: None ports: - port: {{ .Values.network.port }} selector: {{ tuple $envAll "redis" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- end }} ================================================ FILE: redis/templates/test/_python_redis_tests.py.tpl ================================================ import os import redis class RedisTest(object): def __init__(self): host = os.environ.get('REDIS_HOST', 'redis') port = os.environ.get('REDIS_PORT', 6379) db = os.environ.get('REDIS_DB', 0) self.redis_conn = redis.Redis(host, port, db) def test_connection(self): ping = self.redis_conn.ping() if not ping: raise Exception('No connection to database') print("Successfully connected to database") def database_info(self): ip_port = [] for client in self.redis_conn.client_list(): ip_port.append(client["addr"]) print(ip_port) if not self.redis_conn.client_list(): raise Exception('Database client list is null') return ip_port def test_insert_delete_data(self): key = "test" value = "it's working" result_set = self.redis_conn.set(key, value) if not result_set: raise Exception('ERROR: SET command failed') print("Successfully SET keyvalue pair") result_get = self.redis_conn.get(key) if not result_get: raise Exception('ERROR: GET command failed') print("Successfully GET keyvalue pair") db_size = self.redis_conn.dbsize() if db_size <= 0: raise Exception("Database size not valid") result_delete = self.redis_conn.delete(key) if not result_delete == 1: raise Exception("Error: Delete command failed") print("Successfully DELETED keyvalue pair") def test_client_kill(self, client_ip_port_list): for client_ip_port in client_ip_port_list: result = self.redis_conn.client_kill(client_ip_port) if not result: raise Exception('Client failed to be removed') print("Successfully DELETED client") client_ip_port = [] redis_client = RedisTest() redis_client.test_connection() client_ip_port = redis_client.database_info() redis_client.test_insert_delete_data() redis_client.test_client_kill(client_ip_port) ================================================ FILE: redis/templates/test/_redis_test.sh.tpl ================================================ #!/bin/bash set -ex echo "Start Redis Test" echo "Print Environmental variables" echo $REDIS_HOST echo $REDIS_PORT echo $REDIS_DB python /tmp/python-tests.py ================================================ FILE: redis/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for redis. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- images: tags: redis: docker.io/library/redis:4.0.1 helm_tests: docker.io/redislabs/redis-py:latest dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: quay.io/airshipit/docker:27.5.0 pull_policy: IfNotPresent local_registry: active: false exclude: - dep_check - image_repo_sync pod: affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 replicas: server: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 resources: enabled: false server: limits: memory: "128Mi" cpu: "500m" requests: memory: "128Mi" cpu: "500m" jobs: image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" labels: redis: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled network: port: 6379 dependencies: dynamic: common: local_image_registry: jobs: - redis-image-repo-sync services: - endpoint: node service: local_image_registry static: image_repo_sync: services: - endpoint: internal service: local_image_registry redis: services: null secrets: oci_image_registry: redis: redis-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false redis: username: redis password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null manifests: configmap_bin: true deployment: true job_image_repo_sync: true secret_registry: true service: true helm_tests: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: registry/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v2.0.0 description: OpenStack-Helm Docker Registry name: registry version: 2025.2.0 home: https://github.com/kubernetes/ingress sources: - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: registry/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} IFS=',' ; for IMAGE in ${PRELOAD_IMAGES}; do docker pull ${IMAGE} docker tag ${IMAGE} ${LOCAL_REPO}/${IMAGE} docker push ${LOCAL_REPO}/${IMAGE} done ================================================ FILE: registry/templates/bin/_registry-proxy.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec nginx -g "daemon off;" ================================================ FILE: registry/templates/bin/_registry.sh.tpl ================================================ #!/bin/sh {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec registry serve /etc/docker/registry/config.yml ================================================ FILE: registry/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: registry-bin data: bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} registry.sh: | {{ tuple "bin/_registry.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} registry-proxy.sh: | {{ tuple "bin/_registry-proxy.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: registry/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.registry.http.addr -}} {{ $_ := cat "0.0.0.0" (tuple "docker_registry" "internal" "registry" . | include "helm-toolkit.endpoints.endpoint_port_lookup") | replace " " ":" | set .Values.conf.registry.http "addr" -}} {{- end -}} {{- if empty .Values.conf.registry.redis.addr -}} {{ $_ := tuple "redis" "internal" "redis" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.registry.redis "addr" -}} {{- end -}} --- apiVersion: v1 kind: ConfigMap metadata: name: registry-etc data: config.yml: | {{ toYaml .Values.conf.registry | indent 4 }} default.conf: | {{ tuple "etc/_default.conf.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: registry/templates/daemonset-registry-proxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset_registry_proxy }} {{- $envAll := . }} {{- $serviceAccountName := "docker-registry-proxy" }} {{ tuple $envAll "registry_proxy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: docker-registry-proxy annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "docker" "registry-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "docker" "registry-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "docker" "registry-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: {{ dict "envAll" $envAll "application" "registry_proxy" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.registry.node_selector_key }}: {{ .Values.labels.registry.node_selector_value | quote }} dnsPolicy: {{ .Values.pod.dns_policy }} hostNetwork: true initContainers: {{ tuple $envAll "registry_proxy" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: registry-proxy {{ tuple $envAll "registry_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.registry_proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "registry_proxy" "container" "registry_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/registry-proxy.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: registry-bin mountPath: /tmp/registry-proxy.sh subPath: registry-proxy.sh readOnly: true - name: registry-etc mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf readOnly: true volumes: - name: pod-tmp emptyDir: {} - name: registry-bin configMap: name: registry-bin defaultMode: 0555 - name: registry-etc configMap: name: registry-etc defaultMode: 0444 {{- end }} ================================================ FILE: registry/templates/deployment-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_registry }} {{- $envAll := . }} {{- $serviceAccountName := "docker-registry" }} {{ tuple $envAll "registry" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: docker-registry annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "docker" "registry" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.registry }} selector: matchLabels: {{ tuple $envAll "docker" "registry" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "docker" "registry" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: {{ dict "envAll" $envAll "application" "registry" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "docker" "registry" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.registry.node_selector_key }}: {{ .Values.labels.registry.node_selector_value | quote }} initContainers: {{ tuple $envAll "registry" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: registry {{ tuple $envAll "registry" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.registry | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "registry" "container" "registry" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} ports: - name: d-reg containerPort: {{ tuple "docker_registry" "internal" "registry" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} command: - /tmp/registry.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: registry-bin mountPath: /tmp/registry.sh subPath: registry.sh readOnly: true - name: registry-etc mountPath: /etc/docker/registry/config.yml subPath: config.yml readOnly: true - name: docker-images mountPath: {{ .Values.conf.registry.storage.filesystem.rootdirectory }} volumes: - name: pod-tmp emptyDir: {} - name: registry-bin configMap: name: registry-bin defaultMode: 0555 - name: registry-etc configMap: name: registry-etc defaultMode: 0444 - name: docker-images persistentVolumeClaim: claimName: docker-images {{- end }} ================================================ FILE: registry/templates/etc/_default.conf.tpl ================================================ # Docker registry proxy for api version 2 upstream docker-registry { server {{ tuple "docker_registry" "internal" "registry" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }}; } # No client auth or TLS # TODO(bacongobbler): experiment with authenticating the registry if it's using TLS server { listen {{ tuple "docker_registry" "public" "registry" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}; server_name localhost; # disable any limits to avoid HTTP 413 for large image uploads client_max_body_size 0; # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) chunked_transfer_encoding on; location / { # Do not allow connections from docker 1.5 and earlier # docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) { return 404; } include docker-registry.conf; } } ================================================ FILE: registry/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: registry/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_bootstrap }} {{- $envAll := . }} {{- if .Values.bootstrap.enabled }} {{- $serviceAccountName := "docker-bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: docker-bootstrap labels: {{ tuple $envAll "docker" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: template: metadata: labels: {{ tuple $envAll "docker" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value | quote }} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: docker-bootstrap {{ tuple $envAll "bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: - name: LOCAL_REPO value: "localhost:{{ tuple "docker_registry" "public" "registry" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}" - name: PRELOAD_IMAGES value: "{{ include "helm-toolkit.utils.joinListWithComma" .Values.bootstrap.preload_images }}" command: - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: registry-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true - name: docker-socket mountPath: /var/run/docker.sock volumes: - name: pod-tmp emptyDir: {} - name: registry-bin configMap: name: registry-bin defaultMode: 0555 - name: docker-socket hostPath: path: /var/run/docker.sock {{- end }} {{- end }} ================================================ FILE: registry/templates/pvc-images.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pvc_images }} {{- $envAll := . }} --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: docker-images spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: {{ .Values.volume.size }} {{- if ne .Values.volume.class_name "default" }} storageClassName: {{ .Values.volume.class_name }} {{- end }} {{- end }} ================================================ FILE: registry/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: registry/templates/service-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_registry }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "docker_registry" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: d-reg port: {{ tuple "docker_registry" "internal" "registry" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.registry.node_port.enabled }} nodePort: {{ .Values.network.registry.node_port.port }} {{ end }} selector: {{ tuple $envAll "docker" "registry" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.registry.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: registry/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for docker registry. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: registry: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: registry: docker.io/library/registry:2 registry_proxy: registry.k8s.io/kube-registry-proxy:0.4 bootstrap: docker.io/library/docker:29 dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check volume: class_name: general size: 2Gi network: registry: ingress: public: false node_port: enabled: false port: 5000 conf: registry: version: 0.1 log: fields: service: registry storage: cache: blobdescriptor: redis filesystem: rootdirectory: /var/lib/registry http: secret: not-so-secret-secret headers: X-Content-Type-Options: [nosniff] health: storagedriver: enabled: true interval: 10s threshold: 3 redis: addr: null pod: security_context: registry_proxy: pod: runAsUser: 65534 container: registry_proxy: runAsUser: 0 readOnlyRootFilesystem: false registry: pod: runAsUser: 65534 container: registry: allowPrivilegeEscalation: false readOnlyRootFilesystem: true affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 dns_policy: "ClusterFirstWithHostNet" replicas: registry: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 resources: enabled: false registry: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" registry_proxy: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" bootstrap: enabled: true script: docker info preload_images: - quay.io/airshipit/nginx:alpine3.18 dependencies: static: bootstrap: pod: # NOTE(srwilkers): As the daemonset dependency is currently broken for # kubernetes 1.16, use the pod dependency and require the same node # instead for the same result - requireSameNode: true labels: application: docker component: registry-proxy services: - endpoint: internal service: docker_registry registry: services: - endpoint: internal service: redis registry_proxy: services: - endpoint: internal service: docker_registry secrets: oci_image_registry: registry: registry-oci-image-registry-key endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: default: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false registry: username: registry password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null docker_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: default: 5000 redis: namespace: null hosts: default: redis host_fqdn_override: default: null port: redis: default: 6379 manifests: configmap_bin: true configmap_etc: true daemonset_registry_proxy: true deployment_registry: true job_bootstrap: true job_image_repo_sync: true pvc_images: true secret_registry: true service_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: release.asc ================================================ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1 mQINBFX4hgkBEADLqn6O+UFp+ZuwccNldwvh5PzEwKUPlXKPLjQfXlQRig1flpCH E0HJ5wgGlCtYd3Ol9f9+qU24kDNzfbs5bud58BeE7zFaZ4s0JMOMuVm7p8JhsvkU C/Lo/7NFh25e4kgJpjvnwua7c2YrA44ggRb1QT19ueOZLK5wCQ1mR+0GdrcHRCLr 7Sdw1d7aLxMT+5nvqfzsmbDullsWOD6RnMdcqhOxZZvpay8OeuK+yb8FVQ4sOIzB FiNi5cNOFFHg+8dZQoDrK3BpwNxYdGHsYIwU9u6DWWqXybBnB9jd2pve9PlzQUbO eHEa4Z+jPqxY829f4ldaql7ig8e6BaInTfs2wPnHJ+606g2UH86QUmrVAjVzlLCm nqoGymoAPGA4ObHu9X3kO8viMBId9FzooVqR8a9En7ZE0Dm9O7puzXR7A1f5sHoz JdYHnr32I+B8iOixhDUtxIY4GA8biGATNaPd8XR2Ca1hPuZRVuIiGG9HDqUEtXhV fY5qjTjaThIVKtYgEkWMT+Wet3DPPiWT3ftNOE907e6EWEBCHgsEuuZnAbku1GgD LBH4/a/yo9bNvGZKRaTUM/1TXhM5XgVKjd07B4cChgKypAVHvef3HKfCG2U/DkyA LjteHt/V807MtSlQyYaXUTGtDCrQPSlMK5TjmqUnDwy6Qdq8dtWN3DtBWQARAQAB tCpDZXBoLmNvbSAocmVsZWFzZSBrZXkpIDxzZWN1cml0eUBjZXBoLmNvbT6JAjgE EwECACIFAlX4hgkCGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOhKwsBG DzmUXdIQAI8YPcZMBWdv489q8CzxlfRIRZ3Gv/G/8CH+EOExcmkVZ89mVHngCdAP DOYCl8twWXC1lwJuLDBtkUOHXNuR5+Jcl5zFOUyldq1Hv8u03vjnGT7lLJkJoqpG l9QD8nBqRvBU7EM+CU7kP8+09b+088pULil+8x46PwgXkvOQwfVKSOr740Q4J4nm /nUOyTNtToYntmt2fAVWDTIuyPpAqA6jcqSOC7Xoz9cYxkVWnYMLBUySXmSS0uxl 3p+wK0lMG0my/gb+alke5PAQjcE5dtXYzCn+8Lj0uSfCk8Gy0ZOK2oiUjaCGYN6D u72qDRFBnR3jaoFqi03bGBIMnglGuAPyBZiI7LJgzuT9xumjKTJW3kN4YJxMNYu1 FzmIyFZpyvZ7930vB2UpCOiIaRdZiX4Z6ZN2frD3a/vBxBNqiNh/BO+Dex+PDfI4 TqwF8zlcjt4XZ2teQ8nNMR/D8oiYTUW8hwR4laEmDy7ASxe0p5aijmUApWq5UTsF +s/QbwugccU0iR5orksM5u9MZH4J/mFGKzOltfGXNLYI6D5Mtwrnyi0BsF5eY0u6 vkdivtdqrq2DXY+ftuqLOQ7b+t1RctbcMHGPptlxFuN9ufP5TiTWSpfqDwmHCLsT k2vFiMwcHdLpQ1IH8ORVRgPPsiBnBOJ/kIiXG2SxPUTjjEGOVgeA =/Tod -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: releasenotes/config.yaml ================================================ --- # The 2024.2.0 is the release when we introduced CHANGELOG.md # When we generate the CHANGELOG.md we append all earlier release notes as well. # So the earliest release we should take while generating the CHANGELOG.md # is 2024.2.0. earliest_version: 2024.2.0 branch: master collapse_pre_releases: false stop_at_branch_base: true sections: - [aodh, aodh Chart] - [barbican, barbican Chart] - [blazar, blazar Chart] - [ca-issuer, ca-issuer Chart] - [calico, calico Chart] - [ceilometer, ceilometer Chart] - [ceph-client, ceph-client Chart] - [ceph-mon, ceph-mon Chart] - [ceph-osd, ceph-osd Chart] - [ceph-provisioners, ceph-provisioners Chart] - [cinder, cinder Chart] - [cloudkitty, cloudkitty Chart] - [designate, designate Chart] - [elastic-apm-server, elastic-apm-server Chart] - [elastic-filebeat, elastic-filebeat Chart] - [elastic-metricbeat, elastic-metricbeat Chart] - [elastic-packetbeat, elastic-packetbeat Chart] - [elasticsearch, elasticsearch Chart] - [etcd, etcd Chart] - [fluentbit, fluentbit Chart] - [fluentd, fluentd Chart] - [freezer, freezer Chart] - [glance, glance Chart] - [gnocchi, gnocchi Chart] - [grafana, grafana Chart] - [heat, heat Chart] - [helm-toolkit, helm-toolkit Chart] - [horizon, horizon Chart] - [ingress, ingress Chart] - [ironic, ironic Chart] - [keystone, keystone Chart] - [kibana, kibana Chart] - [kube-dns, kube-dns Chart] - [kubernetes-keystone-webhook, kubernetes-keystone-webhook Chart] - [kubernetes-node-problem-detector, kubernetes-node-problem-detector Chart] - [ldap, ldap Chart] - [libvirt, libvirt Chart] - [local-storage, local-storage Chart] - [magnum, magnum Chart] - [mariadb, mariadb Chart] - [memcached, memcached Chart] - [mistral, mistral Chart] - [nagios, nagios Chart] - [namespace-config, namespace-config Chart] - [neutron, neutron Chart] - [nfs-provisioner, nfs-provisioner Chart] - [nova, nova Chart] - [octavia, octavia Chart] - [openvswitch, openvswitch Chart] - [ovn, ovn Chart] - [placement, placement Chart] - [postgresql, postgresql Chart] - [powerdns, powerdns Chart] - [prometheus-alertmanager, prometheus-alertmanager Chart] - [prometheus-blackbox-exporter, prometheus-blackbox-exporter Chart] - [prometheus-kube-state-metrics, prometheus-kube-state-metrics Chart] - [prometheus-node-exporter, prometheus-node-exporter Chart] - [prometheus-openstack-exporter, prometheus-openstack-exporter Chart] - [prometheus-process-exporter, prometheus-process-exporter Chart] - [prometheus, prometheus Chart] - [rabbitmq, rabbitmq Chart] - [rally, rally Chart] - [redis, redis Chart] - [registry, registry Chart] - [tacker, tacker Chart] - [tempest, tempest Chart] - [trove, trove Chart] - [watcher, watcher Chart] - [features, New Features] - [issues, Known Issues] - [upgrade, Upgrade Notes] - [api, API Changes] - [security, Security Issues] - [fixes, Bug Fixes] - [zaqar, zaqar Chart] template: | --- # To create a new release note related to a specific chart: # reno new # # To create a new release note for a common change (when multiple charts # are changed): # reno new common : - | Describe changes here, or remove this section. This paragraph will appear in the unnamed section of the /CHANGELOG.md for a given version. features: - | List new features here, or remove this section. If this section is given in the releasenotes/notes/-.yaml it will only appear in the "New Features" section of the /CHANGELOG.md. If this section is given in the releasenotes/notes/common-.yaml it will appear in the CHANGELOG.md files of all charts. issues: - | List known issues here, or remove this section. If this section is given in the releasenotes/notes/-.yaml it will only appear in the "Known Issues" section of the /CHANGELOG.md. If this section is given in the releasenotes/notes/common-.yaml it will appear in the CHANGELOG.md files of all charts. upgrade: - | List upgrade notes here, or remove this section. If this section is given in the releasenotes/notes/-.yaml it will only appear in the "Upgrade Notes" section of the /CHANGELOG.md. If this section is given in the releasenotes/notes/common-.yaml it will appear in the CHANGELOG.md files of all charts. api: - | List API changes here (e.g. values format), or remove this section. If this section is given in the releasenotes/notes/-.yaml it will only appear in the "API Changes" section of the /CHANGELOG.md. If this section is given in the releasenotes/notes/common-.yaml it will appear in the CHANGELOG.md files of all charts. security: - | List security issues here, or remove this section. If this section is given in the releasenotes/notes/-.yaml it will only appear in the "Security Issues" section of the /CHANGELOG.md. If this section is given in the releasenotes/notes/common-.yaml it will appear in the CHANGELOG.md files of all charts. fixes: - | List bug fixes here, or remove this section. If this section is given in the releasenotes/notes/-.yaml it will only appear in the "Bug Fixes" section of the /CHANGELOG.md. If this section is given in the releasenotes/notes/common-.yaml it will appear in the CHANGELOG.md files of all charts. ... ... ================================================ FILE: releasenotes/notes/added-nova-uid-parameter-to-ovs-chart-41d2b05b79300a31.yaml ================================================ --- other: - | When running openvswitch (OVS) with DPDK enabled, vhost-user sockets are used to connect VMs to OVS. nova-compute needs access to those sockets in order to plug them into OVS. For this reason, the directory containing vhost-user sockets must have proper permissions. The openvswitch chart now sets ownership of this directory to the UID of the nova user. The OVS chart uses the same default as the Nova chart (42424). However, if the Nova UID is changed in the Nova chart in a particular deployment, it also needs to be changed in the OVS chart correspondingly if DPDK is used. ... ================================================ FILE: releasenotes/notes/aodh-0fe345390dd08642.yaml ================================================ --- aodh: - | Remove outdated default kolla images and use quay.io/airshipit/aodh:2025.1-ubuntu_noble ... ================================================ FILE: releasenotes/notes/aodh-1002dad350db1c60.yaml ================================================ --- aodh: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/aodh/aodh.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/aodh-bb91c011b0c7d911.yaml ================================================ --- aodh: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/aodh.yaml ================================================ --- aodh: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.2.0 Remove support for releases before T - 0.2.1 Use policies in yaml format - 0.2.2 Update htk requirements repo - 0.2.3 Enable taint toleration for Openstack services - 0.2.4 Migrated CronJob resource to batch/v1 API version & PodDisruptionBudget to policy/v1 - 0.2.5 Added OCI registry authentication - 0.2.6 Remove default policy rules - 0.2.7 Replace node-role.kubernetes.io/master with control-plane - 0.2.8 Define service_type in keystone_authtoken to support application credentials with access rules - 0.2.9 Enable custom annotations for Openstack pods - 0.2.10 Enable custom annotations for Openstack secrets - 0.2.11 Update images used by default - 0.2.12 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.13 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/barbican-669168de73ab5847.yaml ================================================ --- barbican: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/barbican/barbican.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/barbican-d291498fada9e601.yaml ================================================ --- barbican: - | Removed the autocommit option, which has been deprecated since SQLAlchemy 2.0. ... ================================================ FILE: releasenotes/notes/barbican-ead8061b2a6b1b1b.yaml ================================================ --- barbican: - Use more standard DB config setting ... ================================================ FILE: releasenotes/notes/barbican.yaml ================================================ --- barbican: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Added post-install and post-upgrade helm hook for Jobs - 0.2.0 Remove support for releases before T - 0.2.1 Use policies in yaml format - 0.2.2 Add helm hook conditional - 0.2.3 Add support for master kek rotation - 0.2.4 Add Ussuri release support - 0.2.5 Add Victoria and Wallaby releases support - 0.2.6 Allow Barbican to talk to Mariadb over TLS - 0.2.7 Fix db connection key name - 0.2.8 Update htk requirements repo - 0.2.9 Removed default policy in favor in code policy - 0.2.10 Enable taint toleration for Openstack services - 0.2.11 Fix job annotations for db init job - 0.2.12 Remove older values overrides - 0.2.13 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.14 Add Xena and Yoga values overrides - 0.2.15 Added OCI registry authentication - 0.2.16 Distinguish between port number of internal endpoint and binding port number - 0.2.17 Use HTTP probe instead of TCP probe - 0.2.18 Support TLS for ks jobs - 0.2.19 Support SSL offloading at reverse proxy for internal and admin endpoints - 0.3.0 Remove support for Train and Ussuri - 0.3.1 Replace node-role.kubernetes.io/master with control-plane - 0.3.2 Define service_type in keystone_authtoken to support application credentials with access rules - 0.3.3 Add Zed overrides - 0.3.4 Add 2023.1 overrides - 0.3.5 Add Ubuntu Jammy overrides - 0.3.6 Add 2023.2 Ubuntu Jammy overrides - 0.3.7 Fix TLS connection to rabbitmq, and generate barbican certificate - 0.3.8 Make barbican TLS configuration granular - 0.3.9 Enable custom annotations for Openstack pods - 0.3.10 Add 2024.1 overrides - 0.3.11 Enable custom annotations for Openstack secrets - 0.3.12 Update images used by default - 0.3.13 Sync uWSGI config to other services - 0.3.14 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.15 Add 2024.2 Ubuntu Jammy overrides - 0.3.16 Add livenessProbe and change path in probe - 0.3.17 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/blazar-73cedded47699964.yaml ================================================ --- blazar: - | Added initial support for OpenStack Blazar reservation service deployment in Kubernetes environments through Helm charts. This enables users to deploy and manage Blazar services alongside other OpenStack components. features: - | Introduced Blazar Helm chart with support for: - Blazar API and Manager service deployment and configuration - Integration with existing OpenStack identity services - Support for custom Blazar configuration through values.yaml ... ================================================ FILE: releasenotes/notes/blazar-a7b9b29ba15720c0.yaml ================================================ --- blazar: - | Updating values.yaml for adding support for creating flavor-based instance reservations. ... ================================================ FILE: releasenotes/notes/blazar-b7fc5016b49c8f59.yaml ================================================ --- blazar: - | Updating secret-keystone.yaml to make it similar to other services. Also updating values.yaml to use unique ports and disabling node_port to make it similar to other services, and for DNS lookups and ingress support. ... ================================================ FILE: releasenotes/notes/ca-clusterissuer.yaml ================================================ --- ca-clusterissuer: - 0.1.0 Initial Chart - 0.1.1 Update htk requirements - 0.1.2 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ca-issuer.yaml ================================================ --- ca-issuer: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update apiVersion of Issuer to v1 - 0.1.3 Revert - Update apiVersion of Issuer to v1 - 0.2.0 Only Cert-manager version v1.0.0 or greater will be supported - 0.2.1 Cert-manager "< v1.0.0" supports cert-manager.io/v1alpha3 else use api cert-manager.io/v1 - 0.2.2 Update htk requirements - 0.2.3 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ceilometer-15768e1064d3339d.yaml ================================================ --- ceilometer: - | Support for ceilometer-collector service was removed. This service was removed from ceilometer during queens cycle. ... ================================================ FILE: releasenotes/notes/ceilometer-8fc69d6664cdf101.yaml ================================================ --- ceilometer: - | Removed metrics which require Intel CMT perf events. ... ================================================ FILE: releasenotes/notes/ceilometer-ab177a5c0aad98df.yaml ================================================ --- ceilometer: - | Removed support for ceilometer-api, which was removed from ceilometer long time ago. - | Removed support for oslo.db backend and mongodb backend of ceilometer, which haven't been supported by ceulometer actually for multiple releases. ... ================================================ FILE: releasenotes/notes/ceilometer-b03ea218e1e61f90.yaml ================================================ --- ceilometer: - | Remove outdated default kolla images and use quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ... ================================================ FILE: releasenotes/notes/ceilometer-b86532145d088208.yaml ================================================ --- ceilometer: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/ceilometer/ceilometer.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/ceilometer-c08f029ffa1e122f.yaml ================================================ --- ceilometer: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/ceilometer.yaml ================================================ --- ceilometer: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.2.0 Remove support for releases before T - 0.2.1 Use policies in yaml format - 0.2.2 Update htk requirements repo - 0.2.3 Enable taint toleration for Openstack services - 0.2.4 Update default image values to Wallaby - 0.2.5 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.6 Added OCI registry authentication - 0.2.7 Remove default policy rules - 0.2.8 Replace node-role.kubernetes.io/master with control-plane - 0.2.9 Enable custom annotations for Openstack pods - 0.2.10 Enable custom annotations for Openstack secrets - 0.2.11 Update images used by default - 0.2.12 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.13 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ceph-adapter-rook-2fd83689f9bf78fb.yaml ================================================ --- ceph-adapter-rook: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/ceph-adapter-rook-f0855e8843fe615f.yaml ================================================ --- ceph-adapter-rook: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/ceph-adapter-rook.yaml ================================================ --- ceph-adapter-rook: - 0.1.0 Initial Chart - 0.1.1 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.2 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.3 Simplify and remove unnecessary entities - 0.1.4 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.5 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ceph-client-055d675e86b2d0ea.yaml ================================================ --- ceph-client: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/ceph-client-f4c8397a4313c53a.yaml ================================================ --- ceph-client: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/ceph-client.yaml ================================================ --- ceph-client: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 fix the logic to disable the autoscaler on pools - 0.1.3 Run as ceph user and disallow privilege escalation - 0.1.4 Improvements for ceph-client helm tests - 0.1.5 Fix Helm test check_pgs() check for inactive PGs - 0.1.6 Uplift from Nautilus to Octopus release - 0.1.7 Don't wait for premerge PGs in the rbd pool job - 0.1.8 enhance logic to enable the autoscaler for Octopus - 0.1.9 Revert "[ceph-client] enhance logic to enable the autoscaler for Octopus" - 0.1.10 Separate pool quotas from pg_num calculations - 0.1.11 enhance logic to enable and disable the autoscaler - 0.1.12 Disable autoscaling before pools are created - 0.1.13 Fix ceph-client helm test - 0.1.14 Allow Ceph RBD pool job to leave failed pods - 0.1.15 Make ceph-client helm test more PG specific - 0.1.16 Make Ceph pool init job consistent with helm test - 0.1.17 Add pool rename support for Ceph pools - 0.1.18 Add pool delete support for Ceph pools - 0.1.19 Use full image ref for docker official images - 0.1.20 Export crash dumps when Ceph daemons crash - 0.1.21 Fix Ceph checkDNS script - 0.1.22 Set pg_num_min in all cases - 0.1.23 Helm 3 - Fix Job labels - 0.1.24 Performance optimizations for the ceph-rbd-pool job - 0.1.25 Update htk requirements - 0.1.26 Fix ceph-rbd-pool deletion race - 0.1.27 Update ceph_mon config to ips from fqdn - 0.1.28 Fix ceph.conf update job labels, rendering - 0.1.29 Consolidate mon_host discovery - 0.1.30 Move ceph-mgr deployment to the ceph-mon chart - 0.1.31 Consolidate mon_endpoints discovery - 0.1.32 Simplify test rules for ceph-mgr deployment - 0.1.33 More robust naming of clusterrole-checkdns - 0.1.34 Migrated CronJob resource to batch/v1 API version - 0.1.35 Handle multiple mon versions in the pool job - 0.1.36 Add the ability to run Ceph commands from values - 0.1.37 Added OCI registry authentication - 0.1.38 Make use of noautoscale with Pacific - 0.1.39 Correct check for too many OSDs in the pool job - 0.1.40 Fix OSD count checks in the ceph-rbd-pool job - 0.1.41 Allow gate scripts to use 1x replication in Ceph - 0.1.42 Update all Ceph images to Focal - 0 1.43 Document the use of mon_allow_pool_size_one - 0.1.44 Allow pg_num_min to be overridden per pool - 0.1.45 Update Ceph to 17.2.6 - 0.1.46 Strip any errors preceding pool properties JSON - 0.1.47 Use Helm toolkit functions for Ceph probes - 0.1.48 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.1.49 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.50 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.51 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.52 Run utils-defragOSDs.sh in ceph-osd-default container - 0.1.53 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ceph-mon-1a1ecc38a96bfead.yaml ================================================ --- ceph-mon: - | Grant the bootstrap-osd client the necessary permissions to set cluster config parameters. ... ================================================ FILE: releasenotes/notes/ceph-mon-5ece5f0b0f571966.yaml ================================================ --- ceph-mon: - | Upgrade Ceph to 19.2.3 and adjust the ceph-mgr liveness probe to account for a new asok status query handler that returns an empty dictionary. ... ================================================ FILE: releasenotes/notes/ceph-mon-a1f450d714b90cfb.yaml ================================================ --- ceph-mon: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/ceph-mon-f029c2a86a0b7edd.yaml ================================================ --- ceph-mon: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/ceph-mon.yaml ================================================ --- ceph-mon: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency to >= 0.1.0 - 0.1.2 Enable shareProcessNamespace in mon daemonset - 0.1.3 Run mon container as ceph user - 0.1.4 Uplift from Nautilus to Octopus release - 0.1.5 Add Ceph CSI plugin - 0.1.6 Fix python3 issue for util scripts - 0.1.7 remove deprecated svc annotation tolerate-unready-endpoints - 0.1.8 Use full image ref for docker official images - 0.1.9 Remove unnecessary parameters for ceph-mon - 0.1.10 Export crash dumps when Ceph daemons crash - 0.1.11 Correct mon-check executing binary and logic - 0.1.12 Fix Ceph checkDNS script - 0.1.13 Helm 3 - Fix Job labels - 0.1.14 Update htk requirements - 0.1.15 Prevent mon-check from removing mons when down temporarily - 0.1.16 Correct Ceph Mon Check Ports - 0.1.17 Skip monmap endpoint check for missing mons - 0.1.18 Move ceph-mgr deployment to the ceph-mon chart - 0.1.19 Add a post-apply job to restart mons after mgrs - 0.1.20 Consolidate mon_endpoints discovery - 0.1.21 Change configmap names to be based on release name - 0.1.22 Correct configmap names for all resources - 0.1.23 Release-specific ceph-template configmap name - 0.1.24 Prevents mgr SA from repeated creation - 0.1.25 Allow for unconditional mon restart - 0.1.26 Added OCI registry authentication - 0.1.27 Update all Ceph images to Focal - 0.1.28 Document the use of mon_allow_pool_size_one - 0.1.29 Update Ceph to 17.2.6 - 0.1.30 Use Helm tookkit functions for Ceph probes - 0.1.31 Add Rook Helm charts for managing Ceph with Rook - 0.1.32 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.1.33 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.34 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.35 Use seprate secrets for CSI plugin and CSI provisioner - 0.1.36 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.37 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ceph-osd-294b73092b0b301b.yaml ================================================ --- ceph-osd: - | Add a config script to set Ceph configuration options from Helm values. In some cases, settings in ceph.conf are not effective and must be set via 'ceph config set' commands. This script is called during OSD initialization to set these options. Also, bluestore_elastic_shared_blobs=false is added to the Ceph config to work around https://tracker.ceph.com/issues/70390. ... ================================================ FILE: releasenotes/notes/ceph-osd-c897b82dd8d0104b.yaml ================================================ --- ceph-osd: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/ceph-osd-e9bd9ab0cb036080.yaml ================================================ --- ceph-osd: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/ceph-osd.yaml ================================================ --- ceph-osd: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency to >= 0.1.0 - 0.1.2 wait for only osd pods from post apply job - 0.1.3 Search for complete logical volume name for OSD data volumes - 0.1.4 Don't try to prepare OSD disks that are already deployed - 0.1.5 Fix the sync issue between osds when using shared disk for metadata - 0.1.6 Logic improvement for used osd disk detection - 0.1.7 Synchronization audit for the ceph-volume osd-init script - 0.1.8 Update post apply job - 0.1.9 Check inactive PGs multiple times - 0.1.10 Fix typo in check inactive PGs logic - 0.1.11 Fix post-apply job failure related to fault tolerance - 0.1.12 Add a check for misplaced objects to the post-apply job - 0.1.13 Remove default OSD configuration - 0.1.14 Alias synchronized commands and fix descriptor leak - 0.1.15 Correct naming convention for logical volumes in disk_zap() - 0.1.16 dmsetup remove logical devices using correct device names - 0.1.17 Fix a bug with DB orphan volume removal - 0.1.18 Uplift from Nautilus to Octopus release - 0.1.19 Update rbac api version - 0.1.20 Update directory-based OSD deployment for image changes - 0.1.21 Refactor Ceph OSD Init Scripts - First PS - 0.1.22 Refactor Ceph OSD Init Scripts - Second PS - 0.1.23 Use full image ref for docker official images - 0.1.24 Ceph OSD Init Improvements - 0.1.25 Export crash dumps when Ceph daemons crash - 0.1.26 Mount /var/crash inside ceph-osd pods - 0.1.27 Limit Ceph OSD Container Security Contexts - 0.1.28 Change var crash mount propagation to HostToContainer - 0.1.29 Fix Ceph checkDNS script - 0.1.30 Ceph OSD log-runner container should run as ceph user - 0.1.31 Helm 3 - Fix Job labels - 0.1.32 Update htk requirements - 0.1.33 Update log-runner container for MAC - 0.1.34 Remove wait for misplaced objects during OSD restarts - 0.1.35 Consolidate mon_endpoints discovery - 0.1.36 Add OSD device location pre-check - 0.1.37 Add a disruptive OSD restart to the post-apply job - 0.1.38 Skip pod wait in post-apply job when disruptive - 0.1.39 Allow for unconditional OSD restart - 0.1.40 Remove udev interactions from osd-init - 0.1.41 Remove ceph-mon dependency in ceph-osd liveness probe - 0.1.42 Added OCI registry authentication - 0.1.43 Update all Ceph images to Focal - 0.1.44 Update Ceph to 17.2.6 - 0.1.45 Extend the ceph-osd post-apply job PG wait - 0.1.46 Use Helm toolkit functions for Ceph probes - 0.1.47 Add disk zap to OSD init forced repair case - 0.1.48 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.1.49 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.50 Allow lvcreate to wipe existing LV metadata - 0.1.51 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.52 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.53 Update ceph-daemon to be able to use tini init system - 0.1.54 Remove use of tini for ceph-daemon - 0.1.55 Update ceph-osd pod containers to make sure OSD pods are properly terminated at restart - 0.1.56 Add preStop lifecycle script to log-runner - 0.1.57 Added code to kill another background process in log-runner at restart - 0.1.58 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ceph-provisioners-091a682dc01c219f.yaml ================================================ --- ceph-provisioners: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/ceph-provisioners-c4334743e1cadc04.yaml ================================================ --- ceph-provisioners: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/ceph-provisioners.yaml ================================================ --- ceph-provisioners: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Validate each storageclass created - 0.1.3 Uplift from Nautilus to Octopus release - 0.1.4 Add Ceph CSI plugin - 0.1.5 Fix Helm tests for the Ceph provisioners - 0.1.6 Update ceph_mon config as per new ceph clients - 0.1.7 Use full image ref for docker official images - 0.1.8 Enable Ceph CSI Provisioner to Stand Alone - 0.1.10 Add check for empty ceph endpoint - 0.1.11 Limit Ceph Provisioner Container Security Contexts - 0.1.12 Add ceph mon v2 port for ceph csi provisioner - 0.1.13 Fix ceph-provisioner rbd-healer error - 0.1.14 Helm 3 - Fix Job labels - 0.1.15 Add support to connect to rook-ceph cluster - 0.1.16 Update htk requirements - 0.1.17 Consolidate mon_endpoints discovery - 0.1.18 Update CSI images & fix ceph csi provisioner RBAC - 0.1.19 Add pods watch and list permissions to cluster role - 0.1.20 Add missing CRDs for volume snapshots (classes, contents) - 0.1.21 Added OCI registry authentication - 0.1.22 Remove legacy Ceph provisioners - 0.1.23 Remove unnecessary templates - 0.1.24 Update all Ceph images to Focal - 0.1.25 Update kubernetes registry to registry.k8s.io - 0.1.26 Update Ceph to 17.2.6 - 0.1.27 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.1.28 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.29 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.30 Specify CSI drivername in values.yaml - 0.1.31 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.32 Update ceph_rbd_provisioner image to 18.2.2 - 0.1.33 Remove dependencies on legacy provisioners - 0.1.34 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ceph-rgw-1dc7fd498ff7ed46.yaml ================================================ --- ceph-rgw: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/ceph-rgw-9d99622a011584b0.yaml ================================================ --- ceph-rgw: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/ceph-rgw.yaml ================================================ --- ceph-rgw: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Uplift from Nautilus to Octopus release - 0.1.3 update rbac api version - 0.1.4 Rgw placement target support - 0.1.5 Add tls support - 0.1.6 Update tls override options - 0.1.7 Use ca cert for helm tests - 0.1.8 Add placement target delete support to RGW - 0.1.9 Use full image ref for docker official images - 0.1.10 Fix a bug in placement target deletion for new targets - 0.1.11 Change s3 auth order to use local before external - 0.1.12 Export crash dumps when Ceph daemons crash - 0.1.13 Add configmap hash for keystone rgw - 0.1.14 Disable crash dumps for rgw - 0.1.15 Correct rgw placement target functions - 0.1.16 Helm 3 - Fix Job labels - 0.1.17 Update htk requirements - 0.1.18 Consolidate mon_endpoints discovery - 0.1.19 Add ClusterRole to the bootstrap-job - 0.1.20 Enable taint toleration for Openstack services jobs - 0.1.21 Correct mon discovery for multiple RGWs in different NS - 0.1.22 Update default image values - 0.1.23 Added OCI registry authentication - 0.1.24 Replace civetweb with beast for unencrypted connections - 0.1.25 Update all Ceph images to Focal - 0.1.26 Replace node-role.kubernetes.io/master with control-plane - 0.1.27 Update Ceph to 17.2.6 - 0.1.28 Use Helm toolkit functions for Ceph probes - 0.1.29 Add 2023.1 Ubuntu Focal overrides - 0.1.30 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.1.31 Add a ceph-rgw-pool job to manage RGW pools - 0.1.32 Multiple namespace support for the ceph-rgw-pool job - 0.1.33 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.34 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.35 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.36 Add 2024.1 Ubuntu Jammy overrides - 0.1.37 Update heat image default tag to 2024.1-ubuntu_jammy - 0.1.38 Add 2024.2 overrides - 0.1.39 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/cert-rotation-06fbf166bc55e372.yaml ================================================ --- cert-rotation: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/cert-rotation.yaml ================================================ --- cert-rotation: - 0.1.0 Initial Chart - 0.1.1 Return true if grep finds no match - 0.1.2 Correct and enhance the rotation script - 0.1.3 Update htk requirements - 0.1.4 Consider initContainers when restarting resources - 0.1.5 Migrated CronJob resource to batch/v1 API version - 0.1.6 Added OCI registry authentication - 0.1.7 Update all Ceph images to Focal - 0.1.8 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.9 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.10 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/change-default-ovs-image-c1e24787f1b03170.yaml ================================================ --- other: - | The default image used by the openvswitch chart has been changed from a a Debian based image including a source build of openvswitch v2.8.1 to an Ubuntu Bionic based image including a distribution provided build of openvswitch v2.9.2. ... ================================================ FILE: releasenotes/notes/change-memcache-backend-2d85a3c75b32db39.yaml ================================================ --- other: - | memcache backend for nova has been changed from oslo_cache.memcache_pool to dogpile.cache.memcached. You can revert to previous behaviour by setting conf.nova.cache.backend to "oslo_cache.memcache_pool". ... ================================================ FILE: releasenotes/notes/changed-ovs-dpdk-root-key-f8aaf3ad65189c8a.yaml ================================================ --- other: - | The root configuration key of the DPDK section has been changed from "dpdk" to "ovs_dpdk" to achieve parity with the corresponding configuration key in the Neutron chart. ... ================================================ FILE: releasenotes/notes/cinder-1db248fbc00e56ff.yaml ================================================ --- cinder: - | Add missing default glance identity endpoint for cinder. ... ================================================ FILE: releasenotes/notes/cinder-32aac095ffc09912.yaml ================================================ --- cinder: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/cinder-48232b427a294d57.yaml ================================================ --- cinder: - | Enable passing custom_job_annotations via values for specific Cinder jobs. This allows controlling Argo CD / Helm job behavior (e.g., sync-waves, hook policies) without modifying the chart templates directly. ... ================================================ FILE: releasenotes/notes/cinder-4e17dd8ee84ca1a2.yaml ================================================ --- cinder: - Fix ingress resource generation ... ================================================ FILE: releasenotes/notes/cinder-8f8fd56d2c9a5d75.yaml ================================================ --- cinder: - | Add cronjob to purge old deleted database entries ... ================================================ FILE: releasenotes/notes/cinder-92ee9aa061442690.yaml ================================================ --- cinder: - | Fix cinder volume container permission to fix FailedToDropPrivileges issue. ... ================================================ FILE: releasenotes/notes/cinder-a25114bef0ed2f56.yaml ================================================ --- upgrade: - | Change the default volume v3 path to not include the tenant_id. The is the current recommended approach and has not been necessary since the Yoga release. ... ================================================ FILE: releasenotes/notes/cinder-a530fe90112c74d1.yaml ================================================ --- cinder: - | Unhardcode readiness/liveness probe parameters for cinder-api ... ================================================ FILE: releasenotes/notes/cinder-aca94f2247bcddcd.yaml ================================================ --- cinder: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/cinder/cinder.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/cinder-b605e2bc57b6d49f.yaml ================================================ --- cinder: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/cinder-ddd3bb79dff72ba6.yaml ================================================ --- cinder: - | Add missing priority class and runtime class definition for cinder_db_purge ... ================================================ FILE: releasenotes/notes/cinder-ded5ec20ef58ac93.yaml ================================================ --- cinder: - | Split out the OpenStack service account definitions from cinder.conf and into config snippets which are loaded at /etc/cinder/cinder.d/, which is automatically loaded by OSLO when loading the main cinder.conf. This makes it easier for users to use the regular config generation while supplying credentials out of band. ... ================================================ FILE: releasenotes/notes/cinder-f177532ecd78dcec.yaml ================================================ --- fixes: - | Some backends of cinder will write some temp data into the state_path so it should be something available to be written to for the pod. ... ================================================ FILE: releasenotes/notes/cinder.yaml ================================================ --- cinder: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Support service tokens to prevent long-running job failures - 0.1.3 Support of external ceph backend - 0.1.4 Enable iscsi to work correctly in cinder volume - 0.1.5 Resolves mount issue with termination-log - 0.1.6 Enable volume backup for iSCSI based volumes - 0.1.7 Change Issuer to ClusterIssuer - 0.1.8 Revert - Change Issuer to ClusterIssuer - 0.1.9 Use HostToContainer mount propagation - 0.1.10 Change Issuer to ClusterIssuer - 0.1.11 Update RBAC apiVersion from /v1beta1 to /v1 - 0.1.12 Update volume type creation bootstrap logic - 0.1.13 Add NFS cinder backup override - 0.1.14 Add Multipathd support for ISCSI backed volumes - 0.1.15 Fix the problem in hostNetwork mode - 0.2.0 Remove support for releases before T - 0.2.1 Fix the ceph pool creations for openstack services - 0.2.2 Adding rabbitmq TLS logic - 0.2.3 Mount rabbitmq TLS secret - 0.2.4 Add Ussuri release support - 0.2.5 Add volume QoS support - 0.2.6 Added helm.sh/hook with value of post-install and post-upgrade - 0.2.7 Add Victoria and Wallaby releases support - 0.2.8 Add logic to bootstrap to handle upgrade timing issue - 0.2.9 Mount rabbitmq TLS secret for audit usage cronjob - 0.2.10 Helm 3 - Fix Job Labels - 0.2.11 Update htk requirements repo - 0.2.12 Remove cinder v1/v2 defaults - 0.2.13 Upgrade default images to ussuri - 0.2.14 Fix notifications - 0.2.15 Remove glance registry - 0.2.16 Enable taint toleration for Openstack services - 0.2.17 Remove unsupported values overrides - 0.2.18 Add helm hook in bootstrap job - 0.2.19 Add volume types visibility (public/private) - 0.2.20 Allow cinder v1/v2 endpoint creation if needed - 0.2.21 Migrated CronJob resource to batch/v1 API version & PodDisruptionBudget to policy/v1 - 0.2.22 Add Xena and Yoga values overrides - 0.2.23 Added OCI registry authentication - 0.2.24 Fix conditional check for cinder.utils.has_ceph_backend template - 0.2.25 Remove volumes unrelated with ceph backend from conditional volume list in cinder-volume deployment - 0.2.26 Distinguish between port number of internal endpoint and binding port number - 0.2.27 Support TLS endpoints - 0.2.28 Use HTTP probe instead of TCP probe - 0.2.29 Add SYS_ADMIN capability in cinder-volume - 0.2.30 Specify a existing configmap name for external ceph configuration - 0.2.31 Remove fixed node name from default values and add service cleaner cronjob - 0.2.32 Revert "Remove fixed node name from default values and add service cleaner cronjob" - 0.3.0 Remove support for Train and Ussuri - 0.3.1 Change ceph-config-helper image tag - 0.3.2 Remove default policy rules - 0.3.3 Fix for creation endpoins and services when v1/v2 are disabled - 0.3.4 Fix Helm hooks for storage bootstrap jobs - 0.3.5 Add Nova endpoint details to support online volume resize - 0.3.6 Fix ceph keyring placement for uppercased backends - 0.3.7 Allow Ceph pools to use 1x replication - 0.3.8 Update all Ceph images to Focal - 0.3.9 Replace node-role.kubernetes.io/master with control-plane - 0.3.10 Define service_type in keystone_authtoken to support application credentials with access rules - 0.3.11 Add Zed overrides - 0.3.12 Add 2023.1 overrides - 0.3.13 Use service tokens - 0.3.14 Add Ubuntu Jammy overrides - 0.3.15 Add 2023.2 Ubuntu Jammy overrides - 0.3.16 Update Ceph images to Jammy and Reef 18.2.1 - 0.3.17 Use uWSGI for API service - 0.3.18 Enable custom annotations for Openstack pods - 0.3.19 Add 2024.1 overrides - 0.3.20 Add readiness probe initial delay - 0.3.21 Enable custom annotations for Openstack secrets - 0.3.22 Update images used by default - 0.3.23 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.24 Fix volume type create to allow encrypt volume type - 0.3.25 Add 2024.2 Ubuntu Jammy overrides - 0.3.26 Mount /run/cryptsetup in cinder-volume container - 0.3.27 Add support for using a tmpfs for cinder image conversion - 0.3.28 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/cloudkitty-a95de06fbfeac965.yaml ================================================ --- cloudkitty: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/cloudkitty/cloudkitty.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/cloudkitty-d61bea096f10b731.yaml ================================================ --- cloudkitty: - | Add support for the Cloudkitty rating service to define how resource usage (compute, storage, network, etc) should be priced, then generate cost reports based on usage data collected from various sources. - Removed unnecessary code in pod spec, added metrics.yml to cloudkitty-api container features: - | Added Cloudkitty Helm chart with support for - Cloudkitty API and Processor deployment and config. - Customize cloudkitty metrics scraping from gnocchi/ceilometer and prometheus. - Provides APIs and a Horizon (dashboard) plugin to generate reports for projects/tenants. issues: - | Currently, there is no published support for Skyline dashboard integration Requires gnocchi to be installed and running within the local cluster, or cloudkitty processor pods will throw errors. ... ================================================ FILE: releasenotes/notes/cloudkitty.yaml ================================================ --- cloudkitty: - 0.1.0 Initial Chart ... ================================================ FILE: releasenotes/notes/common-695408be564c5d44.yaml ================================================ --- features: - | Update default ingress classes and annotations for charts to make them implementation agnostic. They used to be nginx specific because we always used ingress-nginx as the most common choice. Ingress-nginx is deprecated and will become unmaintained in Feb/2026. Now for all test jobs we use HAProxy Ingress as the default implementation. However any other implementation can be used as far as it suppports annotations similar to 'nginx.ingress.kubernetes.io/rewrite-target' or 'haproxy.org/path-rewrite' which are used in many OpenStack-Helm charts. ... ================================================ FILE: releasenotes/notes/common-76e452ae14eb3707.yaml ================================================ --- features: - | Update apparmor values to use security_context instead of annotations. ... ================================================ FILE: releasenotes/notes/common-8730c7058550f934.yaml ================================================ --- features: - | Added an extraObjects list to every chart to allow for adding extra Kubernetes objects along side the chart without modifying the chart. It has the added benefit of using Helm's built in templating so you are able to utilize other values supplied to the chart. ... ================================================ FILE: releasenotes/notes/common-d6d7b93fcc7296e9.yaml ================================================ --- features: - | Added emptyDir mounted at /var/lock and set OSLO_LOCK_PATH env var to this path for oslo.concurrency support in all OpenStack services. ... ================================================ FILE: releasenotes/notes/common-eb7338a63d83ad95.yaml ================================================ --- upgrade: - | Support for Helm 2 has been removed by removal of the helm3_hook value across all charts. It is no longer possible to set helm3_hook to False to support Helm 2. ... ================================================ FILE: releasenotes/notes/common-f19dec4799b18756.yaml ================================================ --- features: - | Add support for runtimeClassName and priorityClassName ... ================================================ FILE: releasenotes/notes/cyborg.yaml ================================================ --- cyborg: - 0.1.0 Initial Chart - 0.1.1 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.1.2 Added OCI registry authentication - 0.1.3 Define service_type in keystone_authtoken to support application credentials with access rules - 0.1.4 Enable custom annotations for Openstack pods - 0.1.5 Enable custom annotations for Openstack secrets - 0.1.6 Update images used by default - 0.1.7 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.8 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/designate-9ed4257ab657b224.yaml ================================================ --- designate: - | Add a periodic job to clean Designate services which not report it's heartbeat within two heartbeat interval cycle. ... ================================================ FILE: releasenotes/notes/designate-bc18055009645160.yaml ================================================ --- designate: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/designate/designate.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/designate.yaml ================================================ --- designate: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Added post-install and post-upgrade helm hooks on Jobs - 0.2.0 Remove support for releases before T - 0.2.1 Use policies in yaml format - 0.2.2 Update htk requirements repo - 0.2.3 Fix extra volume mounts - 0.2.4 Update default image values to Wallaby - 0.2.5 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.6 Added OCI registry authentication - 0.2.7 Use HTTP probe instead of TCP probe - 0.2.8 Remove default policy rules - 0.2.9 Define service_type in keystone_authtoken to support application credentials with access rules - 0.2.10 Uses uWSGI for API service - 0.2.11 Enable custom annotations for Openstack pods - 0.2.12 Enable custom annotations for Openstack secrets - 0.2.13 Update images used by default - 0.2.14 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.15 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/elastic-apm-server.yaml ================================================ --- elastic-apm-server: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Update htk requirements - 0.1.4 Added OCI registry authentication - 0.1.5 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.6 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/elastic-filebeat.yaml ================================================ --- elastic-filebeat: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Update htk requirements - 0.1.4 Added OCI registry authentication - 0.1.5 Replace node-role.kubernetes.io/master with control-plane - 0.1.6 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.7 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/elastic-metricbeat.yaml ================================================ --- elastic-metricbeat: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update RBAC apiVersion from /v1beta1 to /v1 - 0.1.3 Use full image ref for docker official images - 0.1.4 Update htk requirements - 0.1.5 Added OCI registry authentication - 0.1.6 Replace node-role.kubernetes.io/master with control-plane - 0.1.7 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.8 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/elastic-packetbeat.yaml ================================================ --- elastic-packetbeat: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Update htk requirements - 0.1.4 Added OCI registry authentication - 0.1.5 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.6 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/elasticseach-625bc83028513f08.yaml ================================================ --- elasticsearch: - | Properly configure RBAC for create-elasticsearch-templates and verify-repositories service accounts. This ensures they have the necessary permissions to access ObjectBucket cluster resources. ... ================================================ FILE: releasenotes/notes/elasticsearch-127e34013b70451d.yaml ================================================ --- elasticsearch: - Upgrade to the latest v8.18.1 - Replace the elasticsearch_templates image with a lighweight upstream image that includes yq and jq - Switch to the upstream image, as S3 repository support is natively integrated starting from v8.x (https://www.elastic.co/guide/en/elasticsearch/plugins/8.0/repository-s3.html) and elasticsearch_templates is replaced to use jq ... ================================================ FILE: releasenotes/notes/elasticsearch-1fb9cb9d0b6169a7.yaml ================================================ --- elasticsearch: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/elasticsearch-4a005ef3cec5f170.yaml ================================================ --- elasticsearch: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/elasticsearch-653d4b77cf26c277.yaml ================================================ --- elasticsearch: - Upgrade the Prometheus elasticsearch-exporter to the latest v1.9.0 - Rename the slm flag according to the changelog https://github.com/prometheus-community/elasticsearch_exporter/releases/tag/v1.9.0 ... ================================================ FILE: releasenotes/notes/elasticsearch-ba314935c85c3b25.yaml ================================================ --- elasticsearch: - | Elasticsearch job responsible for creation of s3 user and bucket required a secret radosgw-s3-admin-creds to be created, but its data wasn't used. Getting rid of this. ... ================================================ FILE: releasenotes/notes/elasticsearch-baf978b047efc111.yaml ================================================ --- elasticsearch: - Upgrade to v8.19.9 - Use absolute paths for log files due to upstream changes (https://github.com/elastic/elasticsearch/commit/6876b8cf05e8a5ae416b5c7394a9c887c8976cf1) ... ================================================ FILE: releasenotes/notes/elasticsearch.yaml ================================================ --- elasticsearch: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update to 7.6.2 image - 0.1.3 Add elasticsearch snapshot policy template for SLM - 0.1.4 Add elasticsearch ILM functionality - 0.1.5 Make templates job more generic - 0.1.6 Fix elasticsearch-master rendering error - 0.1.7 Pin Java options to specific versions - 0.1.8 Disable Curator in Gate & Chart Defaults - 0.2.0 Add more S3 configuration options - 0.2.1 Make templates job more robust & allow overrides - 0.2.2 Update the ES curator config to {} - 0.2.3 Add configurable backoffLimit to templates job - 0.2.4 Update helm-test script - 0.2.5 Enable TLS with Kibana - 0.2.6 Enable TLS path between nodes in cluster and TLS path between ceph-rgw - 0.2.7 Get connection option from values.yaml - 0.2.8 Use full image ref for docker official images - 0.2.9 Removed repo verification check from helm-test - 0.2.10 Enable TLS path between Prometheus-elasticsearch-exporter and Elasticsearch - 0.2.11 Enable TLS path between Curator and Elasticsearch - 0.2.12 Helm 3 - Fix Job labels - 0.2.13 Update htk requirements - 0.2.14 Fix cronjob rendering - 0.2.15 Fix elasticsearch-data shutdown - 0.2.16 Use python3 for helm tests when possible - 0.2.17 Annotate ES master/data sts with S3 secret hash - 0.2.18 Update default image value to Wallaby - 0.2.19 Migrated CronJob resource to batch/v1 API version - 0.2.20 Set default python for helm test - 0.2.21 Added OCI registry authentication - 0.2.22 Update all Ceph images to Focal - 0.2.23 Add configurable liveness probe for elasticsearch client - 0.2.24 Update Ceph to 17.2.6 - 0.2.25 Update ElasticSearch to 8.9.0 - 0.2.26 Add 2023.1 Ubuntu Focal overrides - 0.2.27 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.2.28 Utilize bucket claim CRD when using with Rook - 0.2.29 Make es curator path configurable - 0.2.30 Update curator for es v8 - 0.3.0 Update elasticsearch_exporter to v1.7.0 - 0.3.1 Update Ceph images to Jammy and Reef 18.2.1 - 0.3.2 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.3.3 Update es curator to 8.0.10 - 0.3.4 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.5 Remove gateway node role - 0.3.6 Add 2024.1 Ubuntu Jammy overrides - 0.3.7 Add 2024.2 overrides - 0.3.8 Remove use of python in helm tests - 0.3.9 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/etcd.yaml ================================================ --- etcd: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update to container image repo k8s.gcr.io - 0.1.3 Use full image ref for docker official images - 0.1.4 Update htk requirements - 0.1.5 Added OCI registry authentication - 0.1.6 Update kubernetes registry to registry.k8s.io - 0.1.7 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.8 Switch etcd to staetefulset - 0.1.9 Adding cronjob with etcd compaction - 0.1.10 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/fluentbit.yaml ================================================ --- fluentbit: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Update htk requirements - 0.1.4 Added OCI registry authentication - 0.1.5 Replace node-role.kubernetes.io/master with control-plane - 0.1.6 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.7 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/fluentd.yaml ================================================ --- fluentd: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Add Configurable Readiness and Liveness Probes - 0.1.3 Enable TLS path for output to Elasticsearch - 0.1.4 Use full image ref for docker official images - 0.1.5 Kafka brokers defined as a list with port "kafka1:9092,kafka2:9020,kafka3:9092" - 0.1.6 Update htk requirements - 0.1.7 Update default image values to Wallaby - 0.1.8 Added OCI registry authentication - 0.1.9 Set sticky bit for tmp - 0.1.10 Add 2023.1 Ubuntu Focal overrides - 0.1.11 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.12 Add 2024.1 Ubuntu Jammy overrides - 0.1.13 Add 2024.2 overrides - 0.1.14 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/freezer-3272cc6ed891f5a3.yaml ================================================ --- freezer: > Added support for Freezer disaster recovery and backup-as-a-service component for OpenStack. It provides a way to back up various resources, such as virtual machine instances, databases, and file systems. It will allow users to schedule backups, restore data, and manage the lifecycle of their backups to ensure data protection and business continuity within an OpenStack cloud. features: - | Introduced Freezer Helm chart with support for: - Freezer API, Scheduler, Agent service deployment and configuration - Integration with existing OpenStack identity services - Support for custom Blazar configuration through values.yaml ... ================================================ FILE: releasenotes/notes/glance-1245a71c1694b79c.yaml ================================================ --- glance: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/glance-79dad0da1e27df42.yaml ================================================ --- glance: - | Add support for etcSources to glance-metadefs-load job. ... ================================================ FILE: releasenotes/notes/glance-9043d8c0a8119256.yaml ================================================ --- glance: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/glance-cb814fab2bccc95e.yaml ================================================ --- glance: - | add raise_for_status method call to the livenessProbe command to properly raise an error when return code is 4xx (client error) or 5xx (server error) ... ================================================ FILE: releasenotes/notes/glance-cbd61a1ae1e902b5.yaml ================================================ --- glance: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/glance/glance.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/glance-e528d9f2473763a1.yaml ================================================ --- fixes: - | Fix missing job annotation support from values.yaml on the clean, metadefs-load, and storage-init jobs. ... ================================================ FILE: releasenotes/notes/glance.yaml ================================================ --- glance: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency to >= 0.1.0 - 0.1.2 Change issuer to clusterissuer - 0.1.3 Revert - Change issuer to clusterissuer - 0.1.4 Update RBAC apiVersion from /v1beta1 to /v1 - 0.1.5 Change Issuer to ClusterIssuer - 0.1.6 Update glance default policy values - 0.1.7 Update storage init script with cacert - 0.1.8 Update glance default policy values - 0.2.0 Remove support for releases before T - 0.2.1 Fix the ceph pool creations for openstack services - 0.2.2 Adding rabbitmq TLS logic - 0.2.3 Use policies in yaml format - 0.2.4 Mount rabbitmq TLS secret - 0.2.5 Add Ussuri release support - 0.2.6 Add Victoria and Wallaby releases support - 0.2.7 Added helm.sh/hook for the jobs - 0.2.8 Helm 3 - Fix Job Labels - 0.2.9 Helm 3 - Fix More Job Labels - 0.2.10 Update htk requirements repo - 0.3.0 Remove glance registry - 0.3.1 Enable taint toleration for Openstack services - 0.3.2 Decrease terminationGracePeriodSeconds on glance-api - 0.3.3 Update naming for subchart compatibility - 0.3.4 Change image default version to wallaby - 0.3.5 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.3.6 Add Xena and Yoga values overrides - 0.3.7 Fix glance-etc template changing due to comment and whitespace between install and first upgrade - 0.3.8 Added OCI registry authentication - 0.3.9 Support TLS endpoints - 0.3.10 Distinguish between port number of internal endpoint and binding port number - 0.3.11 Use HTTP probe instead of TCP probe - 0.3.12 Add support for using Cinder as backend - 0.4.0 Remove support for Train and Ussuri - 0.4.1 Remove default policy rules - 0.4.2 Allow Ceph pools to use 1x replication - 0.4.3 Update all Ceph images to Focal - 0.4.4 Replace node-role.kubernetes.io/master with control-plane - 0.4.5 Fix wrong configFile path in glance bootstrap container. - 0.4.6 Define service_type in keystone_authtoken to support application credentials with access rules - 0.4.7 Add Zed overrides - 0.4.8 Add 2023.1 overrides - 0.4.9 Use service tokens - 0.4.10 Add exec probe timeouts - 0.4.11 Bring liveness/readiness params out to values.yaml - 0.4.12 Add flag `keep_pvc` to allows set helm resource-policy for glance-images PVC to keep. - 0.4.13 Add Ubuntu Jammy overrides - 0.4.14 Bump Cirros version to 0.6.2 - 0.4.15 Add 2023.2 Ubuntu Jammy overrides - 0.4.16 Use --region option to prevent OS_SWIFT_ENDPOINT_PREFIX is broken in storage-init.sh - 0.4.17 Update Ceph images to Jammy and Reef 18.2.1 - 0.4.18 Enable custom annotations for Openstack pods - 0.4.19 Add 2024.1 overrides - 0.4.20 Add readiness probe initial delay - 0.4.21 Use uWSGI - 0.4.22 Enable custom annotations for Openstack secrets - 0.4.23 Update images used by default - 0.4.24 Do not attach backend pvc to storage init pod - 0.4.25 Allow customisation of pvc storage accessMode so we can run multiple api pods - 0.4.26 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.5.0 Remove deprecated config options `stores` and `default_store` - 0.5.1 Add 2024.2 Ubuntu Jammy overrides - 0.5.2 Fix HTTP healthcheck URLs for Kubernetes probes - 0.5.3 Add override for downloading Ubuntu image - 0.5.4 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/gnocchi-37ba93d527c7ba75.yaml ================================================ --- gnocchi: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/gnocchi-71bec40a3416cb8a.yaml ================================================ --- gnocchi: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/gnocchi.yaml ================================================ --- gnocchi: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Helm 3 - Fix Job labels - 0.1.4 Update htk requirements - 0.1.5 Enable taint toleration for Openstack services jobs - 0.1.6 Update all Ceph images to Focal - 0.1.7 Replace node-role.kubernetes.io/master with control-plane - 0.1.8 Migrated pdb resource to policy/v1 API version - 0.1.9 Migrated CronJob resource to batch/v1 API version - 0.1.10 Update Ceph to 17.2.6 - 0.1.11 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.1.12 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.13 Bugfix Ceph user creation for RBD access - 0.1.14 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.15 Add 2023.2 Ubuntu Jammy overrides - 0.1.16 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.17 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/grafana-b3fac6a311d115a6.yaml ================================================ --- grafana: - Adjust Python code for SQLAlchemy 2.0 compatibility ... ================================================ FILE: releasenotes/notes/grafana-d1a2049e057fe878.yaml ================================================ --- grafana: - Upgrade Grafana to the latest v12.4.2. - Upgrade grafana-image-renderer to v5.7.3. - Migrate deprecated parameters and add new ones in Grafana configuration. - Fix Grafana helm Selenium test - wait for login form, not page title. ... ================================================ FILE: releasenotes/notes/grafana.yaml ================================================ --- grafana: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update Grafana version - 0.1.3 Provision any dashboard as homepage - 0.1.4 Enable TLS for Grafana - 0.1.5 Enable TLS between Grafana and Prometheus - 0.1.6 Enable TLS for Grafana ingress path - 0.1.7 Update Grafana version and Selenium script - 0.1.8 Use full image ref for docker official images - 0.1.9 Add Alertmanager dashboard to Grafana - 0.1.10 Helm 3 - Fix Job labels - 0.1.11 Update htk requirements - 0.1.12 Add iDRAC dashboard to Grafana - 0.1.13 Update prometheus metric name - 0.1.14 Add run migrator job - 0.1.15 Added OCI registry authentication - 0.1.16 Grafana 8.5.10 with unified alerting - 0.1.17 Fix uid for the user grafana - 0.1.18 Migrator job is now mariadb-fail-proof - 0.1.19 Update grafana to 9.2.10 - 0.1.20 Upgrade osh-selenium image to latest-ubuntu_focal - 0.1.21 Fix run migrator job deployment condition - 0.1.22 Make selenium v4 syntax optional - 0.1.23 Modified selenium test for compatibility - 0.1.24 Add image rendering sidecar - 0.1.25 Add value for rendering sidecar feature - 0.1.26 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.27 Update default images tags. Add 2024.1-ubuntu_jammy overrides. - 0.1.28 Upgrade osh-selenium image to ubuntu_jammy - 0.1.29 Add 2024.2 overrides - 0.1.30 Update chart helm test environment variables - 0.1.31 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/heat-5e861ec1ee8e2784.yaml ================================================ --- heat: - | Create heat and heat_trustee service users in a single job. This is to align with the helm-toolkit change regarding Keystone user creation job. ... ================================================ FILE: releasenotes/notes/heat-7222563449ea848e.yaml ================================================ --- heat: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/heat/heat.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/heat-a584fab629e1c4fc.yaml ================================================ --- heat: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/heat.yaml ================================================ --- heat: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Remove tls values override for clients_heat - 0.1.3 Change Issuer to ClusterIssuer - 0.1.4 Revert - Change Issuer to ClusterIssuer - 0.1.5 Change Issuer to ClusterIssuer - 0.2.0 Remove support for releases before T - 0.2.1 Adding rabbitmq TLS logic - 0.2.2 Use policies in yaml format - 0.2.3 Mount rabbitmq TLS secret - 0.2.4 Add Ussuri release support - 0.2.5 Add Victoria and Wallaby releases support - 0.2.6 Added post-install and post-upgrade helm-hook for jobs - 0.2.7 Helm 3 - Fix Job Labels - 0.2.8 Update htk requirements repo - 0.2.9 Enable taint toleration for Openstack services - 0.2.10 Updated naming for subchart compatibility - 0.2.11 Remove old releases values override in heat - 0.2.12 Migrated CronJob resource to batch/v1 API version & PodDisruptionBudget to policy/v1 - 0.2.13 Add Xena and Yoga values overrides - 0.2.14 Added OCI registry authentication - 0.2.15 Distinguish between port number of internal endpoint and binding port number - 0.2.16 Support TLS endpoints - 0.2.17 Use HTTP probe instead of TCP probe - 0.2.18 Change hook weight for bootstrap job - 0.3.0 Remove support for Train and Ussuri - 0.3.1 Remove default policy rules - 0.3.2 Replace node-role.kubernetes.io/master with control-plane - 0.3.3 Define service_type in keystone_authtoken to support application credentials with access rules - 0.3.4 Add Zed overrides - 0.3.5 Add 2023.1 overrides - 0.3.6 Add Ubuntu Jammy overrides - 0.3.7 Add 2023.2 Ubuntu Jammy overrides - 0.3.8 Fixed annotation indentation for jobs - 0.3.9 Uses uWSGI for API services - 0.3.10 Enable custom annotations for Openstack pods - 0.3.11 Add 2024.1 overrides - 0.3.12 Add readiness probe initial delay - 0.3.13 Enable custom annotations for Openstack secrets - 0.3.14 Update images used by default - 0.3.15 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.16 Add 2024.2 Ubuntu Jammy overrides - 0.3.17 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/helm-toolkit-04996581655d9952.yaml ================================================ --- helm-toolkit: - | The 'service' domain and project are not scoped to regions in most multi-region installations and will instead be shared so it does not make sense to include the region name in the description for those. ... ================================================ FILE: releasenotes/notes/helm-toolkit-1ac16e62f779d907.yaml ================================================ --- helm-toolkit: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/helm-toolkit-49593d58783c3a97.yaml ================================================ --- helm-toolkit: - | Add priorityClassName and runtimeClassName snippets ... ================================================ FILE: releasenotes/notes/helm-toolkit-5fa68b35be3378b3.yaml ================================================ --- helm-toolkit: - | Removing non-used script which allows to create bucket using admin user. Actually any user can do this and there is better script which is utilized by elasticsearch chart: elasticsearch/templates/bin/_create_s3_buckets.sh.tpl The only requirement is - to create the user. Also, removing S3_ADMIN_<> env vars from job manifests (see helm-toolkit.snippets.rgw_s3_admin_env_vars) because those vars are not used by actual scripts. We now use ceph.conf and keyring to create a user. ceph.conf and keyring can be provisioned by either ceph chart or ceph-adapter-rook chart. ... ================================================ FILE: releasenotes/notes/helm-toolkit-81cf091a301877ff.yaml ================================================ --- fixes: - | Added new snippet to include failover OpenRC environment variables in backup cron jobs for MariaDB and PostgreSQL charts. ... ================================================ FILE: releasenotes/notes/helm-toolkit-9618f6c4379c13bc.yaml ================================================ --- helm-toolkit: - | If the specific job that is static dependency has its manifest disabled the user needs to have a long diff to replace out just that one job from being depended on. This makes it automatically disable waiting on those jobs if they've been disabled to make the dependency management easier for users. ... ================================================ FILE: releasenotes/notes/helm-toolkit-a2810391532bd64a.yaml ================================================ --- helm-toolkit: - | Modify job_ks_user template to be able to create multiple Keystone users ... ================================================ FILE: releasenotes/notes/helm-toolkit-acb954baa2fe7b2f.yaml ================================================ --- features: - | Add an ability to add more path into ingress rules, and add more ports into service. ... ================================================ FILE: releasenotes/notes/helm-toolkit-e84e695df114929d.yaml ================================================ --- helm-toolkit: - | Corrected helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount to cover the case when service account must have access to endpoint in different namespace. In that case Role/Binding are getting created in that endpoint namespace, but now rolebinding will be point to the service account in the original namespace, which is $.Release.Namespace. This was tested with elasticsearch chart where s3.clients.local-rgw-elasticsearch.settings.endpoint was pointing to another namespace. With whose changes job-s3-user was able to detect availability of that enpoint. Before changes init container had this error in the logs: Resolving dependency Service rook-ceph-rgw-default in namespace ceph failed: endpoints "rook-ceph-rgw-default" is forbidden: User "system:serviceaccount:osh-infra:elasticsearch-s3-user" cannot get resource "endpoints" in API group "" in the namespace "ceph" ... ================================================ FILE: releasenotes/notes/helm-toolkit-fa49be61648b2d72.yaml ================================================ --- helm-toolkit: - | Mount volumes requested into the job's pod. ... ================================================ FILE: releasenotes/notes/helm-toolkit.yaml ================================================ --- helm-toolkit: - 0.1.0 Initial Chart - 0.1.1 Add extra DNS names to Ingress - 0.1.2 Make database backups work with openstack Train - 0.1.3 Fix ks-user script case matching for domain - 0.1.4 Update ingress tpl in helmtoolkit - 0.1.5 Add capability to delete a backup archive - 0.2.0 Update default Kubernetes API for use with Helm v3 - 0.2.1 Change Issuer to ClusterIssuer - 0.2.2 Revert Change Issuer to ClusterIssuer - 0.2.3 Allow openstack service list to retry in event of keystone connection issues - 0.2.4 Added detailed FiXME for ks-service script bug and code changes - 0.2.5 Added logic to support cert-manager versioning - 0.2.6 Add metadata in job templates - 0.2.7 Replace brace expansion with more standardized Posix approach - 0.2.8 Override the expiry of Ingress TLS certificate - 0.2.9 Jobs; put labels only in the template spec - 0.2.10 Add more S3 configuration options - 0.2.11 Revert S3 User & Bucket job scripts to v0.2.9 - 0.2.12 Remove hook-delete-policy - 0.2.13 Modify connection args for s3 bucket creation when TLS is enabled - 0.2.14 Remove TLS_OPTION argument from s3 bucket creation job - 0.2.15 Adding TLS rabbitmq logic - 0.2.16 Add manual mode to the created backup file name - 0.2.17 Update db backup/restore retry for sending to remote - 0.2.18 Make Rabbit-init job more robust - 0.2.19 Revoke all privileges for PUBLIC role in postgres dbs - 0.2.20 Modify the template of rbac_role to make secrets accessible - 0.2.21 Fix issue with db backup error return code being eaten - 0.2.22 Add ability to set labels to add to resources - 0.2.23 Helm 3 - Fix Job labels - 0.2.24 Migrate Ingress resources to networking.k8s.io/v1 - 0.2.25 Set Security Context to ks-user job - 0.2.26 Revert Set Security Context to ks-user job - 0.2.27 Correct private key size input for Certificates and remove minor version support - 0.2.28 Set Security context to ks-user job at pod and container level - 0.2.29 Enhance mariadb backup - 0.2.30 Add ability to image pull secrets on pods - 0.2.31 Add log strings for alert generation - 0.2.32 Consolidate mon_endpoints discovery - 0.2.33 Remove set -x - 0.2.34 Modify database backup logic to maintain minimum number of backups - 0.2.35 Database B/R improvements - 0.2.36 Enable taint toleration for Openstack services jobs - 0.2.37 Updated chart naming for subchart compatibility - 0.2.38 Minor change to display archive directory with files in sub-directory - 0.2.39 Removed tillerVersion from Chart to pass helm3 linting - 0.2.40 Revert chart naming for subchart compatibility - 0.2.41 Database B/R - archive name parser added - 0.2.42 Database B/R - fix to make script compliant with a retention policy - 0.2.43 Support having a single external ingress controller - 0.2.44 Added OCI registry authentication - 0.2.45 Modify use_external_ingress_controller place in openstack-helm values.yaml - 0.2.46 Fixed for getting kibana ingress value parameters - 0.2.47 Adjusting of kibana ingress value parameters - 0.2.48 Added verify_databases_backup_archives function call to backup process and added remote backup sha256 hash verification - 0.2.49 Moved RabbitMQ Guest Admin removal to init - 0.2.50 Allow tls for external ingress without specifying key and crt - 0.2.51 Added a random delay up to 300 seconds to remote backup upload/download for load spreading purpose - 0.2.52 Decreased random delay to up to 30 seconds and switched remote backup verification protocol to md5 - 0.2.53 Update create db user queries - 0.2.54 Fix dependency resolver to ignore non-existing dependencyKey when dependencyMixinParam is a slice - 0.2.55 Updated deprecated IngressClass annotation - 0.2.56 Expose S3 credentials from Rook bucket CRD secret - 0.2.57 Safer file removal - 0.2.58 Backups verification improvements - 0.2.59 Added throttling remote backups - 0.2.60 Change default ingress pathType to Prefix - 0.2.61 Add custom pod annotations snippet - 0.2.62 Add custom secret annotations snippet - 0.2.63 Add custom job annotations snippet and wire it into job templates - 0.2.64 Use custom secret annotations snippet in other secret templates - 0.2.65 Escape special characters in password for DB connection - 0.2.66 Align db scripts with sqlalchemy 2.0 - 0.2.67 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.68 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.69 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.70 Decode url-encoded password for rabbit connection - 0.2.71 Add snippet with service parameters - 0.2.72 Add snippet configmap_oslo_policy - 0.2.73 Add ability to get multiple hosts endpoint - 0.2.74 Remove trailing slash in endpoinds - 0.2.75 Add daemonset_overrides_root util - 0.2.76 update tookit to support fqdn alias - 0.2.77 Add recommended kubernetes name label to pods definition - 0.2.78 Fix db-init and db-drop scripts to make them work with sqlalchemy >2.0 - 0.2.79 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/horizon-172a4ff3264fc495.yaml ================================================ --- fixes: - | Fix missing job annotation support from values.yaml on the db-sync job. ... ================================================ FILE: releasenotes/notes/horizon.yaml ================================================ --- horizon: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 To avoid wrong version check for mysqlclient - 0.1.3 Modify Password validator related settings in Horizon - 0.1.4 Change Issuer to ClusterIssuer - 0.1.5 Revert - Change Issuer to ClusterIssuer - 0.1.6 Change Issuer to ClusterIssuer - 0.1.7 Update glance default policy values - 0.1.8 Implement "CSRF_COOKIE_HTTPONLY" option support in horizon - 0.2.0 Remove support for releases before T - 0.2.1 Make python script PEP8 compliant - 0.2.2 Use policies in yaml format - 0.2.3 Add openstack_enable_password_retrieve variable in value - 0.2.4 Fix OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT value - 0.2.5 Add Ussuri release support - 0.2.6 Add Victoria and Wallaby releases support - 0.2.7 Fix OPENSTACK_ENABLE_PASSWORD_RETRIEVE value - 0.2.8 Add default polices - 0.2.9 Removed default policy in chart in favor of default policy in code - 0.2.10 Helm 3 - Fix Job Labels - 0.2.11 Update htk requirements repo - 0.2.12 Support both json and yaml RBAC Policy Format - 0.2.13 Add container infra api version in values - 0.2.14 Add OPENSTACK_ENDPOINT_TYPE value - 0.2.15 Add local_settings.d - 0.2.16 Fix container-infra value - 0.2.17 Add custom logo - 0.2.18 Enable taint toleration for Openstack services - 0.2.19 Remove unsupported value overrides - 0.2.20 Add SHOW_OPENRC_FILE value - 0.2.21 Add helm hook annotations in db-sync and db-init jobs - 0.2.22 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.23 Add Xena and Yoga value overrides - 0.2.24 Remove blank lines in logo configmap - 0.2.25 Added OCI registry authentication - 0.2.26 Support SSL identity endpoint - 0.3.0 Remove support for Train and Ussuri - 0.3.1 Fix container infra api version in values - 0.3.2 Update mysql client version to 1.4.0 - 0.3.3 Update mysql client version in django.wsgi also - 0.3.4 Add readiness probe timeout - 0.3.5 Replace node-role.kubernetes.io/master with control-plane - 0.3.6 Fix container infra api version parsing - 0.3.7 Update the script to add extra panels - 0.3.8 Fix horizon tolerations - 0.3.9 Add Zed overrides - 0.3.10 Add 2023.1 overrides - 0.3.11 Rollout when logo configmap is changed - 0.3.12 Add Ubuntu Jammy overrides - 0.3.13 Make selenium v4 syntax optional - 0.3.14 Add 2023.2 Ubuntu Jammy overrides - 0.3.15 Update osh-selenium image used by default - 0.3.16 Add support for custom panels - 0.3.17 Set ingress annotation proxy-body-size=300m by default - 0.3.18 Enable custom annotations for Openstack pods - 0.3.19 Add 2024.1 overrides - 0.3.20 Enable custom annotations for Openstack secrets - 0.3.21 Update images used by default - 0.3.22 Align with 2024.1 requirements - 0.3.23 Use global wsgi subinterpreter - 0.3.24 Use base64 values for custom logo - 0.3.25 Implement "CSRF_TRUSTED_ORIGINS" option support in horizon - 0.3.26 Fix templating of CSRF_TRUSTED_ORIGINS - 0.3.27 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.28 Add WEBSSO_KEYSTONE_URL value - 0.3.29 Add 2024.2 Ubuntu Jammy overrides - 0.3.30 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/increase-default-logging-31db0e9d3e51b429.yaml ================================================ --- other: - | The logging for barbican, cinder, congress, glance, heat, ironic, keystone, magnum, mistral, neutron, nova, and senlin has been increased to log all warnings (and above) to stdout by default. ... ================================================ FILE: releasenotes/notes/ingress.yaml ================================================ --- ingress: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update to container image repo k8s.gcr.io - 0.2.0 Update default Kubernetes API for use with Helm v3 - 0.2.1 Use HostToContainer mountPropagation - 0.2.2 Use full image ref for docker official images - 0.2.3 Uplift ingress to 0.42.0 - 0.2.4 Update htk requirements - 0.2.5 Migrate Ingress resources to networking.k8s.io/v1 - 0.2.6 Add option to assign VIP as externalIP - 0.2.7 Enable taint toleration for Openstack services jobs - 0.2.8 Uplift ingress to 1.1.3 - 0.2.9 Added OCI registry authentication - 0.2.10 Update neutron images to xena release - 0.2.11 Fix resource name in the role - 0.2.12 Uplift ingress to 1.5.1 - 0.2.13 Allow setting node_port for the svc - 0.2.14 Replace node-role.kubernetes.io/master with control-plane - 0.2.15 Update kubernetes registry to registry.k8s.io - 0.2.16 Updated deprecated IngressClass annotation - 0.2.17 Fixed controller parameters - 0.2.18 Fixed some additional controller issues - 0.2.19 Uplift ingress controller image to 1.8.2 ... ================================================ FILE: releasenotes/notes/ironic-0035b6286b1c6333.yaml ================================================ --- ironic: - | Switched the Ironic API server from the built-in ironic-api command to uWSGI to improve concurrency handling and production readiness. A follow-up fix replaced the wsgi-file directive with the module directive because Ironic does not ship a wsgi_scripts entry point, which prevented the application from loading correctly under uWSGI. ... ================================================ FILE: releasenotes/notes/ironic-022571f573f6c430.yaml ================================================ --- ironic: - | Drop additional access that Ironic conductor no longer needs with the removal of the iSCSI deploy interface. This change went into effect with 2023.2. Remove host mount for /dev, /sys, and /var/run. Disable hostIPC by default. ... ================================================ FILE: releasenotes/notes/ironic-2b9283c8924f8c63.yaml ================================================ --- ironic: - | Set default config value for "database.max_retries" to "-1". ... ================================================ FILE: releasenotes/notes/ironic-2fcd7c5ae98b55f4.yaml ================================================ --- ironic: - | Drop the retrive-cleaning-network init container as it was only setting a deprecated option and the script it ran gave less feedback to the user than the built in check inside of Ironic. With the future of Ironic standalone networking this option will make even less sense so allow the default behavior of looking up the name in Ironic. ... ================================================ FILE: releasenotes/notes/ironic-4963b8bfe3c212d0.yaml ================================================ --- ironic: - | Add default TLS secret names like the other charts have. ... ================================================ FILE: releasenotes/notes/ironic-4a1d33f9e4147b79.yaml ================================================ --- ironic: - | Add missing ironic authentication config for `[nova]` and `[cinder]`. ... ================================================ FILE: releasenotes/notes/ironic-82bd78c64b57d2ce.yaml ================================================ --- ironic: - | Remove outdated default kolla images and use quay.io/airshipit/ironic:2025.1-ubuntu_noble ... ================================================ FILE: releasenotes/notes/ironic-adbba9c6718cc0d6.yaml ================================================ --- ironic: - | Add `ironic-dbsync online_data_migrations` to the ironic dbsync template per the ironic upgrade guide: https://docs.openstack.org/ironic/latest/admin/upgrade-guide.html ... ================================================ FILE: releasenotes/notes/ironic-c0de8abe9970dca0.yaml ================================================ --- ironic: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/ironic/ironic.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/ironic.yaml ================================================ --- ironic: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Added post-install and post-upgrade helm.sh/hook for jobs - 0.2.0 Remove support for releases before T - 0.2.1 Use policies in yaml format - 0.2.2 Update htk requirements repo - 0.2.3 Enable taint toleration for Openstack services - 0.2.4 Update defaults to W release - 0.2.5 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.6 Added OCI registry authentication - 0.2.7 Use HTTP probe instead of TCP probe - 0.2.8 Add helm3 hook supports to allow things like terraform deploys - 0.2.9 Replace node-role.kubernetes.io/master with control-plane - 0.2.10 Add standalone overrides - 0.2.11 Enable custom annotations for Openstack pods - 0.2.12 allow custom annotations on jobs - 0.2.13 Enable custom annotations for Openstack secrets - 0.2.14 Update images used by default - 0.2.15 Allow enabling/disabling of conductor http and pxe containers and overriding their init and runtime scripts - 0.2.16 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.17 Allow overriding of hostNetwork and hostIPC for Ironic conductor - 0.2.18 Use service tokens - 0.2.19 Allow extra containers for the conductor - 0.2.20 ensure tempdir is set to a reasonable default - 0.2.21 fix path to ironic.conf for 0.2.20's tempdir setting - 0.2.22 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/keystone-0e6674e1c443cd81.yaml ================================================ --- keystone: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/keystone/keystone.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/keystone-12efe8927d1a0934.yaml ================================================ --- keytone: - | Use Keytone API wsgi module directly instead of wsgi script which has been removed. ... ================================================ FILE: releasenotes/notes/keystone-17cdfeb53f6eb5dd.yaml ================================================ --- keystone: - | Remove endpoint-update.py from db-sync Job. The script was originally introduced in OSH to work around a limitation where `keystone-manage bootstrap` would not update endpoints once created. That limitation was resolved when upstream keystone added endpoint updates support to bootstrap. ... ================================================ FILE: releasenotes/notes/keystone-1aaec51f0512e445.yaml ================================================ --- keystone: - | Provide a WSGI script for Apache to use to start up Keystone since Keystone stopped shipping their own entrypoint. This is done in a way that users can override it and the container has less moving pieces at startup. ... ================================================ FILE: releasenotes/notes/keystone-56908951efdcc19e.yaml ================================================ --- keystone: - | Annotate credential and fernet keys secrets with the Helm keep policy. While helm does not clean up hook resources today, their documentation says that it is coming and users should annotate resources they do not expect to be deleted appropriately. Some GitOps tools like ArgoCD implement the cleanup today as part of their Helm support. ... ================================================ FILE: releasenotes/notes/keystone-5dd1eca70f3382d8.yaml ================================================ --- keystone: - | Ensure all errors go to the kubenertes logs and not to a file in the container. ... ================================================ FILE: releasenotes/notes/keystone-9bca09a40cc3dc68.yaml ================================================ --- fixes: - Fix the number of max active fernet keys ... ================================================ FILE: releasenotes/notes/keystone-dab27a4eeaab96d1.yaml ================================================ --- keystone: - | Use Keystone native wsgi script keystone/wsgi/api.py instead of the wsgi wrapper script provided by the keystone chart. ... ================================================ FILE: releasenotes/notes/keystone-e2d6c0f6c85415ab.yaml ================================================ --- keystone: - | Adds optional settings backoffLimit and activeDeadlineSeconds to the keystone bootstrap job. ... ================================================ FILE: releasenotes/notes/keystone-fb00add9c87916a3.yaml ================================================ --- keystone: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/keystone-healthcheck-1f72d266f886e735.yaml ================================================ --- keystone: - Use oslo.middleware healthcheck endpoint for liveness and readiness ... ================================================ FILE: releasenotes/notes/keystone.yaml ================================================ --- keystone: - 0.1.0 Initial Chart - 0.1.1 UPDATE - 0.1.2 UPDATE - 0.1.3 UPDATE - 0.1.4 UPDATE - 0.1.5 Revert clusterissuer change - 0.1.6 Fix typo in subPath entry - 0.1.7 Move rabbit-init to dynamic dependency - 0.1.8 Change Issuer to ClusterIssuer - 0.1.9 Add helm.sh/hook related annotations - 0.1.10 Update RBAC apiVersion from /v1beta1 to /v1 - 0.1.11 Remove congress residue - 0.1.12 Add helm hook conditional - 0.1.13 Fix Error - wrong number of args for set - 0.1.14 Remove setup helm hooks - 0.2.0 Remove support for releases before T - 0.2.1 Remove paste ini config settings - 0.2.2 Make python script PEP8 compliant - 0.2.3 Adding rabbitmq TLS logic - 0.2.4 Use policies in yaml format - 0.2.5 Mount rabbitmq TLS secret - 0.2.6 Modify default probe timings - 0.2.7 Add Ussuri release support - 0.2.8 Remove member bootstrap logic - 0.2.9 Add Victoria and Wallaby releases support - 0.2.10 Make internal TLS more robust - 0.2.11 Add missing slash - 0.2.12 Helm 3 - Fix Job Labels - 0.2.13 Helm 3 - Fix more Job Labels - 0.2.14 Update htk requirements repo - 0.2.15 Reduce log chattiness - 0.2.16 Remove extra fsGroup - 0.2.17 Update default image references - 0.2.18 Remove default policy - 0.2.19 Revert Reduce log chattiness - 0.2.20 Enable taint toleration for Openstack services - 0.2.21 Updated naming for subchart compatibility - 0.2.22 Remove older values overrides - 0.2.23 Remove usage of six - 0.2.24 Remove unused admin port in keystone - 0.2.25 Migrated CronJob resource to batch/v1 API version & PodDisruptionBudget to policy/v1 - 0.2.26 Add Xena and Yoga values overrides - 0.2.27 Use LOG.warning instead of deprecated LOG.warn - 0.2.28 Added OCI registry authentication - 0.2.29 Support TLS endpoints - 0.2.30 Distinguish between port number of internal endpoint and binding port number - 0.3.0 Remove support for Train and Ussuri - 0.3.1 Replace node-role.kubernetes.io/master with control-plane - 0.3.2 Add Zed overrides - 0.3.3 Add 2023.1 overrides - 0.3.4 Add Ubuntu Jammy overrides - 0.3.5 Add 2023.2 Ubuntu Jammy overrides - 0.3.6 Use region option in keystone endpoint-update.py - 0.3.7 Make keystone TLS configuration granular - 0.3.8 Enable custom annotations for Openstack pods - 0.3.9 Add 2024.1 overrides - 0.3.10 Allow custom annotations on jobs - 0.3.11 Fix custom annotations when helm3_hook is disabled - 0.3.12 Enable custom annotations for Openstack secrets - 0.3.13 Update images used by default - 0.3.14 Align db scripts with sqlalchemy 2.0 - 0.3.15 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.16 Align db scripts with Sqlalchemy 2 - 0.3.17 Add 2024.2 Ubuntu Jammy overrides - 0.3.18 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/kibana-053401293f7f508d.yaml ================================================ --- kibana: - Upgrade to v8.19.9, in sync with Elasticsearch ... ================================================ FILE: releasenotes/notes/kibana-add46185e9a8d6af.yaml ================================================ --- fixes: - | Fix retry logic to index creation script. Prevent creation of duplicate indexes. ... ================================================ FILE: releasenotes/notes/kibana-c0b39f760a7c5b80.yaml ================================================ --- kibana: - Upgrade to the latest v8.18.1, in sync with Elasticsearch ... ================================================ FILE: releasenotes/notes/kibana.yaml ================================================ --- kibana: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Drop usage of fsGroup inside container - 0.1.3 Enable TLS with Elasticsearch - 0.1.4 Enable TLS for Kibana ingress path - 0.1.5 Use full image ref for docker official images - 0.1.6 Remove Kibana indices before pod start up - 0.1.7 Helm 3 - Fix Job labels - 0.1.8 Update htk requirements - 0.1.9 Revert removing Kibana indices before pod start up - 0.1.10 Update image defaults - 0.1.11 Added OCI registry authentication - 0.1.12 Added feedback http_code 200 for kibana indexes - 0.1.13 Update Kibana to 8.9.0 - 0.1.14 Add 2023.1 Ubuntu Focal overrides - 0.1.15 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.16 Add 2024.1 Ubuntu Jammy overrides - 0.1.17 Update script to use data views replacing deprecated api - 0.1.18 Add retry logic to create_kibana_index_patterns.sh - 0.1.19 Add 2024.2 overrides - 0.1.20 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/kube-dns.yaml ================================================ --- kube-dns: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update to container image repo k8s.gcr.io - 0.1.3 Use full image ref for docker official images - 0.1.4 Update htk requirements - 0.1.5 Added OCI registry authentication - 0.1.6 Replace node-role.kubernetes.io/master with control-plane - 0.1.7 Update kubernetes registry to registry.k8s.io - 0.1.8 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.9 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/kubernetes-keystone-webhook.yaml ================================================ --- kubernetes-keystone-webhook: - 0.1.0 Initial Chart - 0.1.1 Update k8s-keystone-auth version - 0.1.2 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.3 Remove Kibana source reference - 0.1.4 Use full image ref for docker official images - 0.1.5 Update htk requirements - 0.1.6 Update default image value to Wallaby - 0.1.7 Added OCI registry authentication - 0.1.8 Add 2023.1 Ubuntu Focal overrides - 0.1.9 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.10 Add 2024.1 Ubuntu Jammy overrides - 0.1.11 Add 2024.2 overrides - 0.1.12 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/kubernetes-node-problem-detector.yaml ================================================ --- kubernetes-node-problem-detector: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Unpin images built with osh-images - 0.1.3 Update RBAC apiVersion from /v1beta1 to /v1 - 0.1.4 Update the systemd-monitor lookback duration - 0.1.5 Use full image ref for docker official images - 0.1.6 Update htk requirements - 0.1.7 Added OCI registry authentication - 0.1.8 Replace node-role.kubernetes.io/master with control-plane - 0.1.9 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.10 Update node_problem_detector to latest-ubuntu_jammy - 0.1.11 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/ldap-4737a2ba0a8a499f.yaml ================================================ --- ldap: - | Update openldap image to symas/openldap:2.6.8-debian-12 ... ================================================ FILE: releasenotes/notes/ldap.yaml ================================================ --- ldap: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Update htk requirements - 0.1.4 Added OCI registry authentication - 0.1.5 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.6 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/libvirt-5bf3185fc00a9938.yaml ================================================ --- features: - | Added ability to configure libvirt hooks. ... ================================================ FILE: releasenotes/notes/libvirt-85375c3ae369bc39.yaml ================================================ --- libvirt: - | Add .Values.libvirt.extraContainers hook to make it possible to add additional containers to libvirt daemonset, e.g. for monitoring purposes. Also move exporter container to values_overrides. ... ================================================ FILE: releasenotes/notes/libvirt-ac59444a6623ddb9.yaml ================================================ --- libvirt: - | Update Ceph to Tentacle 20.2.1 ... ================================================ FILE: releasenotes/notes/libvirt-b5dc605552feb278.yaml ================================================ --- libvirt: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/libvirt-e8ba1d91a8ca4999.yaml ================================================ --- fixes: - | Added readiness and liveness probes for the libvirt-exporter sidecar container. ... ================================================ FILE: releasenotes/notes/libvirt-f81d6fc0b0094209.yaml ================================================ --- libvirt: - | Keeping vnc ca/key/cert in /tmp so in case container (not pod) restarts it could copy them one again to the proper place. This allows to handle libvirt crashes properly without restarting libvirt pods. ... ================================================ FILE: releasenotes/notes/libvirt.yaml ================================================ --- libvirt: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Setup libvirt SSL - 0.1.3 Create override for external ceph cinder backend - 0.1.4 Set unix socket auth method as none - 0.1.5 Use full image ref for docker official images - 0.1.6 Enhancement to enable probes override from values.yaml - 0.1.7 Add libvirt overrides for Victoria and Wallaby - 0.1.8 Update htk requirements - 0.1.9 Exec libvirt instead of forking from bash - 0.1.10 Enable taint toleration for Openstack services jobs - 0.1.11 Remove unused overrides and update default image - 0.1.12 Add libvirt exporter as a sidecar - 0.1.13 Added OCI registry authentication - 0.1.14 Remove use of exec in libvirt.sh - 0.1.15 Add support for libvirt to connect to external ceph without any local ceph present - 0.1.16 Update all Ceph images to Focal - 0.1.17 Add ovn.yaml values_override, remove dependency from neutron-ovs-agent module - 0.1.18 Replace node-role.kubernetes.io/master with control-plane - 0.1.19 Set kubernetes cgroup value equal kubepods.slice to fit systemd cgroup driver - 0.1.20 Update Ceph to 17.2.6 - 0.1.21 Disable libvirt cgroup functionality for cgroup-v2 - 0.1.22 Set targeted dependency of libvirt with ovn networking backend - 0.1.23 Add support for enabling vencrypt - 0.1.24 Include HOSTNAME_FQDN for certificates - 0.1.25 Add 2023.2 Ubuntu Jammy overrides - 0.1.26 Update Rook to 1.12.5 and Ceph to 18.2.0 - 0.1.27 Add watch verb to vencrypt cert-manager Role - 0.1.28 Update Ceph images to Jammy and Reef 18.2.1 - 0.1.29 Update Ceph images to patched 18.2.2 and restore debian-reef repo - 0.1.30 Add 2024.1 overrides - 0.1.31 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.32 Enable a flag to parse Libvirt Nova metadata in libvirt exporter - 0.1.33 Handle cgroupv2 correctly - 0.1.34 Remove hugepages creation test - 0.1.35 Allow to initialize virtualization modules - 0.1.36 Allow to generate dynamic config options - 0.1.37 Make readiness probes more tiny - 0.1.38 Implement daemonset overrides for libvirt - 0.1.39 Add 2023.1 overrides for Ubuntu Focal and Jammy - 0.1.40 Add 2024.2 overrides - 0.1.41 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/local-storage.yaml ================================================ --- local-storage: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update htk requirements - 0.1.3 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/local-volume-provisioner.yaml ================================================ --- local-volume-provisioner: - 0.1.0 Initial Chart - 0.1.1 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/magnum.yaml ================================================ --- magnum: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Added post-install and post-upgrade helm hook for jobs - 0.2.0 Remove support for releases before T - 0.2.1 Use policies in yaml format - 0.2.2 Fix restarting of magnum-conductor pods - 0.2.3 Update htk requirements repo - 0.2.4 Mount empty temp_cache_dir for performance - 0.2.5 Update default image values to wallaby - 0.2.6 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.7 Added OCI registry authentication - 0.2.8 Remove default policy rules - 0.2.9 Define service_type in keystone_authtoken to support application credentials with access rules - 0.2.10 Uses uWSGI for API service - 0.2.11 Enable custom annotations for Openstack pods - 0.2.12 Enable custom annotations for Openstack secrets - 0.2.13 Update images used by default - 0.2.14 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.15 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/manila-23590e37667d10a5.yaml ================================================ --- manila: - | This change enhances the flexibility of the Manila Chart by introducing configurability for the CephFS backend. Previously, CephFS-related configuration values were statically defined within the manifests, limiting deployment customization. With this update, CephFS backend parameters can now be overridden via values. ... ================================================ FILE: releasenotes/notes/manila-3a767553950629bd.yaml ================================================ --- manila: - | Add support for the Ceph File System (CephFS) backend in the manila. ... ================================================ FILE: releasenotes/notes/manila-7bf5ad7472dbf691.yaml ================================================ --- manila: - Use more standard DB config setting ... ================================================ FILE: releasenotes/notes/manila-a5beeacdb577dd23.yaml ================================================ --- manila: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/manila/manila.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/manila-f7286f302a9372eb.yaml ================================================ --- manila: - | Fix Rally test pod template ... ================================================ FILE: releasenotes/notes/manila-f8ada2e675fcc308.yaml ================================================ --- manila: - | Use Manila API module for UWSGI configuration because WSGI script manila-wsgi has been removed. ... ================================================ FILE: releasenotes/notes/manila.yaml ================================================ --- manila: - 0.1.0 Initial Chart - 0.1.1 Define service_type in keystone_authtoken to support application credentials with access rules - 0.1.2 Add Zed overrides - 0.1.3 Add 2023.1 overrides - 0.1.4 Add Ubuntu Jammy overrides - 0.1.5 Update port name of service-api.yaml - 0.1.6 Add 2023.2 Ubuntu Jammy overrides - 0.1.7 Properly config network host for share service - 0.1.8 uses uWSGI for API service - 0.1.9 Enable custom annotations for Openstack pods - 0.1.10 Add 2024.1 overrides - 0.1.11 Enable custom annotations for Openstack secrets - 0.1.12 Update images used by default - 0.1.13 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.14 Add 2024.2 Ubuntu Jammy overrides - 0.1.15 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/mariadb-0cb94bb0ae8cf38a.yaml ================================================ --- fixes: - | Added failover openrc environment variables to database backup cron jobs. ... ================================================ FILE: releasenotes/notes/mariadb-2d75f250c1fbcd73.yaml ================================================ --- mariadb: - | The reboot.node annotation wasn't removed after the cluster init is done. This happened due to the fact that commit c2269d70a23b55c459233ab5fc28362b7c2ca766 removed necessary code lines for this and is absolutely needed. So, we are putting these changes back. ... ================================================ FILE: releasenotes/notes/mariadb-7d8282a6eeb4d249.yaml ================================================ --- mariadb: - | This change applies a fix to the StatefulSet template of the MariaDB chart, ensuring that the hash for the exporter secrets is correctly included. This is necessary for the proper functioning of the exporter component in the MariaDB deployment. ... ================================================ FILE: releasenotes/notes/mariadb-840fccbf8f0e9d39.yaml ================================================ --- # To create a new release note related to a specific chart: # reno new # # To create a new release note for a common change (when multiple charts # are changed): # reno new common mariadb: - | This change disables TLS for the Prometheus MySQL exporter sidecar container in the MariaDB StatefulSet. issues: - | mysql-exporter sidecar container has TLS enabled but was missing the CA certificate, which caused the exporter to fail to connect to the database. fixes: - | In order to fix this issue, the TLS configuration for the Prometheus MySQL exporter sidecar container has been updated to disable TLS. This allows the exporter to connect to the MariaDB database without requiring a CA certificate. ... ================================================ FILE: releasenotes/notes/mariadb-b923ac9345734125.yaml ================================================ --- mariadb: - | Updated to use MariaDB 11.4.8 built on Ubuntu 22.04 (Noble). fixes: - | Replaced deprecated mysql* binaries to their mariadb* equivalents in scripts. Also fixed TLS connection for myqsl-exporter side conainers. ... ================================================ FILE: releasenotes/notes/mariadb-backup-58c8a77f9c03bae8.yaml ================================================ --- fixes: - | Added failover openrc environment variables to database backup cron jobs. ... ================================================ FILE: releasenotes/notes/mariadb-backup-af891fea0cfa3db5.yaml ================================================ --- mariadb: - | - fixed backup_mariadb_sh script to correctly handle verification during the backup process ... ================================================ FILE: releasenotes/notes/mariadb-backup-c27eb2dc0a56a7ed.yaml ================================================ --- mariadb-backup: - Use quay.io/airshipit/mariadb:latest-ubuntu_noble images by default. ... ================================================ FILE: releasenotes/notes/mariadb-backup.yaml ================================================ --- mariadb-backup: - 0.0.1 Initial Chart - 0.0.2 Added staggered backups support - 0.0.3 Backups verification improvements - 0.0.4 Added throttling remote backups - 0.0.5 Add 2024.1 overrides - 0.0.6 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.0.7 Add 2024.2 overrides - 0.0.8 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/mariadb-cluster-4672d16769afdb47.yaml ================================================ --- mariadb-cluster: - Use quay.io/airshipit/mariadb:latest-ubuntu_noble images by default. ... ================================================ FILE: releasenotes/notes/mariadb-cluster.yaml ================================================ --- mariadb-cluster: - 0.0.1 Initial Chart - 0.0.2 Enable auto-upgrade - 0.0.3 Fixed TLS config and added x509 requirement - 0.0.4 Add 2024.1 overrides - 0.0.5 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.0.6 Add 2024.2 overrides - 0.0.7 Allow to use default storage class - 0.0.8 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/mariadb-dcd35d40fcd4a749.yaml ================================================ --- mariadb: - | - fixed backup_mariadb_sh script to correctly handle verification during the backup process ... ================================================ FILE: releasenotes/notes/mariadb.yaml ================================================ --- mariadb: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 mariadb security best practice fixes - 0.1.3 Fix MariaDB backup script - 0.1.4 Unpin images built with osh-images - 0.1.5 Update to container image repo k8s.gcr.io - 0.1.6 Change Issuer to ClusterIssuer - 0.1.7 Revert - Change Issuer to ClusterIssuer - 0.1.8 Change Issuer to ClusterIssuer with logic in place to support cert-manager versioning - 0.1.9 Uplift Mariadb-ingress to 0.42.0 - 0.1.10 Rename mariadb backup identities - 0.1.11 Disable mariadb mysql history client logging - 0.1.12 Set strict permission on mariadb data dir - 0.1.13 Fix race condition for grastate.dat - 0.1.14 Update mysqld-exporter image to v0.12.1 - 0.2.0 Uplift mariadb version and ubuntu release - 0.2.1 Prevent potential splitbrain issue if cluster is in reboot state - 0.2.2 remove deprecated svc annotation tolerate-unready-endpoints - 0.2.3 Remove panko residue - 0.2.4 Use full image ref for docker official images - 0.2.5 Added helm hook for post-install and post-upgrade in prometheus exporter job. - 0.2.6 Update log format stream for mariadb - 0.2.7 add ingress resources - 0.2.8 Helm 3 - Fix Job labels - 0.2.9 Update htk requirements - 0.2.10 Fix Python exceptions - 0.2.11 Enhance mariadb backup - 0.2.12 Remove set -x - 0.2.13 Adjust readiness.sh in single node and no replication case - 0.2.14 Fix comparison value - 0.2.15 Updated naming for subchart compatibility - 0.2.16 Revert naming for subchart compatibility - 0.2.17 Enable taint toleration for Openstack services jobs - 0.2.18 Updated naming for subchart compatibility - 0.2.19 Update default image value to Wallaby - 0.2.20 Migrated CronJob resource to batch/v1 API version & PodDisruptionBudget to policy/v1; Uplift Mariadb-ingress to 1.1.3 - 0.2.21 Fix mysql exporter user privileges - 0.2.22 Fix ingress cluster role privileges - 0.2.23 Fix backup script by ignoring sys database for MariaDB 10.6 compartibility - 0.2.24 Uplift Mariadb-ingress to 1.2.0 - 0.2.25 Add liveness probe to restart a pod that got stuck in a transfer wsrep_local_state_comment - 0.2.26 Added OCI registry authentication - 0.2.27 Fix broken helmrelease for helmv3 - 0.2.28 Added verify_databases_backup_in_directory function implementation - 0.2.29 Uplift Mariadb-ingress to 1.5.1 - 0.2.30 Replace node-role.kubernetes.io/master with control-plane - 0.2.31 Update kubernetes registry to registry.k8s.io - 0.2.32 Prevent liveness probe from killing pods during SST - 0.2.33 Add 2023.1 Ubuntu Focal overrides - 0.2.34 Uplift ingress controller image to 1.8.2 - 0.2.35 Update apparmor override - 0.2.36 Added staggered backups support - 0.2.37 Backups verification improvements - 0.2.38 Added throttling remote backups - 0.2.39 Template changes for image 1.9 compatibility - 0.2.40 Start.py allows to create mariadb-service-primary service and endpoint - 0.2.41 Switch to primary service instead of ingress by default - 0.2.42 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.43 Add 2024.1 Ubuntu Jammy overrides - 0.2.44 Uplift ingress controller image to 1.11.2 - 0.2.45 Add mariadb controller support - 0.2.46 Avoid using cluster endpoints - 0.2.47 Deploy exporter as sidecar - 0.2.48 Switch to mariadb controller deployment - 0.2.49 Remove ingress deployment - 0.2.50 Add cluster-wait job - 0.2.51 Add 2024.2 overrides - 0.2.52 Added SSL support to cluster-wait job - 0.2.53 Use constant for mysql binary name - 0.2.54 Improve leader election on cold start - 0.2.55 Improve python3 compatibility - 0.2.56 Stop running threads on sigkill - 0.2.57 Remove useless retries on conflicts during cm update - 0.2.58 Prevent TypeError in get_active_endpoint function - 0.2.59 Give more time on resolving configmap update conflicts - 0.2.60 Refactor liveness/readiness probes - 0.2.61 Avoid using deprecated isAlive() - 0.2.62 Implement mariadb upgrade during start - 0.2.63 Use service ip for endpoint discovery - 0.2.64 Add terminationGracePeriodSeconds - 0.2.65 Allow to use default storage class - 0.2.66 Add probes for exporter - 0.2.67 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/masakari-ea8acf2427bc9811.yaml ================================================ --- masakari: - | Add instance introspection to the Masakari chart features: - | Added Instance Introspection monitor the Openstack Helm Masakari project to provide vm HA by automatically detecting the system-level failure events via QEMU Guest Agent. If it detects VM heartbeat failure events, it sends notifications to the masakari-api. ... ================================================ FILE: releasenotes/notes/masakari.yaml ================================================ --- masakari: - 0.1.0 Initial Chart - 0.1.1 Seperate node labels for monitors - 0.1.2 Added halm hook and fix for hostmonitors to support pacemaker remote - 0.1.3 Mount sudoers file for masakari hostmonitors - 0.1.4 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.1.5 Added OCI registry authentication - 0.1.6 Use HTTP probe instead of TCP probe - 0.1.7 Define service_type in keystone_authtoken to support application credentials with access rules - 0.1.8 Add helm hook to jobs-rabbitmq-init - 0.1.9 Enable custom annotations for Openstack pods - 0.1.10 Enable custom annotations for Openstack secrets - 0.1.11 Move api_paste_config value to wsgi - 0.1.12 Update images used by default - 0.1.13 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.14 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/memcached-1ae10613b2e36813.yaml ================================================ --- memcached: - | Add .Values.memcached.extraContainers hook to make it possible to add extra containers to memcached statefulset, e.g. for monitoring purposes. Also move the exporter sidecar to values_overrides. ... ================================================ FILE: releasenotes/notes/memcached.yaml ================================================ --- memcached: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Make stats cachedump configurable. - 0.1.3 Remove panko residue - 0.1.4 Use full image ref for docker official images - 0.1.5 Update htk requirements - 0.1.6 Switch to using sidecar for exporter - 0.1.7 Updated naming for subchart compatibility - 0.1.8 Enable taint toleration for Openstack services jobs - 0.1.9 Revert naming for subchart compatibility - 0.1.10 Updated naming for subchart compatibility - 0.1.11 Remove gnocchi netpol override - 0.1.12 Added OCI registry authentication - 0.1.13 Replace node-role.kubernetes.io/master with control-plane - 0.1.14 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.15 Allow to pass additional service parameters - 0.1.16 Change deployment type to statefulset - 0.1.17 Fix statefulset spec format - 0.1.18 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/mistral.yaml ================================================ --- mistral: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Added post-install and post-upgrade hook for Jobs - 0.2.0 Remove support for releases before T - 0.2.1 Use policies in yaml format - 0.2.2 Update htk requirements repo - 0.2.3 Update default imaage values to Wallaby - 0.2.4 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.5 Added OCI registry authentication - 0.2.6 Use HTTP probe instead of TCP probe - 0.2.7 Remove default policy rules - 0.2.8 Enable custom annotations for Openstack pods - 0.2.9 Enable custom annotations for Openstack secrets - 0.2.10 Update images used by default - 0.2.11 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.12 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/nagios-36a6b2cb6e9fc720.yaml ================================================ --- nagios: - | Use the quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image by default for init containers ... ================================================ FILE: releasenotes/notes/nagios.yaml ================================================ --- nagios: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Mount internal TLS CA certificate - 0.1.4 Update htk requirements - 0.1.5 Switch nagios image from xenial to bionic - 0.1.6 Added OCI registry authentication - 0.1.7 Upgrade osh-selenium image to latest-ubuntu_focal - 0.1.8 Use helm toolkit for readiness probes - 0.1.9 Make using selenium v4 syntax optional - 0.1.10 Correct selenium v3 syntax - 0.1.11 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.12 Update nagios image tag to latest-ubuntu_jammy - 0.1.13 Add the ability to use custom Nagios plugins - 0.1.14 Upgrade osh-selenium image to ubuntu_jammy - 0.1.15 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/namespace-config.yaml ================================================ --- namespace-config: - 0.1.0 Initial Chart - 0.1.1 Grant access to existing PodSecurityPolicy - 0.1.2 Rmove PodSecurityPolicy - 0.1.3 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/neutron-00a56405067b123d.yaml ================================================ --- neutron: - | Fix issue with etcSources where resources fails to apply if the list is empty. ... ================================================ FILE: releasenotes/notes/neutron-013c9be46456b92c.yaml ================================================ --- neutron: - | Fix neutron ironic agent fail to start with missing host information. ... ================================================ FILE: releasenotes/notes/neutron-288ac8b37720832e.yaml ================================================ --- neutron: - | Use psutil.net_connections to iterate over tcp connections during health check. The psutil.connections is still available but deprecated. - | Do not skip children processes when counting established connections because after eventlet removal plain threads are used. ... ================================================ FILE: releasenotes/notes/neutron-2af36e49a0a377c3.yaml ================================================ --- # To create a new release note related to a specific chart: # reno new # # To create a new release note for a common change (when multiple charts # are changed): # reno new common neutron: - | Use `ip add replace` instead of `ip addr add` in the init script to make it idempotent and avoid errors when the script tries to assign the same IP address to the interface on subsequent runs. ... ================================================ FILE: releasenotes/notes/neutron-2bb975307f0d27f2.yaml ================================================ --- neutron: - | Added the ability to configure custom OVN Northbound (ovn_nb_connection) and Southbound (ovn_sb_connection) connection strings (e.g., for deployments using Kube-OVN or external OVN databases). By default, the chart continues to use the in-cluster service environment This change provides flexibility to support both default in-cluster OVN and custom/external OVN backends seamlessly. ... ================================================ FILE: releasenotes/notes/neutron-2d4db97bc8900286.yaml ================================================ --- neutron: - | Create multiple Keystone service accounts to access to other Openstack APIs ... ================================================ FILE: releasenotes/notes/neutron-315f825e54d3f34c.yaml ================================================ --- neutron: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/neutron/neutron.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. Ensure that the neutron chart always loads config overrides from /etc/neutron/neutron.conf.d ... ================================================ FILE: releasenotes/notes/neutron-32815761690bedf5.yaml ================================================ --- neutron: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/neutron-3c11cf48f8c7c592.yaml ================================================ --- neutron: - | add raise_for_status method call to the livenessProbe command to properly raise an error when return code is 4xx (client error) or 5xx (server error) ... ================================================ FILE: releasenotes/notes/neutron-3c33aea435f7ab8a.yaml ================================================ --- # To create a new release note related to a specific chart: # reno new # # To create a new release note for a common change (when multiple charts # are changed): # reno new common neutron: - | Neutron OVN now runs under **uWSGI**, and the legacy **eventlet** support has been removed. The ``neutron-server`` binary is no longer provided. Updated configuration references to reflect the switch to uWSGI for Neutron OVN. ... ================================================ FILE: releasenotes/notes/neutron-42b77d74ce8fe287.yaml ================================================ --- neutron: - | Update values_overrides for ovn. If OVN is used, network.backend needs to be ovn. There is no need to keep openvswitch as it adds OVS plugin related pod dependencies. daemonset_netns_cleanup_cron is also not required anymore with ovn. ... ================================================ FILE: releasenotes/notes/neutron-4f9263300df02c9b.yaml ================================================ --- neutron: - | Add missing `--config-dir` option to `neutron-ovn-db-sync-util`. ... ================================================ FILE: releasenotes/notes/neutron-659f0c21af1feaa0.yaml ================================================ --- fixes: - | Since 0e7fe77f49 neutron-ironic-agent has had an invalid volumes spec. Fix the spec so the agent can run. ... ================================================ FILE: releasenotes/notes/neutron-670d4cd96f100dea.yaml ================================================ --- features: - | Split out the OpenStack service account definitions from neutron.conf and into config snippets which are loaded at /etc/neutron/neutron.d/, which is automatically loaded by OSLO when loading the main neutron.conf. This makes it easier for users to use the regular config generation while supplying credentials out of band. ... ================================================ FILE: releasenotes/notes/neutron-96d95ffbdeaaf29a.yaml ================================================ --- neutron: - | Add required OVN VPN configuration files to Neutron server so VPN features behave as expected. The Neutron server receives RPC calls from the Neutron OVN VPN agent and executes VPN operations. Therefore, the VPN configuration must be present on the Neutron server. ... ================================================ FILE: releasenotes/notes/neutron-9dbb4250fd893743.yaml ================================================ --- neutron: - | Fix ovn sync db cron job to use helm-toolkit snippets when specifying runtime and priority classes. ... ================================================ FILE: releasenotes/notes/neutron-add-uwsgi-start-time-d73ba462e1157dd2.yaml ================================================ --- neutron: - | Added uwsgi start-time configuration to neutron-api-uwsgi section. The start-time parameter is set to "%t" (unix time at instance startup) and is used by ML2/OVN for creating OVN hash ring registers per worker. This configuration is mandatory for proper ML2/OVN operation. See the Neutron documentation for more details: https://docs.openstack.org/neutron/latest/admin/config-wsgi.html ... ================================================ FILE: releasenotes/notes/neutron-b2247f89a5f258aa.yaml ================================================ --- # To create a new release note related to a specific chart: # reno new # # To create a new release note for a common change (when multiple charts # are changed): # reno new common neutron: - | Add interface name parameter for DPDK configs ... ================================================ FILE: releasenotes/notes/neutron-b225c11a5e1d522d.yaml ================================================ --- neutron: - | Fix OVN support in neutron DHCP. ... ================================================ FILE: releasenotes/notes/neutron-c0c7ca4e49cbf03c.yaml ================================================ --- neutron: - | Fix port duplication in neutron server deployment ... ================================================ FILE: releasenotes/notes/neutron-c451a4129f97e891.yaml ================================================ --- fixes: - | Fixed OVN metadata agent DaemonSet resource configuration inconsistency. All containers now consistently reference pod.resources.agent.ovn_metadata. ... ================================================ FILE: releasenotes/notes/neutron-d39cc4643edac73c.yaml ================================================ --- neutron: - | Support for tungstenfabric has been removed. ... ================================================ FILE: releasenotes/notes/neutron-f0674e08d80fc203.yaml ================================================ --- neutron: - | Add new cron job for neutron ovn db sync that runs evey 5 mins by default. This could be use as log alert if any part out of sync. Or it can be use as automatic repair method to prevent OVN DB got modified and failed it's purpose. This cron job is default disabled. Set `.Values.manifests.cron_job_ovn_db_sync_repair` to `true` to enable the cronjob. The sync mode for the cronjob is default only for check sync status. Set `.Values.jobs.ovn_db_sync_repair.sync_mode` to `repair` for enable automatic repair and sync OVN DB from Neutron DB. ... ================================================ FILE: releasenotes/notes/neutron-fca28403d7a0be3a.yaml ================================================ --- neutron: - | When enabling the OVN backend, don't fail to start with the default connection setup to OVN NB and SB. A feature change was made allowing users to override these connections but it did not preserve the default. ... ================================================ FILE: releasenotes/notes/neutron.yaml ================================================ --- neutron: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 fixes tls issue - 0.1.3 Update neutron to use Nginx apparmor profile - 0.1.4 Pass ovs agent config to dhcp agent - 0.1.5 Add missing flags to nginx container in neutron chart - 0.1.6 Use HostToContainer mountPropagation - 0.1.7 Change Issuer to ClusterIssuer - 0.1.8 Revert Change Issuer to ClusterIssuer - 0.1.9 Update ovs agent to support host/label overrides - 0.1.10 Change Issuer to ClusterIssuer - 0.1.11 Added the helm.sh/hook, helm.sh/hook-weight annotations - 0.1.12 Removed "name" parameter from Rally tests - 0.2.0 Remove support for releases before T - 0.2.1 Adding rabbitmq TLS logic - 0.2.2 Use policies in yaml format - 0.2.3 Mount rabbitmq TLS secret - 0.2.4 Add Ussuri release support - 0.2.5 Use rootwrap daemon - 0.2.6 Fix neutron agent-init script - 0.2.7 Made dnsmasq.conf overridable in configmap-bin - 0.2.8 Add Victoria and Wallaby releases support - 0.2.9 Add option to disable helm.sh/hook annotations - 0.2.10 Update htk requirements repo - 0.2.11 Improve health probe logging - 0.2.12 Fix infinite recursion deadlock on netns cleanup cron - 0.2.13 Enable taint toleration for Openstack services - 0.2.14 Migrate IP from bridge for auto_bridge_add - 0.2.15 Remove unsupported values overrides - 0.2.16 Remove usage of six - 0.2.17 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.18 Updated naming for subchart compatibility - 0.2.19 Added qdhcp NS host validation for deleting wrong namespaces. - 0.2.20 Add Xena and Yoga values overrides - 0.2.21 Fix for qdhcp NS host validation for deleting wrong namespaces. - 0.2.22 Fix /run/xtables.lock may be a directory - 0.2.23 Add neutron_netns_cleanup_cron release image override, so that the respective release image is used - 0.2.24 Added OCI registry authentication - 0.2.25 Support TLS endpoints - 0.2.26 Use HTTP probe instead of TCP probe - 0.2.27 Distinguish between port number of internal endpoint and binding port number - 0.3.0 Remove support for Train and Ussuri - 0.3.1 Remove default policy rules - 0.3.2 Use correct labels for ovs which uses one daemonset for ovs-db and ovs-vswitchd - 0.3.3 Add OVN Support - 0.3.4 Replace node-role.kubernetes.io/master with control-plane - 0.3.5 Fix health probe for OVN metadata agent - 0.3.6 Fix the issue that ovn metadata not work in muti-node enviroment - 0.3.7 Sync neutron db to ovn nb db when neutron-server start - 0.3.8 Define service_type in keystone_authtoken to support application credentials with access rules - 0.3.9 Extend neutron liveness probe with readiness probe - 0.3.10 Configure keystone authentication credentials for placement - 0.3.11 Add Zed overrides - 0.3.12 Update oslo_messaging_RPCClient and get_rpc_transport - 0.3.13 Remove duplicated argument when running a liveness check - 0.3.14 Add 2023.1 overrides - 0.3.15 Add asap2 support - 0.3.16 Use service tokens - 0.3.17 Add exec probe timeouts - 0.3.18 Improve OVN support - 0.3.19 Fix getting IP for interface when there are multiple IPs assigned - 0.3.20 Add Ubuntu Jammy overrides - 0.3.21 Run native netns cleanup - 0.3.22 Add BGP Dragent support for running dragent agents as daemonsets - 0.3.23 Fix start function template - 0.3.24 Add 2023.2 Ubuntu Jammy overrides - 0.3.25 Fix ovs member support for readiness - 0.3.26 Fix ovs options to allow multiple options - 0.3.27 Move old overrides from the tools directory - 0.3.28 Fix ovn for slow enviroment - 0.3.29 Disable DVR for OVN floating ip - 0.3.30 Fix designate auth url - 0.3.31 FIX ovn-metadata-agent mountPropagation overrides by parent directory - 0.3.32 Update dpdk override - 0.3.33 Make sure trust on command is applied to avoid race-condition with ovs-dpdk - 0.3.34 Update metadata endpoint - 0.3.35 Do not attach non-existing interfaces to br-ex bridge for OVS agent - 0.3.36 Enable custom annotations for Openstack pods - 0.3.37 Proper chown /run/openvswitch/db.sock under OVN - 0.3.38 Add 2024.1 overrides - 0.3.39 Ensure that the script handles cases where the PID file exists but is empty or does not contain the expected data structure. - 0.3.40 Fix ovs bridge creation in mappings for DPDK - 0.3.41 Enable custom annotations for Openstack secrets - 0.3.42 Update images used by default - 0.3.43 Switch neutron to uWSGI - 0.3.44 Add OVN VPNaas support - 0.3.45 Fix ironic/baremetal authentication - 0.3.46 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.47 Add service role to the Neutron user - 0.3.48 Add 2024.2 Ubuntu Jammy overrides - 0.3.49 Add node_selector_* for OVN VPN agent - 0.3.50 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/nfs-provisioner.yaml ================================================ --- nfs-provisioner: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Update htk requirements - 0.1.4 Added OCI registry authentication - 0.1.5 Update image version - 0.1.6 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.7 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/nova-1a7fb130b261f92d.yaml ================================================ --- nova: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/nova-29572c7b62b6ae0b.yaml ================================================ --- nova: - Fix Cinder auth config in values.yaml ... ================================================ FILE: releasenotes/notes/nova-2c10ffbcf8d2f838.yaml ================================================ --- nova: - | Support for tungstenfabric has been removed. ... ================================================ FILE: releasenotes/notes/nova-2e97a6de46b4c9b9.yaml ================================================ --- upgrade: - | Change the default volume v3 path to not include the tenant_id. The is the current recommended approach and has not been necessary since the Yoga release. ... ================================================ FILE: releasenotes/notes/nova-3493b35ba8c4479a.yaml ================================================ --- nova: - | Update values_overrides for ovn. If OVN is used, network.backend needs to be ovn. There is no need to keep openvswitch as it adds OVS plugin related pod dependencies. ... ================================================ FILE: releasenotes/notes/nova-366b14dea33d416d.yaml ================================================ --- aodh: - | Remove outdated default kolla images and use quay.io/airshipit/aodh:2025.1-ubuntu_noble ... ================================================ FILE: releasenotes/notes/nova-467e6c34e9fd1b05.yaml ================================================ --- nova: - | Fix issue with etcSources where resources fails to apply if the list is empty. ... ================================================ FILE: releasenotes/notes/nova-476f40003a31bc77.yaml ================================================ --- features: - | Split out the OpenStack service account definitions from nova.conf and into config snippets which are loaded at /etc/nova/nova.d/, which is automatically loaded by OSLO when loading the main nova.conf. This makes it easier for users to use the regular config generation while supplying credentials out of band. ... ================================================ FILE: releasenotes/notes/nova-495c648112a2b539.yaml ================================================ --- nova: - | Fix mount path /etc/nova/nova.conf.d for novncproxy deployment ... ================================================ FILE: releasenotes/notes/nova-4b998ef222e57fd1.yaml ================================================ --- nova: - | Remove `memcache_servers` and `memcache_secret_key` from `[ironic]` section. It was found that nothing consumes those configurations. ... ================================================ FILE: releasenotes/notes/nova-5bb93c130c2a280d.yaml ================================================ --- nova: - | Update the wait computes default bootstrap script. Now it is going to print timestamps while waiting for the computes to be ready. This is going to be handy during debugging. Also the typo has been fixed that prevented the script to fail after timeout. - | Update dependencies for the bootstrap job. It must start after cell setup job is finished because it looks up for hypervisors which are discovered by the cell setup job. ... ================================================ FILE: releasenotes/notes/nova-5d7903f3b97aa088.yaml ================================================ --- nova: - | Includes custom job annotations for nova-bootstrap chart. Other jobs include the custom job annotations, but they were missing for the nova-bootstrap job. ... ================================================ FILE: releasenotes/notes/nova-60c926ac61319ba1.yaml ================================================ --- nova: - | Add ability to disable nova-ssh Secret with `.manifests.secret_ssh`. upgrade: - | The `.manifests.configmap_etc` value no longer control the nova-ssh Secret, use `.manifests.secret_ssh` instead. ... ================================================ FILE: releasenotes/notes/nova-69cb1a01b6f5c561.yaml ================================================ --- nova: - | Allows users to set custom 'host' values for nova conductor and scheduler services. This may be useful for kubernetes users, where new deploys of scheduler and conductor use the pod names, leaaving stale compute service entries which are eventually cleaned by the nova-service-cleaner job. Ref: https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.host ... ================================================ FILE: releasenotes/notes/nova-6b1d99fb5c67b2dd.yaml ================================================ --- nova: - | health-probe.py now supports reading database connections from /etc/nova/nova.conf.d. ... ================================================ FILE: releasenotes/notes/nova-7f3dbce1333752b8.yaml ================================================ --- nova: - | Ensure that the nova chart always loads config overrides from /etc/nova/nova.conf.d ... ================================================ FILE: releasenotes/notes/nova-9df2dfa1e3521305.yaml ================================================ --- nova: - | The ironic Keystone user for Nova will not be created anymore unless `manifests.statefulset_compute_ironic` is set to True. ... ================================================ FILE: releasenotes/notes/nova-b0749b6144e2b871.yaml ================================================ --- nova: - Add custom annotations to the nova-cell-setup job ... ================================================ FILE: releasenotes/notes/nova-b2ce6bcc83029d1b.yaml ================================================ --- nova: - | Refactored the flavor creation logic in the nova bootstrap script to simplify and generalize flavor definitions using dynamic key/value iteration. This makes the chart more maintainable and flexible for various flavor configurations. ... ================================================ FILE: releasenotes/notes/nova-c59fc7469b3a8500.yaml ================================================ --- nova: - Add serialproxy support ... ================================================ FILE: releasenotes/notes/nova-dd4188dbc489977c.yaml ================================================ --- upgrade: - | Change the default volume v2.1 path to not include the tenant_id. The is the current recommended approach and has not been necessary since the Mitaka release. ... ================================================ FILE: releasenotes/notes/nova-e42deac3199480e6.yaml ================================================ --- nova: - | Add missing nova-etc-snippets for cell-setup cronjob. ... ================================================ FILE: releasenotes/notes/nova-e8350419e59bc440.yaml ================================================ --- nova: - Adds support to UUID deployment-provisioning configuration ... ================================================ FILE: releasenotes/notes/nova-fc00bda9bb69988e.yaml ================================================ --- nova: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/nova/nova.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/nova.yaml ================================================ --- nova: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Add ssh to Nova compute - 0.1.3 Establish Nova and Placement dependencies - 0.1.4 Remove deprecated os_region_name for placement - 0.1.5 Enable hostIPC - 0.1.6 Swap SSH key names to reflect the correct key - 0.1.7 Use HostToContainer mountPropagation - 0.1.8 Change Issuer to ClusterIssuer - 0.1.9 Revert "Change Issuer to ClusterIssuer" - 0.1.10 Use HostToContainer mount propagation - 0.1.11 Secure libvirt connection from using 127.0.0.1 to use unix socket - 0.1.12 Update RBAC apiVersion from /v1beta1 to /v1 - 0.1.13 Change Issuer to ClusterIssuer - 0.1.14 BUG for deploying multiple compute nodes - 0.1.15 Mount /dev/pts in Nova compute container - 0.1.16 Use first IP address for migration - 0.1.17 Add multipathd support for ISCSI backed volume VMs - 0.1.18 Fix the nova-compute-ironic label issue - 0.1.19 Host resource scale adjustment about ironic - 0.2.0 Remove support for releases before T - 0.2.1 Remove unnecessary +x permission on gotpl files - 0.2.2 Adding rabbitmq TLS logic - 0.2.3 Replace deprecated configuration ``[vnc]/vncserver_proxyclient_address`` - 0.2.4 Mount rabbitmq TLS secret - 0.2.5 Set reasonable default probe timeouts - 0.2.6 Added cronJob with script for archive deleted rows which cleanup databases - 0.2.7 Add Ussuri release support - 0.2.8 Fix the cron archive_deleted_rows bash script for before and max-rows values - 0.2.9 Add image clean up to rally test - 0.2.10 Add tls cert mounting to nova-novnc - 0.2.11 Add Victoria and Wallaby releases support - 0.2.12 Bootstrap flavor creation efficiencies - 0.2.13 Add missing 'runlock' hostMount when enable_scsi - 0.2.14 Use helm.sh/hook annotations for jobs - 0.2.15 Fix archive-deleted-rows for enabling date command as value for before option - 0.2.16 Remove the policy document in values file - 0.2.17 Fix disablement of helm.sh/hook for Helm v2 - 0.2.18 Give service time to restore - 0.2.19 Define service cleaner sleep time - 0.2.20 Update script to true of grep does get anything. - 0.2.21 Helm 3 - Fix Job Labels - 0.2.22 Update htk requirements repo - 0.2.23 Add option to enable extra wait for cell-setup-init - 0.2.24 Fix nova-bootstrap job labels - 0.2.25 Add check for compute nodes - 0.2.26 Fix _ssh-init.sh.tpl to copy the ssh keys to the user on the security context - 0.2.27 Add tls1.2 minimum version to tls overrides - 0.2.28 Move ssl_minimum_version to console section - 0.2.29 Remove ssh-config - 0.2.30 Improve health probe logging - 0.2.31 Update oslo messaging get_transport - 0.2.32 Host of ironic compute service equals pod name - 0.2.33 Cleanup old releases - 0.2.34 Remove consoleauth in nova - 0.2.35 Enable taint toleration for Openstack services - 0.2.36 Support TLS endpoints - 0.2.37 Remove nova-placement - 0.2.38 Update nova image defaults - 0.2.39 Migrated CronJob resource to batch/v1 API version & PodDisruptionBudget to policy/v1 - 0.2.40 Updated naming for subchart compatibility - 0.2.41 Add Xena and Yoga values overrides - 0.2.42 Add missing configuration ``[vnc]/novncproxy_host`` - 0.2.43 Added OCI registry authentication - 0.2.44 Distinguish between port number of internal endpoint and binding port number - 0.2.45 Support TLS endpoints for metadata-api - 0.2.46 Use HTTP probe instead of TCP probe - 0.2.47 Remove list agents rally test - 0.3.0 Remove support for Train and Ussuri - 0.3.1 Added backoffLimit for bootstrap job - 0.3.2 Remove un-used configs for Nova - 0.3.3 Update all Ceph images to Focal - 0.3.4 Add OVN values_override, disable dependency to ovn-agent and vif configs for ovn - 0.3.5 Replace node-role.kubernetes.io/master with control-plane - 0.3.6 Fix VNC access issues - 0.3.7 Fix live migration without DNS resolution - 0.3.8 Fix missing privilege separation directory for nova compute ssh - 0.3.9 Fix typo in spice proxy deployment - 0.3.10 Define service_type in keystone_authtoken to support application credentials with access rules - 0.3.11 Update get_notification_transport - 0.3.12 Update oslo_messaging_RPCClient - 0.3.13 Add Zed overrides - 0.3.14 Add 2023.1 overrides - 0.3.15 Ensure that the health check script handles cases where the PID file exists but is empty or does not contain the expected data structure. - 0.3.16 Use service tokens - 0.3.17 Set targeted dependency of nova-compute with ovn networking backend - 0.3.18 Fix nova ssh keys permission - 0.3.19 Add support for enabling vencrypt - 0.3.20 Add cinder auth config - 0.3.21 Update health probe script considering ovsdb_connection config - 0.3.22 Replace deprecated configuration vncserver_proxyclient_address to server_proxyclient_address - 0.3.23 Add Ubuntu Jammy overrides - 0.3.24 Create a certificate for novnc vencrypt separately - 0.3.25 Add IP addresses search control flag - 0.3.26 Improve cinder authentication support - 0.3.27 Add 2023.2 Ubuntu Jammy overrides - 0.3.28 Add ability to define extra command(s) for the nova cell setup job - 0.3.29 Add ability to define extra command(s) for the nova service cleaner job - 0.3.30 Add the conditional statement for log_config_append - 0.3.31 Add getting LISTEN IP for CIDR - 0.3.32 Set the startupProbe for nova-compute - 0.3.33 Add job to create 'vms' pool - 0.3.34 Add public endpoints for the spiceproxy - 0.3.35 Use directory mount for vencrypt certificates - 0.3.36 Update Ceph images to Jammy and Reef 18.2.1 - 0.3.37 Use metadata_listen_port instead of metadata_port - 0.3.38 Using uWSGI - 0.3.39 Enable custom annotations for Openstack pods - 0.3.40 Add 2024.1 overrides - 0.3.41 Enable custom annotations for Openstack secrets - 0.3.42 Update images used by default - 0.3.43 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.44 Add DPDK overrides - 0.3.45 Add configuration for nova-scheduler - 0.3.46 Add 2024.2 Ubuntu Jammy overrides - 0.3.47 Use nova-compute.conf in nova-compute-ironic - 0.3.48 Fix typo in archive_deleted_rows script - 0.3.49 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/octavia-171c56de7891c86d.yaml ================================================ --- octavia: - | Directly use module for Octavia API UWSGI as WSGI script octavia-wsgi has removed from Octavia. ... ================================================ FILE: releasenotes/notes/octavia-3c13346818a743cc.yaml ================================================ --- octavia: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/octavia/octavia.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/octavia-63cb483419410e3c.yaml ================================================ --- octavia: - Fixes typos for driver agent mounts in helm templates ... ================================================ FILE: releasenotes/notes/octavia-73c0f7c8c13c00a1.yaml ================================================ --- octavia: - Run driver agent as a separate deployment on network nodes - Run worker as a daemonset instead of deployment on network nodes - | Worker daemonset creates an interface attached to the Octavia management network to get access to amphora instances ... ================================================ FILE: releasenotes/notes/octavia-74938cd9ffae016b.yaml ================================================ --- octavia: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/octavia-875ff6ae26e5586c.yaml ================================================ --- octavia: - | Set octavia-health-manager pods to run on openstack-network-node nodes in order to access the ovs socket and perform ovs functions. ... ================================================ FILE: releasenotes/notes/octavia-a9a696fde141cd8b.yaml ================================================ --- octavia: - | Fix containerPort and readiness/liveness probe port of octavia-api. ... ================================================ FILE: releasenotes/notes/octavia-b40e89ec5e5b5568.yaml ================================================ --- octavia: - | Adjust default container images to 2024.1 like other applications in OpenStack Helm instead of an out of date container. ... ================================================ FILE: releasenotes/notes/octavia-c0e8011e138832db.yaml ================================================ --- octavia: - | Move healthcheck endpoint path to the proper values section ... ================================================ FILE: releasenotes/notes/octavia-c952d2266d5dbd62.yaml ================================================ --- octavia: - | Fixes octavia-api custom volume mounts inadvertently removed in https://review.opendev.org/c/openstack/openstack-helm/+/953481 ... ================================================ FILE: releasenotes/notes/octavia-c9f2b0ece7ba8406.yaml ================================================ --- octavia: - | Allow for rbac customization of octavia policy.yaml by including a policy.yaml file. ... ================================================ FILE: releasenotes/notes/octavia-d22c4az0a92b7d16.yaml ================================================ --- octavia: - | Add helm hook annotations in jobs by default. ... ================================================ FILE: releasenotes/notes/octavia-f6afc93cf3ccc8f7.yaml ================================================ --- octavia: - | Unhardcode readiness of octavia-api and add liveness probe. Also healthcheck of octavia is enabled. ... ================================================ FILE: releasenotes/notes/octavia-health-manager-net-caps-49adc645e1d03456.yaml ================================================ --- # To create a new release note related to a specific chart: # reno new # # To create a new release note for a common change (when multiple charts # are changed): # reno new common octavia: - | Health manager requires NET_RAW and NET_BIND_SERVICE for allowing ISC DHCPD to work ... ================================================ FILE: releasenotes/notes/octavia.yaml ================================================ --- octavia: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Added post-install and post-upgrade hook for Jobs - 0.2.0 Remove support for releases before T - 0.2.1 Fix dnsPolicy for housekeeping service - 0.2.2 Update htk requirements repo - 0.2.3 Allow using log_config_append=null - 0.2.4 Fix transport_url - 0.2.5 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.6 Added OCI registry authentication - 0.2.7 Use HTTP probe instead of TCP probe - 0.2.8 Define service_type in keystone_authtoken to support application credentials with access rules - 0.2.9 Use default timeout and retry configs for haproxy_amphora - 0.2.10 Fix generating health_manager Role and RoleBinding - 0.2.11 Uses uWSGI for API service - 0.2.12 Enable custom annotations for Openstack pods - 0.2.13 Enable custom annotations for Openstack secrets - 0.2.14 Update images used by default - 0.2.15 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.16 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/openstack.yaml ================================================ --- openstack: - 0.1.0 Initial Chart - 0.1.1 Deploy compute-kit charts (neutron, nova, libvirt, openvswitch, placement) - 0.1.2 Use host path storage for rabbitmq, so that rabbitmq retains data across pod recreation - 0.1.3 Add neutron_netns_cleanup_cron release image override, so that the respective release image is used - 0.1.4 Remove links in openstack/charts - 0.1.5 Revert Remove links in openstack/charts - 0.1.6 Added horizon to install as default component. - 0.1.7 Remove placement db-migrate - 0.2.0 Remove support for Train and Ussuri - 0.2.1 Update all Ceph images to Focal - 0.2.2 Add zed values override - 0.2.3 Add Ubuntu Jammy overrides - 0.2.4 Add 2023.1 overrides for Ubuntu Focal and Jammy - 0.2.5 Add 2023.2 Ubuntu Jammy overrides - 0.2.6 Update libvirt overrides for 2023.1 and 2023.2 - 0.2.7 Update Ceph images to Jammy and Reef 18.2.1 - 0.2.8 Add 2024.1 overrides - 0.2.9 Add 2024.1 overrides - 0.2.10 Add 2024.1 overrides - 0.2.11 Add 2024.1 overrides - 0.2.12 Add 2024.1 overrides - 0.2.13 Add 2024.1 overrides - 0.2.14 Add 2024.1 overrides - 0.2.15 Add 2024.1 overrides - 0.2.16 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.17 Update default values to work on multinode cluster - 0.2.18 Add 2024.2 Ubuntu Jammy overrides - 0.2.19 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/openvswitch-0b37403ffc75bb63.yaml ================================================ --- openvswitch: - Change Open vSwitch to run with non-root user ... ================================================ FILE: releasenotes/notes/openvswitch-3401ba2f0dc8e1f6.yaml ================================================ --- openvswitch: - | Introduce .Values.openvswitch.extraContainers hook to make it possible to add extra containers to openvswitch daemonset, e.g. for monitoring purposes. ... ================================================ FILE: releasenotes/notes/openvswitch-3df8c5ca6034009f.yaml ================================================ --- openvswitch: - | Add missing priority class and runtime class definition for openvswitch ... ================================================ FILE: releasenotes/notes/openvswitch-5c0d74ca4f420e56.yaml ================================================ --- openvswitch: - Set nova user as owner for hugepages mount path ... ================================================ FILE: releasenotes/notes/openvswitch-63f74f08815529dd.yaml ================================================ --- features: - | Add ability to override cpuset.mems and cpuset.cpus for osh-openvswitch cgroup. ... ================================================ FILE: releasenotes/notes/openvswitch-c123b289b476575a.yaml ================================================ --- openvswitch: - Use quay.io/airshipit/openvswitch:latest-ubuntu_noble images by default. ... ================================================ FILE: releasenotes/notes/openvswitch-e761d6733b84bdc7.yaml ================================================ --- openvswitch: - Make the --user flag for OVS server optional ... ================================================ FILE: releasenotes/notes/openvswitch-e888d02378d4d044.yaml ================================================ --- openvswitch: - | Added /var/tmp mount to ovs-vswitchd container. This change ensures proper operation when using DPDK with the Mellanox driver. ... ================================================ FILE: releasenotes/notes/openvswitch.yaml ================================================ --- openvswitch: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Unpin images built with osh-images - 0.1.3 Use HostToContainer mountPropagation - 0.1.4 Support override of vswitchd liveness and readiness probe - 0.1.5 Use full image ref for docker official images - 0.1.6 Update htk requirements - 0.1.7 Enable taint toleration for Openstack services jobs - 0.1.8 Added OCI registry authentication - 0.1.9 Enable ovs hardware offload - 0.1.10 Merge ovs-db and ovs-vswitchd in one Daemonset - 0.1.11 Add ovn.yaml in values_override, Enable ptcp_port 6640 which needed when use ovn - 0.1.12 Replace node-role.kubernetes.io/master with control-plane - 0.1.13 Upgrade openvswitch image to latest-ubuntu_focal to fix qos issue - 0.1.14 Add buffer before accesses pid file - 0.1.15 Add buffer before accesses ovs controller pid socket - 0.1.16 Restore ServiceAccount to openvswitch pod - 0.1.17 Add buffer to wait for potential new CTL file before running chown - 0.1.18 Add value for extra poststart command - 0.1.19 Add check for cgroups v2 file structure - 0.1.20 Add Ubuntu Focal and Ubuntu Jammy overrides - 0.1.21 Add overrides for dpdk - 0.1.22 Change hugepages size to 2M for easier configuration - 0.1.23 Fix rolebinding for init container - 0.1.24 Change ovs to run as child process of start script - 0.1.25 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.26 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/other-23a753cb53b10bb8.yaml ================================================ --- other: - | Use Loci images by default in all charts. Loci builds images using periodic pipeline and publishes them to Docker Hub registry and to Quay registry which has more tolerant rate limits which is more convenient for users with anonymous accounts. ... ================================================ FILE: releasenotes/notes/ovn-3b9e82e5d469bc98.yaml ================================================ --- features: - Implement daemonset overrides ... ================================================ FILE: releasenotes/notes/ovn-3e576a7be97232fe.yaml ================================================ --- ovn: - | Update system id annotation key. This is to align with the openstack-helm-infra repo retirement. ... ================================================ FILE: releasenotes/notes/ovn-50ba6d3611decff9.yaml ================================================ --- ovn: - Add OVN Kubernetes support ... ================================================ FILE: releasenotes/notes/ovn-53e7ddb42d51e7c9.yaml ================================================ --- ovn: - | Add missing apiVersion and kind to volumeClaimTemplates for ovn-ovsdb-nb and ovn-ovsdb-sb StatefulSet. ... ================================================ FILE: releasenotes/notes/ovn-6c1c8afff28cf7f7.yaml ================================================ --- ovn: - | This change introduces the use of a PersistentVolumeClaim (PVC) mounted at /var/lib/ovn to store OVN database files (ovnnb_db.db and ovnsb_db.db). Previously, the OVN databases were stored on ephemeral pod storage, which caused the databases to be lost whenever the OVN pods were restarted. This resulted in network outages and forced a full synchronization between the Neutron database and OVN, impacting cluster stability. The issue was introduced by commit ffd183a164be190afcc2ce4de27de7e72ab8d386, which caused problems during OVN upgrades due to the lack of persistent storage. By storing the OVN databases on a persistent volume, pod restarts and upgrades can be performed safely without data loss or network disruption. ... ================================================ FILE: releasenotes/notes/ovn-73332b0bc5d647f2.yaml ================================================ --- ovn: - | Add support for overriding OVN environment variables. OVN relies on environment variables to control the behavior of its services. This allowing users to override these variables enables finer tuning of OVN services when needed. ... ================================================ FILE: releasenotes/notes/ovn-8b5cc103886f3b25.yaml ================================================ --- ovn: - | Add support for ovn_monitor_all. ... ================================================ FILE: releasenotes/notes/ovn-a82eced671495a3d.yaml ================================================ --- ovn: - Add OVN network logging parser ... ================================================ FILE: releasenotes/notes/ovn-b172c29d8c0602b1.yaml ================================================ --- ovn: - | Update Ceph to Tentacle 20.2.0 and replaced image sources from docker.io/openstackhelm with quay.io/airshipit ... ================================================ FILE: releasenotes/notes/ovn-d195851d81d68036.yaml ================================================ --- ovn: - | Add a missing support for oci_image_registry. ... ================================================ FILE: releasenotes/notes/ovn-ffd84bb8c9e73b64.yaml ================================================ --- # To create a new release note related to a specific chart: # reno new # # To create a new release note for a common change (when multiple charts # are changed): # reno new common ovn: - | Use `ip add replace` instead of `ip addr add` in the init script to make it idempotent and avoid errors when the script tries to assign the same IP address to the interface on subsequent runs. ... ================================================ FILE: releasenotes/notes/ovn.yaml ================================================ --- ovn: - 0.1.0 Add OVN! - 0.1.1 Fix ovn db persistence issue - 0.1.2 Add bridge-mapping configuration - 0.1.3 Fix system-id reuse - 0.1.4 Add support for OVN HA + refactor - 0.1.5 Add ubuntu_focal and ubuntu_jammy overrides - 0.1.6 Fix ovsdb port number - 0.1.7 Use host network for ovn controller pods - 0.1.8 Fix attaching interfaces to the bridge - 0.1.9 Make ovn db file path as configurable - 0.1.10 Fix typo in the controller init script - 0.1.11 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.12 Fix oci_image_registry secret name - 0.1.13 Allow share OVN DB NB/SB socket - 0.1.14 Make the label for OVN controller gateway configurable - 0.1.15 Fix resources - 0.1.16 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/panko.yaml ================================================ --- panko: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.2.0 Remove support for releases before T - 1.0.0 Removed due to retirement ... ================================================ FILE: releasenotes/notes/placement-2b023904bc06028b.yaml ================================================ --- placement: - | Split out the OpenStack service account definitions from placement.conf and into config snippets which are loaded at /etc/placement/placement.d/, which is automatically loaded by OSLO when loading the main placement.conf. This makes it easier for users to use the regular config generation while supplying credentials out of band. ... ================================================ FILE: releasenotes/notes/placement-3115f3ce4c0801af.yaml ================================================ --- placement: - | Add support for etcSources to db-sync job. ... ================================================ FILE: releasenotes/notes/placement-a180f4e88ed81d30.yaml ================================================ --- placement: - | Allow users to add additional sources to the Projected Volume that is mounted at /etc/placement/placement.conf.d/ so they may more easily override configs or provide additional configs for the various services in the chart. ... ================================================ FILE: releasenotes/notes/placement.yaml ================================================ --- placement: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Establish Nova/Placement dependencies - 0.1.3 Use proper default placement image - 0.1.4 Add null check condition in placement deployment manifest - 0.1.5 Change Issuer to ClusterIssuer - 0.1.6 Revert - Change Issuer to ClusterIssuer - 0.1.7 Change Issuer to ClusterIssuer - 0.2.0 Remove support for releases before T - 0.2.1 Add Ussuri release support - 0.2.2 Add Victoria and Wallaby releases support - 0.2.3 Added helm.sh/hook annotations for Jobs - 0.2.4 Helm 3 - Fix Job Labels - 0.2.5 Update htk requirements repo - 0.2.6 Enable taint toleration for Openstack services - 0.2.7 Add helm hook annotations for db-sync job - 0.2.8 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.9 Add Xena and Yoga values overrides - 0.2.10 Added OCI registry authentication - 0.2.11 Distinguish between port number of internal endpoint and binding port number - 0.2.12 Use HTTP probe instead of TCP probe - 0.2.13 Support TLS endpoints - 0.3.0 Remove placement-migrate - 0.3.1 Remove support for Train and Ussuri - 0.3.2 Remove default policy rules - 0.3.3 Replace node-role.kubernetes.io/master with control-plane - 0.3.4 Define service_type in keystone_authtoken to support application credentials with access rules - 0.3.5 Add Zed overrides - 0.3.6 Add 2023.1 overrides - 0.3.7 Use service tokens - 0.3.8 Add Ubuntu Jammy overrides - 0.3.9 Add 2023.2 Ubuntu Jammy overrides - 0.3.10 Add log_dir option for placement - 0.3.11 Enable custom annotations for Openstack pods - 0.3.12 Add 2024.1 overrides - 0.3.13 Enable custom annotations for Openstack secrets - 0.3.14 Update images used by default - 0.3.15 Uses uWSGI for API service - 0.3.16 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.3.17 Add 2024.2 Ubuntu Jammy overrides - 0.3.18 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/podsecuritypolicy.yaml ================================================ --- podsecuritypolicy: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update htk requirements - 1.0.0 Remove chart due to PodSecurityPolicy deprecation ... ================================================ FILE: releasenotes/notes/postgresql-4ee4e72706f17d8a.yaml ================================================ --- fixes: - | Added failover openrc environment variables to database backup cron jobs. ... ================================================ FILE: releasenotes/notes/postgresql-e1a02dbbe6601b0f.yaml ================================================ --- postgresql: - Add support of hostPath volume for archive mode - Use DirectoryOrCreate type for hostPath volumes ... ================================================ FILE: releasenotes/notes/postgresql.yaml ================================================ --- postgresql: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 adding archiving to postgres - 0.1.3 Use explicit entrypoint for prometheus exporter - 0.1.4 Allow probe tweaking - 0.1.5 Optimize restart behavior - 0.1.6 Revert "Add default reject rule ..." - 0.1.7 postgres archive cleanup script - 0.1.8 Add tls to Postgresql - 0.1.9 Use full image ref for docker official images - 0.1.10 Helm 3 - Fix Job labels - 0.1.11 Update htk requirements - 0.1.12 Enhance postgresql backup - 0.1.13 Remove set -x - 0.1.14 Fix invalid fields in values - 0.1.15 Migrated CronJob resource to batch/v1 API version - 0.1.16 Added OCI registry authentication - 0.1.17 Added empty verify_databases_backup_archives() function implementation to match updated backup_databases() function in helm-toolkit - 0.1.18 Updated postgres to 14.5 and replaced deprecated config item wal_keep_segments with wal_keep_size - 0.1.19 Added staggered backups support - 0.1.20 Added throttling remote backups - 0.1.21 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.22 Update default images tags. Add 2024.1-ubuntu_jammy overrides. - 0.1.23 Add 2024.2 overrides - 0.1.24 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/powerdns.yaml ================================================ --- powerdns: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Helm 3 - Fix Job labels - 0.1.4 Update htk requirements - 0.1.5 Update default image values - 0.1.6 Added OCI registry authentication - 0.1.7 Add 2023.1 Ubuntu Focal overrides - 0.1.8 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.9 Add 2024.1 Ubuntu Jammy overrides - 0.1.10 Add 2024.2 overrides - 0.1.11 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometeus-alertmanager-293616e8a47a12e8.yaml ================================================ --- prometheus-alertmanager: - Add support of hostPath volume ... ================================================ FILE: releasenotes/notes/prometeus-e9a80f262470313c.yaml ================================================ --- prometheus: - Add support of hostPath volume ... ================================================ FILE: releasenotes/notes/prometheus-alertmanager.yaml ================================================ --- prometheus-alertmanager: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Add extensible command line flags to Alertmanager - 0.1.3 Add LDAP to Alertmanager - 0.1.4 Remove snmp_notifier subchart from alertmanager - 0.1.5 Add Prometheus Scrape Annotation - 0.1.6 Remove Alerta from openstack-helm-infra repository - 0.1.7 Use full image ref for docker official images - 0.1.8 Update htk requirements - 0.1.9 Added OCI registry authentication - 0.1.10 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.11 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometheus-blackbox-exporter.yaml ================================================ --- prometheus-blackbox-exporter: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Rename image key name - 0.1.3 Update htk requirements - 0.1.4 Fix indentation - 0.1.5 Added OCI registry authentication - 0.1.6 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometheus-kube-state-metrics-b1fc3bf8e9109ae4.yaml ================================================ --- prometheus-kube-state-metrics: - Update kube-state-metrics image ... ================================================ FILE: releasenotes/notes/prometheus-kube-state-metrics.yaml ================================================ --- prometheus-kube-state-metrics: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update to make current - 0.1.3 Update image version from v2.0.0-alpha to v2.0.0-alpha-1 - 0.1.4 Use full image ref for docker official images - 0.1.5 Fix helm3 compatability - 0.1.6 Update htk requirements - 0.1.7 Added OCI registry authentication - 0.1.8 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.9 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometheus-mysql-exporter.yaml ================================================ --- prometheus-mysql-exporter: - 0.0.1 Initial Chart - 0.0.2 Add 2024.1 overrides - 0.0.3 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.0.4 Fix typo in the values_overrides directory name - 0.0.5 Add 2024.2 overrides - 0.0.6 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometheus-node-exporter.yaml ================================================ --- prometheus-node-exporter: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Add possibility to use overrides for some charts - 0.1.3 Use full image ref for docker official images - 0.1.4 Update htk requirements - 0.1.5 Added OCI registry authentication - 0.1.6 Replace node-role.kubernetes.io/master with control-plane - 0.1.7 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.8 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometheus-openstack-exporter-39b2a7f52552033d.yaml ================================================ --- prometheus-openstack-exporter: - Upgrade openstack-exporter to the latest v1.7.0. ... ================================================ FILE: releasenotes/notes/prometheus-openstack-exporter-d95d286faa68ea98.yaml ================================================ --- prometheus-openstack-exporter: - Swap to official openstack exporter image. ... ================================================ FILE: releasenotes/notes/prometheus-openstack-exporter.yaml ================================================ --- prometheus-openstack-exporter: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Unpin prometheus-openstack-exporter image - 0.1.3 Add possibility to use overrides for some charts - 0.1.4 Use full image ref for docker official images - 0.1.5 Helm 3 - Fix Job labels - 0.1.6 Update htk requirements - 0.1.7 Added OCI registry authentication - 0.1.8 Switch to jammy-based images - 0.1.9 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.10 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometheus-process-exporter.yaml ================================================ --- prometheus-process-exporter: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Fix values_overrides directory naming - 0.1.3 Use full image ref for docker official images - 0.1.4 Update htk requirements - 0.1.5 Added OCI registry authentication - 0.1.6 Replace node-role.kubernetes.io/master with control-plane - 0.1.7 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.8 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/prometheus.yaml ================================================ --- prometheus: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Add configurable readiness/liveness Probes - 0.1.3 Revert "Render Rules as Templates" - 0.1.4 Fix spacing inconsistencies with flags - 0.1.5 Fix spacing inconsistencies with flags - 0.1.6 Upgrade version to v2.25 fix/remove deprecated flags - 0.1.7 Enable TLS for Prometheus - 0.1.8 Change readiness probe from /status to /-/ready - 0.1.9 Retrieve backend port name from values.yaml - 0.1.10 Use full image ref for docker official images - 0.1.11 Update htk requirements - 0.1.12 Update default image value to Wallaby - 0.1.13 Added OCI registry authentication - 0.1.14 Added feature to launch Prometheus with custom script - 0.1.15 Add 2023.1 Ubuntu Focal overrides - 0.1.16 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.17 Add 2024.1 Ubuntu Jammy overrides - 0.1.18 Add 2024.2 overrides - 0.1.19 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/rabbitmq-04d68343d1f9dbec.yaml ================================================ --- rabbitmq: - | Removing rabbitmq exporter due to EOL. Converted to use built-in metrics instead. ... ================================================ FILE: releasenotes/notes/rabbitmq.yaml ================================================ --- rabbitmq: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 changes rmq-exporter secret src - 0.1.4 Add configurable RABBIT_TIMEOUT parameter - 0.1.5 Update Rabbitmq exporter version - 0.1.6 Disallow privilege escalation in rabbitmq server container - 0.1.7 Adding TLS logic to rabbitmq - 0.1.8 Make helm test work with TLS - 0.1.9 Use full image ref for docker official images - 0.1.10 Set separate for HTTPS - 0.1.11 Add TLS support for helm test - 0.1.12 Added helm hook post-install and post-upgrade for rabbitmq wait cluster job - 0.1.13 Add prestop action and version 3.8.x upgrade prep - 0.1.14 Update readiness and liveness probes - 0.1.15 Update htk requirements - 0.1.16 Add force_boot command to rabbit start template - 0.1.17 Updated naming for subchart compatibility - 0.1.18 Revert naming for subchart compatibility - 0.1.19 Enable taint toleration for Openstack services jobs - 0.1.20 Bump Rabbitmq version to 3.9.0 - 0.1.21 Updated naming for subchart compatibility - 0.1.22 Remove guest admin account - 0.1.23 Fixed guest account removal - 0.1.24 Added OCI registry authentication - 0.1.25 Add hostPort support - 0.1.26 Moved guest admin removal to init template - 0.1.27 Replace node-role.kubernetes.io/master with control-plane - 0.1.28 Add IPv6 environment support for rabbitmq - 0.1.29 Add build-in prometheus plugin and disable external exporter - 0.1.30 Add labels to rabbitmq service - 0.1.31 Support management api metrics collection - 0.1.32 Enable addition of default consumer prefetch count - 0.1.33 Bump RabbitMQ image version to 3.13.0 - 0.1.34 Add 2024.1 overrides - 0.1.35 Add configurable probes to rabbitmq container - 0.1.36 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.37 Update rabbitmq readiness/liveness command - 0.1.38 Do not use hardcoded username in rabbitmq chown container - 0.1.39 Allow to bootstrap rabbitmq with initial config - 0.1.40 Set password for guest user rabbitmq - 0.1.41 Use short rabbitmq node name - 0.1.42 Revert Use short rabbitmq node name - 0.1.43 Add 2024.2 overrides - 0.1.44 Allow to use default storage class - 0.1.45 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/rally.yaml ================================================ --- rally: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.2.0 Remove support for releases before T - 0.2.1 Update htk requirements repo - 0.2.2 Add values for backoffLimit and restartPolicy - 0.2.3 Update default image values to Wallaby - 0.2.4 Migrated PodDisruptionBudget resource to policy/v1 API version - 0.2.5 Add helm hook for jobs - 0.2.6 Added OCI registry authentication - 0.2.7 Support TLS for identity endpoint - 0.2.8 Bump Cirros version to 0.6.2 - 0.2.9 Enable custom annotations for Openstack secrets - 0.2.10 Update images used by default - 0.2.11 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.12 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/redis.yaml ================================================ --- redis: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Use full image ref for docker official images - 0.1.3 Update htk requirements - 0.1.4 Added OCI registry authentication - 0.1.5 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.6 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/registry-daf63a0fbe9771cb.yaml ================================================ --- registry: - Update docker client image to 29 - | Use quay.io/airshipit/keystone-entrypoint:latest-ubuntu_jammy image by default for init containers ... ================================================ FILE: releasenotes/notes/registry.yaml ================================================ --- registry: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.1.2 Update to container image repo k8s.gcr.io - 0.1.3 Use full image ref for docker official images - 0.1.4 Helm 3 - Fix Job labels - 0.1.5 Update htk requirements - 0.1.6 Added OCI registry authentication - 0.1.7 Update kubernetes registry to registry.k8s.io - 0.1.8 Update bootstrap image url for newer image format - 0.1.9 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.10 Allow to use default storage class - 0.1.11 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/remove-legacy-volume-apis-12d2d1abbb7fbe61.yaml ================================================ --- cinder: - | Removed endpoints for v1 API and v2 API because these were already removed from cinder. ... ================================================ FILE: releasenotes/notes/remove-share-v1-api-d7b0b85e395bf131.yaml ================================================ --- manila: - | Removed endpoint for the legacy share API, becuase it has been removed from manila. ... ================================================ FILE: releasenotes/notes/rename-ceph-rbd-pool-app-name.yaml ================================================ --- other: - | rbd_pool_app_name is a Ceph pool attribute. Moving it from conf.software.rbd to conf.ceph.pools as app_name. This means that conf.software.rbd.rbd_pool_app_name is now conf.ceph.pools.cinder.volumes.app_name and conf.software.rbd.rbd_pool_app_name_backup is now conf.ceph.pools.backup.app_name. ... ================================================ FILE: releasenotes/notes/skyline-0cc4caaea4f05714.yaml ================================================ --- skyline: - | Adding a missing oci_image_registry endpoint and secret in the Skyline Helm chart. ... ================================================ FILE: releasenotes/notes/skyline-4763b3a9c14ace98.yaml ================================================ --- skyline: - | Bring out database migrations and nginx config generation to separate scripts so that they can be run independently during init container phase. - | Use Loci Skyline image by default. ... ================================================ FILE: releasenotes/notes/skyline-794e9be9cc48f98d.yaml ================================================ --- skyline: - | Initial release of the Skyline chart ... ================================================ FILE: releasenotes/notes/skyline-db-sync-image-b56ba0a4cad85c9c.yaml ================================================ --- skyline: - | Fix db-sync container image tag variable to match the style of all other charts to be prefixed with the project name. ... ================================================ FILE: releasenotes/notes/skyline-de744253bec9dfa3.yaml ================================================ --- fixes: - | Mount Skyline apiserver socket directory to the nginx container. The Skyline pods have two containers: nginx and skyline apiserver. The nginx container needs access to the apiserver socket to proxy requests to it. ... ================================================ FILE: releasenotes/notes/tacker.yaml ================================================ --- tacker: - 0.1.0 Initial Chart - 0.1.1 Add Ubuntu Jammy overrides - 0.1.2 Add 2023.2 Ubuntu Jammy overrides - 0.1.3 Add 2024.1 overrides - 0.1.4 Enable custom annotations for Openstack secrets - 0.1.5 Update images used by default - 0.1.6 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.1.7 Add Tacker Test Job - 0.1.8 Add 2024.2 Ubuntu Jammy overrides - 0.1.9 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/tempest.yaml ================================================ --- tempest: - 0.1.0 Initial Chart - 0.1.1 Change helm-toolkit dependency version to ">= 0.1.0" - 0.2.0 Remove support for releases before T - 0.2.1 Update htk requirements repo - 0.2.2 Add helm hook for ks job - 0.2.3 Fix logging config - 0.2.4 Update default image values to Wallaby - 0.2.5 Added OCI registry authentication - 0.2.6 Support SSL openstack endpoints - 0.2.7 Add configuration for heat-tempest-plugin - 0.2.8 Bump Cirros version to 0.6.2 - 0.2.9 Enable custom annotations for Openstack secrets - 0.2.10 Update images used by default - 0.2.11 Use quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal by default - 0.2.12 Update Chart.yaml apiVersion to v2 - 2024.2.0 Update version to align with the Openstack release cycle ... ================================================ FILE: releasenotes/notes/trove-a1b2c3d4e5f6g7h8.yaml ================================================ --- features: - | Added configuration for required OpenStack service endpoints (Nova, Neutron, Cinder, and Glance) in the Trove Helm chart. - | Added service credential definitions to support integration with dependent OpenStack services. ... ================================================ FILE: releasenotes/notes/trove.yaml ================================================ --- trove: - Initial Chart - OpenStack Database as a Service (DBaaS) ... ================================================ FILE: releasenotes/notes/watcher.yaml ================================================ --- watcher: - 0.1.0 Initial Chart ... ================================================ FILE: releasenotes/notes/zaqar-e43f9b2ace992d92.yaml ================================================ --- zaqar: - | Added initial support for OpenStack Zaqar messaging service deployment in Kubernetes environments through Helm charts. This enables users to deploy and manage Zaqar services alongside other OpenStack components. features: - | Introduced Zaqar Helm chart with support for: - Zaqar API service deployment and configuration - Support for HTTP-based RESTful API and WebSocket messaging - Integration with existing OpenStack identity services (Keystone) - Support for custom Zaqar configuration through values.yaml ... ================================================ FILE: releasenotes/requirements.txt ================================================ # The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. sphinx>=2.0.0,!=2.1.0 # BSD openstackdocstheme>=2.2.1 # Apache-2.0 reno>=3.1.0 # Apache-2.0 ================================================ FILE: releasenotes/source/conf.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'openstackdocstheme', 'reno.sphinxext', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # -- Options for Internationalization output ------------------------------ locale_dirs = ['locale/'] ================================================ FILE: releasenotes/source/current.rst ================================================ ============================== Current Series Release Notes ============================== .. release-notes:: ================================================ FILE: releasenotes/source/index.rst ================================================ ============================= OpenStack-Helm Release Notes ============================= .. toctree:: :maxdepth: 1 current ================================================ FILE: releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po ================================================ # Andi Chandler , 2021. #zanata # Andi Chandler , 2022. #zanata # Andi Chandler , 2023. #zanata msgid "" msgstr "" "Project-Id-Version: Python\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-02-21 00:39+0000\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2023-02-03 04:48+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: English (United Kingdom)\n" "Language: en_GB\n" "X-Generator: Zanata 4.3.3\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" msgid "0.1.0 Initial Chart" msgstr "0.1.0 Initial Chart" msgid "0.1.1 Change helm-toolkit dependency to >= 0.1.0" msgstr "0.1.1 Change helm-toolkit dependency to >= 0.1.0" msgid "0.1.1 Change helm-toolkit dependency version to \">= 0.1.0\"" msgstr "0.1.1 Change helm-toolkit dependency version to \">= 0.1.0\"" msgid "0.1.1 UPDATE" msgstr "0.1.1 UPDATE" msgid "0.1.10 Change Issuer to ClusterIssuer" msgstr "0.1.10 Change Issuer to ClusterIssuer" msgid "0.1.10 Update RBAC apiVersion from /v1beta1 to /v1" msgstr "0.1.10 Update RBAC apiVersion from /v1beta1 to /v1" msgid "0.1.10 Use HostToContainer mount propagation" msgstr "0.1.10 Use HostToContainer mount propagation" msgid "0.1.11 Added the helm.sh/hook, helm.sh/hook-weight annotations" msgstr "0.1.11 Added the helm.sh/hook, helm.sh/hook-weight annotations" msgid "0.1.11 Remove congress residue" msgstr "0.1.11 Remove congress residue" msgid "" "0.1.11 Secure libvirt connection from using 127.0.0.1 to use unix socket" msgstr "" "0.1.11 Secure libvirt connection from using 127.0.0.1 to use Unix socket" msgid "0.1.11 Update RBAC apiVersion from /v1beta1 to /v1" msgstr "0.1.11 Update RBAC apiVersion from /v1beta1 to /v1" msgid "0.1.12 Add helm hook conditional" msgstr "0.1.12 Add helm hook conditional" msgid "0.1.12 Removed \"name\" parameter from Rally tests" msgstr "0.1.12 Removed \"name\" parameter from Rally tests" msgid "0.1.12 Update RBAC apiVersion from /v1beta1 to /v1" msgstr "0.1.12 Update RBAC apiVersion from /v1beta1 to /v1" msgid "0.1.12 Update volume type creation bootstrap logic" msgstr "0.1.12 Update volume type creation bootstrap logic" msgid "0.1.13 Add NFS cinder backup override" msgstr "0.1.13 Add NFS cinder backup override" msgid "0.1.13 Change Issuer to ClusterIssuer" msgstr "0.1.13 Change Issuer to ClusterIssuer" msgid "0.1.13 Fix Error - wrong number of args for set" msgstr "0.1.13 Fix Error - wrong number of args for set" msgid "0.1.14 Add Multipathd support for ISCSI backed volumes" msgstr "0.1.14 Add Multipathd support for ISCSI backed volumes" msgid "0.1.14 BUG for deploying multiple compute nodes" msgstr "0.1.14 BUG for deploying multiple compute nodes" msgid "0.1.14 Remove setup helm hooks" msgstr "0.1.14 Remove setup Helm hooks" msgid "0.1.15 Fix the problem in hostNetwork mode" msgstr "0.1.15 Fix the problem in hostNetwork mode" msgid "0.1.15 Mount /dev/pts in Nova compute container" msgstr "0.1.15 Mount /dev/pts in Nova compute container" msgid "0.1.16 Use first IP address for migration" msgstr "0.1.16 Use first IP address for migration" msgid "0.1.17 Add multipathd support for ISCSI backed volume VMs" msgstr "0.1.17 Add multipathd support for ISCSI backed volume VMs" msgid "0.1.18 Fix the nova-compute-ironic label issue" msgstr "0.1.18 Fix the nova-compute-ironic label issue" msgid "0.1.19 Host resource scale adjustment about ironic" msgstr "0.1.19 Host resource scale adjustment about Ironic" msgid "0.1.2 Add ssh to Nova compute" msgstr "0.1.2 Add ssh to Nova compute" msgid "0.1.2 Added post-install and post-upgrade helm hook for Jobs" msgstr "0.1.2 Added post-install and post-upgrade helm hook for Jobs" msgid "0.1.2 Added post-install and post-upgrade helm hook for jobs" msgstr "0.1.2 Added post-install and post-upgrade helm hook for jobs" msgid "0.1.2 Added post-install and post-upgrade helm hooks on Jobs" msgstr "0.1.2 Added post-install and post-upgrade helm hooks on Jobs" msgid "0.1.2 Added post-install and post-upgrade helm.sh/hook for jobs" msgstr "0.1.2 Added post-install and post-upgrade helm.sh/hook for jobs" msgid "0.1.2 Added post-install and post-upgrade hook for Jobs" msgstr "0.1.2 Added post-install and post-upgrade hook for Jobs" msgid "0.1.2 Change issuer to clusterissuer" msgstr "0.1.2 Change issuer to clusterissuer" msgid "0.1.2 Establish Nova/Placement dependencies" msgstr "0.1.2 Establish Nova/Placement dependencies" msgid "0.1.2 Remove tls values override for clients_heat" msgstr "0.1.2 Remove tls values override for clients_heat" msgid "0.1.2 Support service tokens to prevent long-running job failures" msgstr "0.1.2 Support service tokens to prevent long-running job failures" msgid "0.1.2 To avoid wrong version check for mysqlclient" msgstr "0.1.2 To avoid wrong version check for mysqlclient" msgid "0.1.2 UPDATE" msgstr "0.1.2 UPDATE" msgid "0.1.2 fixes tls issue" msgstr "0.1.2 fixes tls issue" msgid "0.1.3 Change Issuer to ClusterIssuer" msgstr "0.1.3 Change Issuer to ClusterIssuer" msgid "0.1.3 Establish Nova and Placement dependencies" msgstr "0.1.3 Establish Nova and Placement dependencies" msgid "0.1.3 Modify Password validator related settings in Horizon" msgstr "0.1.3 Modify Password validator related settings in Horizon" msgid "0.1.3 Revert - Change issuer to clusterissuer" msgstr "0.1.3 Revert - Change issuer to clusterissuer" msgid "0.1.3 Support of external ceph backend" msgstr "0.1.3 Support of external CEPH backend" msgid "0.1.3 UPDATE" msgstr "0.1.3 UPDATE" msgid "0.1.3 Update neutron to use Nginx apparmor profile" msgstr "0.1.3 Update neutron to use Nginx apparmor profile" msgid "0.1.3 Use proper default placement image" msgstr "0.1.3 Use proper default placement image" msgid "0.1.4 Add null check condition in placement deployment manifest" msgstr "0.1.4 Add null check condition in placement deployment manifest" msgid "0.1.4 Change Issuer to ClusterIssuer" msgstr "0.1.4 Change Issuer to ClusterIssuer" msgid "0.1.4 Enable iscsi to work correctly in cinder volume" msgstr "0.1.4 Enable iSCSI to work correctly in Cinder volume" msgid "0.1.4 Pass ovs agent config to dhcp agent" msgstr "0.1.4 Pass ovs agent config to DHCP agent" msgid "0.1.4 Remove deprecated os_region_name for placement" msgstr "0.1.4 Remove deprecated os_region_name for placement" msgid "0.1.4 Revert - Change Issuer to ClusterIssuer" msgstr "0.1.4 Revert - Change Issuer to ClusterIssuer" msgid "0.1.4 UPDATE" msgstr "0.1.4 UPDATE" msgid "0.1.4 Update RBAC apiVersion from /v1beta1 to /v1" msgstr "0.1.4 Update RBAC apiVersion from /v1beta1 to /v1" msgid "0.1.5 Add missing flags to nginx container in neutron chart" msgstr "0.1.5 Add missing flags to Nginx container in Neutron chart" msgid "0.1.5 Change Issuer to ClusterIssuer" msgstr "0.1.5 Change Issuer to ClusterIssuer" msgid "0.1.5 Enable hostIPC" msgstr "0.1.5 Enable hostIPC" msgid "0.1.5 Resolves mount issue with termination-log" msgstr "0.1.5 Resolves mount issue with termination-log" msgid "0.1.5 Revert - Change Issuer to ClusterIssuer" msgstr "0.1.5 Revert - Change Issuer to ClusterIssuer" msgid "0.1.5 Revert clusterissuer change" msgstr "0.1.5 Revert clusterissuer change" msgid "0.1.6 Change Issuer to ClusterIssuer" msgstr "0.1.6 Change Issuer to ClusterIssuer" msgid "0.1.6 Enable volume backup for iSCSI based volumes" msgstr "0.1.6 Enable volume backup for iSCSI based volumes" msgid "0.1.6 Fix typo in subPath entry" msgstr "0.1.6 Fix typo in subPath entry" msgid "0.1.6 Revert - Change Issuer to ClusterIssuer" msgstr "0.1.6 Revert - Change Issuer to ClusterIssuer" msgid "0.1.6 Swap SSH key names to reflect the correct key" msgstr "0.1.6 Swap SSH key names to reflect the correct key" msgid "0.1.6 Update glance default policy values" msgstr "0.1.6 Update glance default policy values" msgid "0.1.6 Use HostToContainer mountPropagation" msgstr "0.1.6 Use HostToContainer mountPropagation" msgid "0.1.7 Change Issuer to ClusterIssuer" msgstr "0.1.7 Change Issuer to ClusterIssuer" msgid "0.1.7 Move rabbit-init to dynamic dependency" msgstr "0.1.7 Move rabbit-init to dynamic dependency" msgid "0.1.7 Update glance default policy values" msgstr "0.1.7 Update glance default policy values" msgid "0.1.7 Update storage init script with cacert" msgstr "0.1.7 Update storage init script with cacert" msgid "0.1.7 Use HostToContainer mountPropagation" msgstr "0.1.7 Use HostToContainer mountPropagation" msgid "0.1.8 Change Issuer to ClusterIssuer" msgstr "0.1.8 Change Issuer to ClusterIssuer" msgid "0.1.8 Implement \"CSRF_COOKIE_HTTPONLY\" option support in horizon" msgstr "0.1.8 Implement \"CSRF_COOKIE_HTTPONLY\" option support in horizon" msgid "0.1.8 Revert - Change Issuer to ClusterIssuer" msgstr "0.1.8 Revert - Change Issuer to ClusterIssuer" msgid "0.1.8 Revert Change Issuer to ClusterIssuer" msgstr "0.1.8 Revert Change Issuer to ClusterIssuer" msgid "0.1.8 Update glance default policy values" msgstr "0.1.8 Update glance default policy values" msgid "0.1.9 Add helm.sh/hook related annotations" msgstr "0.1.9 Add helm.sh/hook related annotations" msgid "0.1.9 Revert \"Change Issuer to ClusterIssuer\"" msgstr "0.1.9 Revert \"Change Issuer to ClusterIssuer\"" msgid "0.1.9 Update ovs agent to support host/label overrides" msgstr "0.1.9 Update ovs agent to support host/label overrides" msgid "0.1.9 Use HostToContainer mount propagation" msgstr "0.1.9 Use HostToContainer mount propagation" msgid "0.2.0 Remove support for releases before T" msgstr "0.2.0 Remove support for releases before T" msgid "0.2.1 Add Ussuri release support" msgstr "0.2.1 Add Ussuri release support" msgid "0.2.1 Adding rabbitmq TLS logic" msgstr "0.2.1 Adding RabbitMQ TLS logic" msgid "0.2.1 Fix dnsPolicy for housekeeping service" msgstr "0.2.1 Fix dnsPolicy for housekeeping service" msgid "0.2.1 Fix the ceph pool creations for openstack services" msgstr "0.2.1 Fix the Ceph pool creations for OpenStack services" msgid "0.2.1 Make python script PEP8 compliant" msgstr "0.2.1 Make Python script PEP8 compliant" msgid "0.2.1 Remove paste ini config settings" msgstr "0.2.1 Remove paste ini config settings" msgid "0.2.1 Remove unnecessary +x permission on gotpl files" msgstr "0.2.1 Remove unnecessary +x permission on gotpl files" msgid "0.2.1 Update htk requirements repo" msgstr "0.2.1 Update htk requirements repo" msgid "0.2.1 Use policies in yaml format" msgstr "0.2.1 Use policies in yaml format" msgid "0.2.10 Add tls cert mounting to nova-novnc" msgstr "0.2.10 Add tls cert mounting to nova-novnc" msgid "0.2.10 Added OCI registry authentication" msgstr "0.2.10 Added OCI registry authentication" msgid "0.2.10 Enable taint toleration for Openstack services" msgstr "0.2.10 Enable taint toleration for OpenStack services" msgid "0.2.10 Helm 3 - Fix Job Labels" msgstr "0.2.10 Helm 3 - Fix Job Labels" msgid "0.2.10 Make internal TLS more robust" msgstr "0.2.10 Make internal TLS more robust" msgid "0.2.10 Update htk requirements repo" msgstr "0.2.10 Update htk requirements repo" msgid "0.2.10 Updated naming for subchart compatibility" msgstr "0.2.10 Updated naming for subchart compatibility" msgid "0.2.11 Add Victoria and Wallaby releases support" msgstr "0.2.11 Add Victoria and Wallaby releases support" msgid "0.2.11 Add missing slash" msgstr "0.2.11 Add missing slash" msgid "" "0.2.11 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.2.11 Distinguish between the port number of internal endpoint and binding " "port number" msgid "0.2.11 Fix job annotations for db init job" msgstr "0.2.11 Fix job annotations for db init job" msgid "0.2.11 Improve health probe logging" msgstr "0.2.11 Improve health probe logging" msgid "0.2.11 Remove old releases values override in heat" msgstr "0.2.11 Remove old releases values override in heat" msgid "0.2.11 Update htk requirements repo" msgstr "0.2.11 Update htk requirements repo" msgid "0.2.12 Bootstrap flavor creation efficiencies" msgstr "0.2.12 Bootstrap flavour creation efficiencies" msgid "0.2.12 Fix infinite recursion deadlock on netns cleanup cron" msgstr "0.2.12 Fix infinite recursion deadlock on netns cleanup cron" msgid "0.2.12 Helm 3 - Fix Job Labels" msgstr "0.2.12 Helm 3 - Fix Job Labels" msgid "" "0.2.12 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgstr "" "0.2.12 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgid "0.2.12 Remove cinder v1/v2 defaults" msgstr "0.2.12 Remove Cinder v1/v2 defaults" msgid "0.2.12 Remove older values overrides" msgstr "0.2.12 Remove older values overrides" msgid "0.2.12 Support both json and yaml RBAC Policy Format" msgstr "0.2.12 Support both JSON and YAML RBAC Policy Format" msgid "0.2.12 Use HTTP probe instead of TCP probe" msgstr "0.2.12 Use HTTP probe instead of TCP probe" msgid "0.2.13 Add Xena and Yoga values overrides" msgstr "0.2.13 Add Xena and Yoga values overrides" msgid "0.2.13 Add container infra api version in values" msgstr "0.2.13 Add container infra API version in values" msgid "0.2.13 Add missing 'runlock' hostMount when enable_scsi" msgstr "0.2.13 Add missing 'runlock' hostMount when enable_scsi" msgid "0.2.13 Enable taint toleration for Openstack services" msgstr "0.2.13 Enable taint toleration for OpenStack services" msgid "0.2.13 Helm 3 - Fix more Job Labels" msgstr "0.2.13 Helm 3 - Fix more Job Labels" msgid "0.2.13 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.2.13 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.2.13 Support TLS endpoints" msgstr "0.2.13 Support TLS endpoints" msgid "0.2.13 Upgrade default images to ussuri" msgstr "0.2.13 Upgrade default images to Ussuri" msgid "0.2.14 Add OPENSTACK_ENDPOINT_TYPE value" msgstr "0.2.14 Add OPENSTACK_ENDPOINT_TYPE value" msgid "0.2.14 Add Xena and Yoga values overrides" msgstr "0.2.14 Add Xena and Yoga values overrides" msgid "0.2.14 Added OCI registry authentication" msgstr "0.2.14 Added OCI registry authentication" msgid "0.2.14 Fix notifications" msgstr "0.2.14 Fix notifications" msgid "0.2.14 Migrate IP from bridge for auto_bridge_add" msgstr "0.2.14 Migrate IP from bridge for auto_bridge_add" msgid "0.2.14 Update htk requirements repo" msgstr "0.2.14 Update htk requirements repo" msgid "0.2.14 Use helm.sh/hook annotations for jobs" msgstr "0.2.14 Use helm.sh/hook annotations for jobs" msgid "0.2.15 Add local_settings.d" msgstr "0.2.15 Add local_settings.d" msgid "0.2.15 Added OCI registry authentication" msgstr "0.2.15 Added OCI registry authentication" msgid "" "0.2.15 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.2.15 Distinguish between the port number of the internal endpoint and the " "binding port number" msgid "" "0.2.15 Fix archive-deleted-rows for enabling date command as value for " "before option" msgstr "" "0.2.15 Fix archive-deleted-rows for enabling date command as value for " "before option" msgid "0.2.15 Reduce log chattiness" msgstr "0.2.15 Reduce log chattiness" msgid "0.2.15 Remove glance registry" msgstr "0.2.15 Remove glance registry" msgid "0.2.15 Remove unsupported values overrides" msgstr "0.2.15 Remove unsupported values overrides" msgid "" "0.2.16 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.2.16 Distinguish between the port number of the internal endpoint and the " "binding port number" msgid "0.2.16 Enable taint toleration for Openstack services" msgstr "0.2.16 Enable taint toleration for OpenStack services" msgid "0.2.16 Fix container-infra value" msgstr "0.2.16 Fix container-infra value" msgid "0.2.16 Remove extra fsGroup" msgstr "0.2.16 Remove extra fsGroup" msgid "0.2.16 Remove the policy document in values file" msgstr "0.2.16 Remove the policy document in values file" msgid "0.2.16 Remove usage of six" msgstr "0.2.16 Remove usage of six" msgid "0.2.16 Support TLS endpoints" msgstr "0.2.16 Support TLS endpoints" msgid "0.2.17 Add custom logo" msgstr "0.2.17 Add custom logo" msgid "0.2.17 Fix disablement of helm.sh/hook for Helm v2" msgstr "0.2.17 Fix disablement of helm.sh/hook for Helm v2" msgid "0.2.17 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.2.17 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.2.17 Remove unsupported values overrides" msgstr "0.2.17 Remove unsupported values overrides" msgid "0.2.17 Update default image references" msgstr "0.2.17 Update default image references" msgid "0.2.17 Use HTTP probe instead of TCP probe" msgstr "0.2.17 Use HTTP probe instead of TCP probe" msgid "0.2.18 Add helm hook in bootstrap job" msgstr "0.2.18 Add Helm hook in bootstrap job" msgid "0.2.18 Change hook weight for bootstrap job" msgstr "0.2.18 Change hook weight for bootstrap job" msgid "0.2.18 Enable taint toleration for Openstack services" msgstr "0.2.18 Enable taint toleration for OpenStack services" msgid "0.2.18 Give service time to restore" msgstr "0.2.18 Give service time to restore" msgid "0.2.18 Remove default policy" msgstr "0.2.18 Remove default policy" msgid "0.2.18 Support TLS for ks jobs" msgstr "0.2.18 Support TLS for ks jobs" msgid "0.2.18 Updated naming for subchart compatibility" msgstr "0.2.18 Updated naming for subchart compatibility" msgid "0.2.19 Add volume types visibility (public/private)" msgstr "0.2.19 Add volume types visibility (public/private)" msgid "0.2.19 Added qdhcp NS host validation for deleting wrong namespaces." msgstr "0.2.19 Added qdhcp NS host validation for deleting wrong namespaces." msgid "0.2.19 Define service cleaner sleep time" msgstr "0.2.19 Define service cleaner sleep time" msgid "0.2.19 Remove unsupported value overrides" msgstr "0.2.19 Remove unsupported value overrides" msgid "0.2.19 Revert Reduce log chattiness" msgstr "0.2.19 Revert Reduce log chattiness" msgid "" "0.2.19 Support SSL offloading at reverse proxy for internal and admin " "endpoints" msgstr "" "0.2.19 Support SSL offloading at reverse proxy for internal and admin " "endpoints" msgid "0.2.2 Add Victoria and Wallaby releases support" msgstr "0.2.2 Add Victoria and Wallaby release support" msgid "0.2.2 Add helm hook conditional" msgstr "0.2.2 Add helm hook conditional" msgid "0.2.2 Add helm hook for ks job" msgstr "0.2.2 Add Helm hook for ks job" msgid "0.2.2 Add values for backoffLimit and restartPolicy" msgstr "0.2.2 Add values for backoffLimit and restartPolicy" msgid "0.2.2 Adding rabbitmq TLS logic" msgstr "0.2.2 Adding RabbitMQ TLS logic" msgid "0.2.2 Fix restarting of magnum-conductor pods" msgstr "0.2.2 Fix restarting of magnum-conductor pods" msgid "0.2.2 Make python script PEP8 compliant" msgstr "0.2.2 Make Python script PEP8 compliant" msgid "0.2.2 Update htk requirements repo" msgstr "0.2.2 Update htk requirements repo" msgid "0.2.2 Use policies in yaml format" msgstr "0.2.2 Use policies in yaml format" msgid "0.2.20 Add SHOW_OPENRC_FILE value" msgstr "0.2.20 Add SHOW_OPENRC_FILE value" msgid "0.2.20 Add Xena and Yoga values overrides" msgstr "0.2.20 Add Xena and Yoga values overrides" msgid "0.2.20 Allow cinder v1/v2 endpoint creation if needed" msgstr "0.2.20 Allow Cinder v1/v2 endpoint creation if needed" msgid "0.2.20 Enable taint toleration for Openstack services" msgstr "0.2.20 Enable taint toleration for OpenStack services" msgid "0.2.20 Update script to true of grep does get anything." msgstr "0.2.20 Update script to true of grep does get anything." msgid "0.2.21 Add helm hook annotations in db-sync and db-init jobs" msgstr "0.2.21 Add Helm hook annotations in db-sync and db-init jobs" msgid "0.2.21 Fix for qdhcp NS host validation for deleting wrong namespaces." msgstr "0.2.21 Fix for qdhcp NS host validation for deleting wrong namespaces." msgid "0.2.21 Helm 3 - Fix Job Labels" msgstr "0.2.21 Helm 3 - Fix Job Labels" msgid "" "0.2.21 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgstr "" "0.2.21 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgid "0.2.21 Updated naming for subchart compatibility" msgstr "0.2.21 Updated naming for subchart compatibility" msgid "0.2.22 Add Xena and Yoga values overrides" msgstr "0.2.22 Add Xena and Yoga values overrides" msgid "0.2.22 Fix /run/xtables.lock may be a directory" msgstr "0.2.22 Fix /run/xtables.lock may be a directory" msgid "0.2.22 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.2.22 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.2.22 Remove older values overrides" msgstr "0.2.22 Remove older values overrides" msgid "0.2.22 Update htk requirements repo" msgstr "0.2.22 Update htk requirements repo" msgid "0.2.23 Add Xena and Yoga value overrides" msgstr "0.2.23 Add Xena and Yoga value overrides" msgid "" "0.2.23 Add neutron_netns_cleanup_cron release image override, so that the " "respective release image is used" msgstr "" "0.2.23 Add neutron_netns_cleanup_cron release image override, so that the " "respective release image is used" msgid "0.2.23 Add option to enable extra wait for cell-setup-init" msgstr "0.2.23 Add option to enable extra wait for cell-setup-init" msgid "0.2.23 Added OCI registry authentication" msgstr "0.2.23 Added OCI registry authentication" msgid "0.2.23 Remove usage of six" msgstr "0.2.23 Remove usage of six" msgid "0.2.24 Added OCI registry authentication" msgstr "0.2.24 Added OCI registry authentication" msgid "0.2.24 Fix conditional check for cinder.utils.has_ceph_backend template" msgstr "" "0.2.24 Fix conditional check for cinder.utils.has_ceph_backend template" msgid "0.2.24 Fix nova-bootstrap job labels" msgstr "0.2.24 Fix nova-bootstrap job labels" msgid "0.2.24 Remove blank lines in logo configmap" msgstr "0.2.24 Remove blank lines in logo configmap" msgid "0.2.24 Remove unused admin port in keystone" msgstr "0.2.24 Remove unused admin port in Keystone" msgid "0.2.25 Add check for compute nodes" msgstr "0.2.25 Add check for compute nodes" msgid "0.2.25 Added OCI registry authentication" msgstr "0.2.25 Added OCI registry authentication" msgid "" "0.2.25 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgstr "" "0.2.25 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgid "" "0.2.25 Remove volumes unrelated with ceph backend from conditional volume " "list in cinder-volume deployment" msgstr "" "0.2.25 Remove volumes unrelated with Ceph backend from conditional volume " "list in cinder-volume deployment" msgid "0.2.25 Support TLS endpoints" msgstr "0.2.25 Support TLS endpoints" msgid "0.2.26 Add Xena and Yoga values overrides" msgstr "0.2.26 Add Xena and Yoga values overrides" msgid "" "0.2.26 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.2.26 Distinguish between port number of internal endpoint and binding port " "number" msgid "" "0.2.26 Fix _ssh-init.sh.tpl to copy the ssh keys to the user on the security " "context" msgstr "" "0.2.26 Fix _ssh-init.sh.tpl to copy the ssh keys to the user on the security " "context" msgid "0.2.26 Support SSL identity endpoint" msgstr "0.2.26 Support SSL identity endpoint" msgid "0.2.26 Use HTTP probe instead of TCP probe" msgstr "0.2.26 Use HTTP probe instead of TCP probe" msgid "0.2.27 Add tls1.2 minimum version to tls overrides" msgstr "0.2.27 Add tls1.2 minimum version to TLS overrides" msgid "" "0.2.27 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.2.27 Distinguish between port number of internal endpoint and binding port " "number" msgid "0.2.27 Support TLS endpoints" msgstr "0.2.27 Support TLS endpoints" msgid "0.2.27 Use LOG.warning instead of deprecated LOG.warn" msgstr "0.2.27 Use LOG.warning instead of deprecated LOG.warn" msgid "0.2.28 Added OCI registry authentication" msgstr "0.2.28 Added OCI registry authentication" msgid "0.2.28 Move ssl_minimum_version to console section" msgstr "0.2.28 Move ssl_minimum_version to console section" msgid "0.2.28 Use HTTP probe instead of TCP probe" msgstr "0.2.28 Use HTTP probe instead of TCP probe" msgid "0.2.29 Add SYS_ADMIN capability in cinder-volume" msgstr "0.2.29 Add SYS_ADMIN capability in cinder-volume" msgid "0.2.29 Remove ssh-config" msgstr "0.2.29 Remove ssh-config" msgid "0.2.29 Support TLS endpoints" msgstr "0.2.29 Support TLS endpoints" msgid "0.2.3 Add conductor & health manager" msgstr "0.2.3 Add conductor & health manager" msgid "0.2.3 Add openstack_enable_password_retrieve variable in value" msgstr "0.2.3 Add openstack_enable_password_retrieve variable in value" msgid "0.2.3 Add support for master kek rotation" msgstr "0.2.3 Add support for master kek rotation" msgid "0.2.3 Added helm.sh/hook annotations for Jobs" msgstr "0.2.3 Added helm.sh/hook annotations for Jobs" msgid "0.2.3 Adding rabbitmq TLS logic" msgstr "0.2.3 Adding RabbitMQ TLS logic" msgid "0.2.3 Allow using log_config_append=null" msgstr "0.2.3 Allow using log_config_append=null" msgid "0.2.3 Enable taint toleration for Openstack services" msgstr "0.2.3 Enable taint toleration for OpenStack services" msgid "0.2.3 Fix extra volume mounts" msgstr "0.2.3 Fix extra volume mounts" msgid "0.2.3 Fix logging config" msgstr "0.2.3 Fix logging config" msgid "0.2.3 Mount rabbitmq TLS secret" msgstr "0.2.3 Mount RabbitMQ TLS secret" msgid "" "0.2.3 Replace deprecated configuration ``[vnc]/" "vncserver_proxyclient_address``" msgstr "" "0.2.3 Replace deprecated configuration ``[vnc]/" "vncserver_proxyclient_address``" msgid "0.2.3 Update default imaage values to Wallaby" msgstr "0.2.3 Update default image values to Wallaby" msgid "0.2.3 Update default image values to Wallaby" msgstr "0.2.3 Update default image values to Wallaby" msgid "0.2.3 Update htk requirements repo" msgstr "0.2.3 Update htk requirements repo" msgid "0.2.3 Use policies in yaml format" msgstr "0.2.3 Use policies in yaml format" msgid "" "0.2.30 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.2.30 Distinguish between port number of internal endpoint and binding port " "number" msgid "0.2.30 Improve health probe logging" msgstr "0.2.30 Improve health probe logging" msgid "" "0.2.30 Specify a existing configmap name for external ceph configuration" msgstr "" "0.2.30 Specify a existing configmap name for external Ceph configuration" msgid "" "0.2.31 Remove fixed node name from default values and add service cleaner " "cronjob" msgstr "" "0.2.31 Remove fixed node name from default values and add service cleaner " "cronjob" msgid "0.2.31 Update oslo messaging get_transport" msgstr "0.2.31 Update Oslo messaging get_transport" msgid "0.2.32 Host of ironic compute service equals pod name" msgstr "0.2.32 Host of Ironic compute service equals pod name" msgid "" "0.2.32 Revert \"Remove fixed node name from default values and add service " "cleaner cronjob\"" msgstr "" "0.2.32 Revert \"Remove fixed node name from default values and add service " "cleaner cronjob\"" msgid "0.2.33 Cleanup old releases" msgstr "0.2.33 Cleanup old releases" msgid "0.2.34 Remove consoleauth in nova" msgstr "0.2.34 Remove consoleauth in Nova" msgid "0.2.35 Enable taint toleration for Openstack services" msgstr "0.2.35 Enable taint toleration for OpenStack services" msgid "0.2.36 Support TLS endpoints" msgstr "0.2.36 Support TLS endpoints" msgid "0.2.37 Remove nova-placement" msgstr "0.2.37 Remove nova-placement" msgid "0.2.38 Update nova image defaults" msgstr "0.2.38 Update Nova image defaults" msgid "" "0.2.39 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgstr "" "0.2.39 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgid "0.2.4 Add Ussuri release support" msgstr "0.2.4 Add Ussuri release support" msgid "0.2.4 Fix OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT value" msgstr "0.2.4 Fix OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT value" msgid "0.2.4 Fix transport_url" msgstr "0.2.4 Fix transport_url" msgid "0.2.4 Helm 3 - Fix Job Labels" msgstr "0.2.4 Helm 3 - Fix Job Labels" msgid "" "0.2.4 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgstr "" "0.2.4 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgid "0.2.4 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.2.4 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.2.4 Mount empty temp_cache_dir for performance" msgstr "0.2.4 Mount empty temp_cache_dir for performance" msgid "0.2.4 Mount rabbitmq TLS secret" msgstr "0.2.4 Mount RabbitMQ TLS secret" msgid "0.2.4 Update default image release" msgstr "0.2.4 Update default image release" msgid "0.2.4 Update default image values to Wallaby" msgstr "0.2.4 Update default image values to Wallaby" msgid "0.2.4 Update defaults to W release" msgstr "0.2.4 Update defaults to W release" msgid "0.2.4 Use policies in yaml format" msgstr "0.2.4 Use policies in yaml format" msgid "0.2.40 Updated naming for subchart compatibility" msgstr "0.2.40 Updated naming for subchart compatibility" msgid "0.2.41 Add Xena and Yoga values overrides" msgstr "0.2.41 Add Xena and Yoga values overrides" msgid "0.2.42 Add missing configuration ``[vnc]/novncproxy_host``" msgstr "0.2.42 Add missing configuration ``[vnc]/novncproxy_host``" msgid "0.2.43 Added OCI registry authentication" msgstr "0.2.43 Added OCI registry authentication" msgid "" "0.2.44 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.2.44 Distinguish between port number of internal endpoint and binding port " "number" msgid "0.2.45 Support TLS endpoints for metadata-api" msgstr "0.2.45 Support TLS endpoints for metadata-api" msgid "0.2.46 Use HTTP probe instead of TCP probe" msgstr "0.2.46 Use HTTP probe instead of TCP probe" msgid "0.2.47 Remove list agents rally test" msgstr "0.2.47 Remove list agents rally test" msgid "0.2.5 Add Ussuri release support" msgstr "0.2.5 Add Ussuri release support" msgid "0.2.5 Add Victoria and Wallaby releases support" msgstr "0.2.5 Add Victoria and Wallaby release support" msgid "0.2.5 Add helm hook for jobs" msgstr "0.2.5 Add Helm hook for jobs" msgid "0.2.5 Add volume QoS support" msgstr "0.2.5 Add volume QoS support" msgid "0.2.5 Added OCI registry authentication" msgstr "0.2.5 Added OCI registry authentication" msgid "" "0.2.5 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgstr "" "0.2.5 Migrated CronJob resource to batch/v1 API version & " "PodDisruptionBudget to policy/v1" msgid "0.2.5 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.2.5 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.2.5 Mount rabbitmq TLS secret" msgstr "0.2.5 Mount RabbitMQ TLS secret" msgid "0.2.5 Set reasonable default probe timeouts" msgstr "0.2.5 Set reasonable default probe timeouts" msgid "0.2.5 Update default image values to wallaby" msgstr "0.2.5 Update default image values to Wallaby" msgid "0.2.5 Update htk requirements repo" msgstr "0.2.5 Update htk requirements repo" msgid "0.2.5 Use rootwrap daemon" msgstr "0.2.5 Use rootwrap daemon" msgid "0.2.6 Add Victoria and Wallaby releases support" msgstr "0.2.6 Add Victoria and Wallaby release support" msgid "0.2.6 Add helm.sh/hook annotations for Jobs" msgstr "0.2.6 Add helm.sh/hook annotations for Jobs" msgid "0.2.6 Added OCI registry authentication" msgstr "0.2.6 Added OCI registry authentication" msgid "" "0.2.6 Added cronJob with script for archive deleted rows which cleanup " "databases" msgstr "" "0.2.6 Added cronJob with script for archive deleted rows which cleanup " "databases" msgid "0.2.6 Added helm.sh/hook with value of post-install and post-upgrade" msgstr "0.2.6 Added helm.sh/hook with value of post-install and post-upgrade" msgid "0.2.6 Added post-install and post-upgrade helm-hook for jobs" msgstr "0.2.6 Added post-install and post-upgrade helm-hook for jobs" msgid "0.2.6 Allow Barbican to talk to Mariadb over TLS" msgstr "0.2.6 Allow Barbican to talk to Mariadb over TLS" msgid "0.2.6 Enable taint toleration for Openstack services" msgstr "0.2.6 Enable taint toleration for OpenStack services" msgid "0.2.6 Fix neutron agent-init script" msgstr "0.2.6 Fix Neutron agent-init script" msgid "0.2.6 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.2.6 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.2.6 Modify default probe timings" msgstr "0.2.6 Modify default probe timings" msgid "0.2.6 Remove default policy rules" msgstr "0.2.6 Remove default policy rules" msgid "0.2.6 Support SSL openstack endpoints" msgstr "0.2.6 Support SSL OpenStack endpoints" msgid "0.2.6 Use HTTP probe instead of TCP probe" msgstr "0.2.6 Use HTTP probe instead of TCP probe" msgid "0.2.7 Add Ussuri release support" msgstr "0.2.7 Add Ussuri release support" msgid "0.2.7 Add Victoria and Wallaby releases support" msgstr "0.2.7 Add Victoria and Wallaby release support" msgid "0.2.7 Add configuration for heat-tempest-plugin" msgstr "0.2.7 Add configuration for heat-tempest-plugin" msgid "0.2.7 Add helm hook annotations for db-sync job" msgstr "0.2.7 Add Helm hook annotations for db-sync job" msgid "0.2.7 Added OCI registry authentication" msgstr "0.2.7 Added OCI registry authentication" msgid "0.2.7 Added helm.sh/hook for the jobs" msgstr "0.2.7 Added helm.sh/hook for the jobs" msgid "0.2.7 Fix OPENSTACK_ENABLE_PASSWORD_RETRIEVE value" msgstr "0.2.7 Fix OPENSTACK_ENABLE_PASSWORD_RETRIEVE value" msgid "0.2.7 Fix db connection key name" msgstr "0.2.7 Fix db connection key name" msgid "0.2.7 Helm 3 - Fix Job Labels" msgstr "0.2.7 Helm 3 - Fix Job Labels" msgid "0.2.7 Made dnsmasq.conf overridable in configmap-bin" msgstr "0.2.7 Made dnsmasq.conf overridable in configmap-bin" msgid "0.2.7 Remove default policy rules" msgstr "0.2.7 Remove default policy rules" msgid "0.2.7 Support TLS for identity endpoint" msgstr "0.2.7 Support TLS for identity endpoint" msgid "0.2.7 Use HTTP probe instead of TCP probe" msgstr "0.2.7 Use HTTP probe instead of TCP probe" msgid "0.2.8 Add Victoria and Wallaby releases support" msgstr "0.2.8 Add Victoria and Wallaby release support" msgid "0.2.8 Add default polices" msgstr "0.2.8 Add default policies" msgid "0.2.8 Add helm3 hook supports to allow things like terraform deploys" msgstr "0.2.8 Add helm3 hook supports to allow things like Terraform deploys" msgid "0.2.8 Add logic to bootstrap to handle upgrade timing issue" msgstr "0.2.8 Add logic to bootstrap to handle upgrade timing issue" msgid "" "0.2.8 Fix the cron archive_deleted_rows bash script for before and max-rows " "values" msgstr "" "0.2.8 Fix the cron archive_deleted_rows bash script for before and max-rows " "values" msgid "0.2.8 Helm 3 - Fix Job Labels" msgstr "0.2.8 Helm 3 - Fix Job Labels" msgid "0.2.8 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.2.8 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.2.8 Remove default policy rules" msgstr "0.2.8 Remove default policy rules" msgid "0.2.8 Remove member bootstrap logic" msgstr "0.2.8 Remove member bootstrap logic" msgid "0.2.8 Update htk requirements repo" msgstr "0.2.8 Update htk requirements repo" msgid "0.2.9 Add Victoria and Wallaby releases support" msgstr "0.2.9 Add Victoria and Wallaby releases support" msgid "0.2.9 Add Xena and Yoga values overrides" msgstr "0.2.9 Add Xena and Yoga values overrides" msgid "0.2.9 Add image clean up to rally test" msgstr "0.2.9 Add image clean-up to rally test" msgid "0.2.9 Add option to disable helm.sh/hook annotations" msgstr "0.2.9 Add option to disable helm.sh/hook annotations" msgid "0.2.9 Enable taint toleration for Openstack services" msgstr "0.2.9 Enable taint toleration for OpenStack services" msgid "0.2.9 Helm 3 - Fix More Job Labels" msgstr "0.2.9 Helm 3 - Fix More Job Labels" msgid "0.2.9 Mount rabbitmq TLS secret for audit usage cronjob" msgstr "0.2.9 Mount RabbitMQ TLS secret for audit usage cronjob" msgid "" "0.2.9 Removed default policy in chart in favor of default policy in code" msgstr "" "0.2.9 Removed default policy in chart in favour of default policy in code" msgid "0.2.9 Removed default policy in favor in code policy" msgstr "0.2.9 Removed default policy in favour in code policy" msgid "0.3.0 Remove glance registry" msgstr "0.3.0 Remove Glance registry" msgid "0.3.0 Remove placement-migrate" msgstr "0.3.0 Remove placement-migrate" msgid "0.3.0 Remove support for Train and Ussuri" msgstr "0.3.0 Remove support for Train and Ussuri" msgid "0.3.1 Added backoffLimit for bootstrap job" msgstr "0.3.1 Added backoffLimit for bootstrap job" msgid "0.3.1 Change ceph-config-helper image tag" msgstr "0.3.1 Change ceph-config-helper image tag" msgid "0.3.1 Enable taint toleration for Openstack services" msgstr "0.3.1 Enable taint toleration for OpenStack services" msgid "0.3.1 Fix container infra api version in values" msgstr "0.3.1 Fix container infra api version in values" msgid "0.3.1 Remove default policy rules" msgstr "0.3.1 Remove default policy rules" msgid "0.3.1 Remove support for Train and Ussuri" msgstr "0.3.1 Remove support for Train and Ussuri" msgid "" "0.3.10 Distinguish between port number of internal endpoint and binding port " "number" msgstr "" "0.3.10 Distinguish between port number of internal endpoint and binding port " "number" msgid "0.3.11 Use HTTP probe instead of TCP probe" msgstr "0.3.11 Use HTTP probe instead of TCP probe" msgid "0.3.12 Add support for using Cinder as backend" msgstr "0.3.12 Add support for using Cinder as a backend" msgid "0.3.2 Decrease terminationGracePeriodSeconds on glance-api" msgstr "0.3.2 Decrease terminationGracePeriodSeconds on Glance-api" msgid "0.3.2 Remove default policy rules" msgstr "0.3.2 Remove default policy rules" msgid "0.3.2 Update mysql client version to 1.4.0" msgstr "0.3.2 Update MySQL client version to 1.4.0" msgid "" "0.3.2 Use correct labels for ovs which uses one daemonset for ovs-db and ovs-" "vswitchd" msgstr "" "0.3.2 Use correct labels for ovs which uses one daemonset for ovs-db and ovs-" "vswitchd" msgid "0.3.3 Fix for creation endpoins and services when v1/v2 are disabled" msgstr "0.3.3 Fix for creation endpoins and services when v1/v2 are disabled" msgid "0.3.3 Update naming for subchart compatibility" msgstr "0.3.3 Update naming for subchart compatibility" msgid "0.3.4 Change image default version to wallaby" msgstr "0.3.4 Change image default version to wallaby" msgid "0.3.5 Migrated PodDisruptionBudget resource to policy/v1 API version" msgstr "0.3.5 Migrated PodDisruptionBudget resource to policy/v1 API version" msgid "0.3.6 Add Xena and Yoga values overrides" msgstr "0.3.6 Add Xena and Yoga values overrides" msgid "" "0.3.7 Fix glance-etc template changing due to comment and whitespace between " "install and first upgrade" msgstr "" "0.3.7 Fix glance-etc template changing due to comment and whitespace between " "install and first upgrade" msgid "0.3.8 Added OCI registry authentication" msgstr "0.3.8 Added OCI registry authentication" msgid "0.3.9 Support TLS endpoints" msgstr "0.3.9 Support TLS endpoints" msgid "0.4.0 Remove support for Train and Ussuri" msgstr "0.4.0 Remove support for Train and Ussuri" msgid "0.4.1 Remove default policy rules" msgstr "0.4.1 Remove default policy rules" msgid "Current Series Release Notes" msgstr "Current Series Release Notes" msgid "OpenStack-Helm Release Notes" msgstr "OpenStack-Helm Release Notes" msgid "aodh Chart" msgstr "aodh Chart" msgid "barbican Chart" msgstr "barbican Chart" msgid "ceilometer Chart" msgstr "ceilometer Chart" msgid "cinder Chart" msgstr "cinder Chart" msgid "designate Chart" msgstr "designate Chart" msgid "glance Chart" msgstr "glance Chart" msgid "heat Chart" msgstr "heat Chart" msgid "horizon Chart" msgstr "horizon Chart" msgid "ironic Chart" msgstr "ironic Chart" msgid "keystone Chart" msgstr "keystone Chart" msgid "magnum Chart" msgstr "magnum Chart" msgid "mistral Chart" msgstr "mistral Chart" msgid "neutron Chart" msgstr "neutron Chart" msgid "nova Chart" msgstr "nova Chart" msgid "octavia Chart" msgstr "octavia Chart" msgid "placement Chart" msgstr "placement Chart" msgid "rally Chart" msgstr "rally Chart" msgid "senlin Chart" msgstr "senlin Chart" msgid "tempest Chart" msgstr "tempest Chart" ================================================ FILE: roles/build-helm-packages/defaults/main.yml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- version: helm: v3.12.2 url: helm_repo: https://get.helm.sh ... ================================================ FILE: roles/build-helm-packages/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - include: setup-helm-serve.yaml - name: build all charts in repo make: chdir: "{{ work_dir }}" target: all ... ================================================ FILE: roles/build-helm-packages/tasks/setup-helm-serve.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - block: - name: check if correct version of helm client already installed shell: "set -e; [ \"x$($(type -p helm) version --client --short | awk '{ print $NF }' | awk -F '+' '{ print $1 }')\" == \"x${HELM_VERSION}\" ] || exit 1" environment: HELM_VERSION: "{{ version.helm }}" args: executable: /bin/bash register: need_helm ignore_errors: True - name: install helm client when: need_helm is failed become_user: root shell: | TMP_DIR=$(mktemp -d) curl -sSL ${HELM_REPO_URL}/helm-${HELM_VERSION}-linux-amd64.tar.gz | tar -zxv --strip-components=1 -C ${TMP_DIR} sudo mv ${TMP_DIR}/helm /usr/bin/helm rm -rf ${TMP_DIR} environment: HELM_VERSION: "{{ version.helm }}" HELM_REPO_URL: "{{ url.helm_repo }}" args: executable: /bin/bash - name: setting up helm client command: helm init --client-only --skip-refresh --stable-repo-url "https://charts.helm.sh/stable" - block: - name: checking if local helm server is running shell: curl -s 127.0.0.1:8879 | grep -q 'Helm Repository' args: executable: /bin/bash register: helm_server_running ignore_errors: True - name: getting current host user name when: helm_server_running is failed shell: id -un args: executable: /bin/bash register: helm_server_user - name: moving systemd unit into place for helm server when: helm_server_running is failed become: yes become_user: root template: src: helm-serve.service.j2 dest: /etc/systemd/system/helm-serve.service mode: 416 - name: starting helm serve service when: helm_server_running is failed become: yes become_user: root systemd: state: restarted daemon_reload: yes name: helm-serve enabled: yes - name: wait for helm server to be ready shell: curl -s 127.0.0.1:8879 | grep -q 'Helm Repository' args: executable: /bin/bash register: wait_for_helm_server until: wait_for_helm_server.rc == 0 retries: 120 delay: 5 - block: - name: checking if helm 'stable' repo is present shell: helm repo list | grep -q "^stable" args: executable: /bin/bash register: helm_stable_repo_present ignore_errors: True - name: remove helm 'stable' repo when exists when: helm_stable_repo_present is succeeded command: helm repo remove stable - name: adding helm local repo command: helm repo add local http://localhost:8879/charts ... ================================================ FILE: roles/build-helm-packages/templates/helm-serve.service.j2 ================================================ [Unit] Description=Helm Server After=network.target [Service] User={{ helm_server_user.stdout }} Restart=always ExecStart=/usr/bin/helm serve [Install] WantedBy=multi-user.target ================================================ FILE: roles/chart-testing/README.rst ================================================ Run chart-testing (for helm charts) **Role Variables** .. zuul:rolevar:: zuul_work_dir :default: {{ zuul.project.src_dir }} The location of the main working directory of the job. .. zuul:rolevar:: chart_testing_options :default: --validate-maintainers=false --check-version-increment=false Arguments passed to chart testing. The defaults are suitable for a Zuul environment because `validate-maintainers` requires a valid git remote (which is not present in Zuul) and `check-version-increment` requires each commit to have a new version; Zuul users are expected to set the version when tagging/publishing a release. ================================================ FILE: roles/chart-testing/defaults/main.yaml ================================================ zuul_work_dir: "{{ zuul.project.src_dir }}" chart_testing_options: --validate-maintainers=false --check-version-increment=false virtualenv: "{{ ansible_user_dir }}/venv" ================================================ FILE: roles/chart-testing/tasks/main.yaml ================================================ - name: Run chart-testing shell: | source "{{ virtualenv }}/bin/activate" ct lint {{ chart_testing_options }} args: chdir: "{{ zuul_work_dir }}" executable: /bin/bash ================================================ FILE: roles/clean-host/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: remove osh directory become: yes become_user: root file: path: "{{ item }}" state: absent with_items: - /var/lib/openstack-helm ... ================================================ FILE: roles/deploy-apparmor/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - block: - name: ensuring AppArmor is deployed on host when: ansible_distribution == 'Ubuntu' include_role: name: deploy-package tasks_from: dist vars: packages: deb: - apparmor - name: "Enable AppArmor" when: ansible_distribution == 'Ubuntu' become: true become_user: root shell: |- set -xe systemctl enable apparmor systemctl start apparmor systemctl status apparmor.service args: executable: /bin/bash ignore_errors: True ... ================================================ FILE: roles/deploy-docker/defaults/main.yml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- proxy: http: null https: null noproxy: null ... ================================================ FILE: roles/deploy-docker/tasks/deploy-ansible-docker-support.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: ensuring SELinux is disabled on centos & fedora when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' or ansible_distribution == 'Fedora' become: true become_user: root command: setenforce 0 ignore_errors: True # NOTE(portdirect): See https://ask.openstack.org/en/question/110437/importerror-cannot-import-name-unrewindablebodyerror/ - name: fix docker removal issue with ansible's docker_container on centos when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' block: - name: remove requests and urllib3 distro packages to fix docker removal issue with ansible's docker_container on centos include_role: name: deploy-package tasks_from: dist vars: state: absent packages: rpm: - python-urllib3 - python-requests - name: restore requests and urllib3 distro packages to fix docker removal issue with ansible's docker_container on centos include_role: name: deploy-package tasks_from: dist vars: state: present packages: rpm: - python-urllib3 - python-requests - name: install additional packages include_role: name: deploy-package tasks_from: dist vars: state: present packages: deb: - conntrack - bc - nmap rpm: - conntrack-tools - bc - nmap - name: Ensure docker python packages deployed include_role: name: deploy-package tasks_from: pip vars: packages: - docker ... ================================================ FILE: roles/deploy-docker/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: setting default limit memlock shell: | set -xe; echo "DefaultLimitMEMLOCK=16777216" | sudo tee -a /etc/systemd/system.conf sudo systemctl daemon-reexec sudo systemctl daemon-reload - name: check if docker deploy is needed raw: which docker register: need_docker ignore_errors: True - name: centos | moving systemd unit into place when: ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) and ( need_docker is failed ) template: src: centos-docker.service.j2 dest: /etc/systemd/system/docker.service mode: 416 - name: fedora | moving systemd unit into place when: ( ansible_distribution == 'Fedora' ) and ( need_docker is failed ) template: src: fedora-docker.service.j2 dest: /etc/systemd/system/docker.service mode: 416 - name: ubuntu | moving systemd unit into place when: ( ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' ) and ( need_docker is failed ) template: src: ubuntu-docker.service.j2 dest: /etc/systemd/system/docker.service mode: 416 # NOTE: (lamt) Setting up the proxy before installing docker - name: ensure docker.service.d directory exists when: proxy.http file: path: /etc/systemd/system/docker.service.d state: directory - name: proxy | moving proxy systemd unit into place when: proxy.http template: src: http-proxy.conf.j2 dest: /etc/systemd/system/docker.service.d/http-proxy.conf mode: 416 - name: deploy docker packages when: need_docker is failed include_role: name: deploy-package tasks_from: dist vars: packages: deb: - docker.io rpm: - docker - name: restarting docker systemd: state: restarted daemon_reload: yes name: docker - include: deploy-ansible-docker-support.yaml ... ================================================ FILE: roles/deploy-docker/templates/centos-docker.service.j2 ================================================ [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.com After=network.target [Service] Type=notify NotifyAccess=all Environment=GOTRACEBACK=crash Environment=DOCKER_HTTP_HOST_COMPAT=1 Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin ExecStart=/usr/bin/dockerd-current \ --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \ --default-runtime=docker-runc \ --exec-opt native.cgroupdriver=systemd \ --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \ --seccomp-profile=/etc/docker/seccomp.json \ --graph=/var/lib/docker \ --storage-driver=overlay2 \ --log-driver=json-file \ --iptables=false # NOTE(portdirect): fix mount propagation for CentOS, this is done post start, # as docker seems to reset this. ExecStartPost=/usr/bin/mount --make-rshared / ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=1048576 LimitNPROC=1048576 LimitCORE=infinity TimeoutStartSec=0 Restart=on-abnormal MountFlags=share KillMode=process [Install] WantedBy=multi-user.target ================================================ FILE: roles/deploy-docker/templates/fedora-docker.service.j2 ================================================ [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.com After=network.target docker-containerd.service Requires=docker-containerd.service [Service] Type=notify Environment=GOTRACEBACK=crash ExecStart=/usr/bin/dockerd-current \ --add-runtime oci=/usr/libexec/docker/docker-runc-current \ --default-runtime=oci \ --containerd /run/containerd.sock \ --exec-opt native.cgroupdriver=systemd \ --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \ --init-path=/usr/libexec/docker/docker-init-current \ --seccomp-profile=/etc/docker/seccomp.json \ --graph=/var/lib/docker \ --storage-driver=overlay2 \ --log-driver=json-file \ --iptables=false # NOTE(portdirect): fix mount propagation for Fedora, this is done post start, # as docker seems to reset this. ExecStartPost=/usr/bin/mount --make-rshared / ExecReload=/bin/kill -s HUP $MAINPID TasksMax=8192 LimitNOFILE=1048576 LimitNPROC=1048576 LimitCORE=infinity TimeoutStartSec=0 Restart=on-abnormal [Install] WantedBy=multi-user.target ================================================ FILE: roles/deploy-docker/templates/http-proxy.conf.j2 ================================================ [Service] Environment="HTTP_PROXY={{ proxy.http }}" Environment="HTTPS_PROXY={{ proxy.https }}" Environment="NO_PROXY={{ proxy.noproxy }}" ================================================ FILE: roles/deploy-docker/templates/ubuntu-docker.service.j2 ================================================ [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network.target docker.socket firewalld.service Requires=docker.socket [Service] Type=notify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not support the cgroup feature set required # for containers run by docker EnvironmentFile=-/etc/default/docker ExecStart=/usr/bin/dockerd --iptables=false -H fd:// $DOCKER_OPTS ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=1048576 # Having non-zero Limit*s causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container-local accounting. LimitNPROC=infinity LimitCORE=infinity # Uncomment TasksMax if your systemd version supports it. # Only systemd 226 and above support this version. TasksMax=infinity TimeoutStartSec=0 # set delegate yes so that systemd does not reset the cgroups of docker containers Delegate=yes # kill only the docker process, not all processes in the cgroup KillMode=process [Install] WantedBy=multi-user.target ================================================ FILE: roles/deploy-env/README.md ================================================ This role is used to deploy test environment which includes - install necessary prerequisites including Helm - deploy Containerd and a container runtime for Kubernetes - deploy Kubernetes using Kubeadm with a single control plane node - install Calico as a Kubernetes networking - establish tunnel between primary node and K8s control plane ndoe The role works both for single-node and multi-node inventories. The role totally relies on inventory groups. The `primary` and `k8s_control_plane` groups must include only one node and this can be the same node for these two groups. The `primary` group is where we install `kubectl` and `helm` CLI tools. You can consider this group as a deployer's machine. The `k8s_control_plane` is where we deploy the K8s control plane. The `k8s_cluster` group must include all the K8s nodes including control plane and worker nodes. In case of running tests on a single-node environment the group `k8s_nodes` must be empty. This means the K8s cluster will consist of a single control plane node where all the workloads will be running. See for example: ```yaml all: vars: ansible_port: 22 ansible_user: ubuntu ansible_ssh_private_key_file: /home/ubuntu/.ssh/id_rsa ansible_ssh_extra_args: -o StrictHostKeyChecking=no hosts: primary: ansible_host: 10.10.10.10 node-1: ansible_host: 10.10.10.11 node-2: ansible_host: 10.10.10.12 node-3: ansible_host: 10.10.10.13 children: primary: hosts: primary: k8s_cluster: hosts: node-1: node-2: node-3: k8s_control_plane: hosts: node-1: k8s_nodes: hosts: node-2: node-3: ``` ================================================ FILE: roles/deploy-env/defaults/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- kube_version_repo: "v1.35" # the list of k8s package versions are available here # https://pkgs.k8s.io/core:/stable:/{{ kube_version_repo }}/deb/Packages kube_version: "1.35.0-1.1" helm_version: "4.1.1" crictl_version: "v1.35.0" calico_setup: true calico_version: "v3.31.3" calico_manifest_url: "https://raw.githubusercontent.com/projectcalico/calico/{{ calico_version }}/manifests/calico.yaml" cilium_setup: false cilium_version: "1.17.4" flannel_setup: false flannel_version: v0.26.7 gatewayapi_setup: true gatewayapi_implementation: "envoy" # options: envoy gatewayapi_envoy_version: "v1.7.0" ingress_setup: false ingress_implementation: "haproxy" # options: haproxy, nginx ingress_nginx_version: "4.12.2" ingress_haproxy_version: "0.15.0" ingress_openstack_setup: true ingress_ceph_setup: true ingress_osh_infra_setup: false kubectl: user: zuul group: zuul osh_plugin_repo: "https://opendev.org/openstack/openstack-helm-plugin.git" kubeadm: pod_network_cidr: "10.244.0.0/16" service_cidr: "10.96.0.0/16" docker: root_path: /var/lib/docker docker_users: - zuul containerd: root_path: /var/lib/containerd loopback_setup: false loopback_device: /dev/loop100 loopback_image: /var/lib/openstack-helm/ceph-loop.img loopback_image_size: 12G loopback_format: false loopback_format_fs_type: ext4 loopback_mount: false loopback_mount_path: /srv/node/loop100 coredns_resolver_setup: false coredns_dns_server: "8.8.8.8" # This will be appended to the Corefile after the main configuration block # Example: | # example.com:53 { # forward . 1.2.3.4 # } coredns_extra_config: "" metallb_setup: true metallb_version: "0.15.3" metallb_pool_cidr: "172.24.128.0/24" metallb_ingress_openstack_endpoint_cidr: "172.24.128.100/24" metallb_ingress_osh_infra_endpoint_cidr: "172.24.128.101/24" metallb_gatewayapi_endpoint_cidr: "172.24.128.102/24" client_cluster_ssh_setup: true client_ssh_user: zuul cluster_ssh_user: zuul floating_network_setup: false floating_network_cidr: "172.24.4.0/24" floating_network_gateway_cidr: "172.24.4.1/24" tcpproxy_cidr: "172.24.6.0/24" tcpproxy_gatewayapi_cidr: "172.24.6.1/24" tcpproxy_ingress_openstack_cidr: "172.24.6.2/24" tunnel_network_cidr: "172.24.5.0/24" tunnel_client_cidr: "172.24.5.2/24" tunnel_cluster_cidr: "172.24.5.1/24" dnsmasq_image: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" dnsmasq_dns_server: "8.8.8.8" dnsmasq_extra_args: "" nginx_image: "quay.io/airshipit/nginx:alpine3.18" overlay_network_setup: true overlay_network_prefix: "10.248.0." overlay_network_vxlan_iface: vxlan42 overlay_network_vxlan_id: 42 # NOTE: This is to avoid conflicts with the vxlan overlay managed by Openstack # which uses 4789 by default. Some alternative implementations used to # leverage 8472, so let's use it. overlay_network_vxlan_port: 8472 overlay_network_bridge_name: brvxlan overlay_network_bridge_ip: "{{ overlay_network_prefix }}{{ (groups['all'] | sort).index(inventory_hostname) + 1 }}" overlay_network_underlay_dev: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['interface'] }}" ... ================================================ FILE: roles/deploy-env/files/calico_patch.yaml ================================================ --- spec: template: spec: containers: - name: calico-node env: # we need Calico to skip this interface while discovering the # network changes on the host to prevent announcing unnecessary networks. - name: IP_AUTODETECTION_METHOD value: "skip-interface=br-ex|tcpproxy.*|provider.*|client.*|o-hm.*|o-w.*" ... ================================================ FILE: roles/deploy-env/files/cluster_resolv.conf ================================================ nameserver 10.96.0.10 ================================================ FILE: roles/deploy-env/files/containerd_config.toml ================================================ disabled_plugins = [] imports = [] oom_score = 0 plugin_dir = "" required_plugins = [] root = "{{ containerd.root_path }}" state = "/run/containerd" temp = "" version = 2 [cgroup] path = "" [debug] address = "" format = "" gid = 0 level = "" uid = 0 [grpc] address = "/run/containerd/containerd.sock" gid = 0 max_recv_message_size = 16777216 max_send_message_size = 16777216 tcp_address = "" tcp_tls_ca = "" tcp_tls_cert = "" tcp_tls_key = "" uid = 0 [metrics] address = "" grpc_histogram = false [plugins] [plugins."io.containerd.gc.v1.scheduler"] deletion_threshold = 0 mutation_threshold = 100 pause_threshold = 0.02 schedule_delay = "0s" startup_delay = "100ms" [plugins."io.containerd.grpc.v1.cri"] device_ownership_from_security_context = false disable_apparmor = false disable_cgroup = false disable_hugetlb_controller = true disable_proc_mount = false disable_tcp_service = true enable_selinux = false enable_tls_streaming = false enable_unprivileged_icmp = false enable_unprivileged_ports = false ignore_image_defined_volumes = false max_concurrent_downloads = 3 max_container_log_line_size = 16384 netns_mounts_under_state_dir = false restrict_oom_score_adj = false sandbox_image = "registry.k8s.io/pause:3.9" selinux_category_range = 1024 stats_collect_period = 10 stream_idle_timeout = "4h0m0s" stream_server_address = "127.0.0.1" stream_server_port = "0" systemd_cgroup = false tolerate_missing_hugetlb_controller = true unset_seccomp_profile = "" [plugins."io.containerd.grpc.v1.cri".cni] bin_dir = "/opt/cni/bin" conf_dir = "/etc/cni/net.d" conf_template = "" ip_pref = "" max_conf_num = 1 [plugins."io.containerd.grpc.v1.cri".containerd] default_runtime_name = "runc" disable_snapshot_annotations = true discard_unpacked_layers = false ignore_rdt_not_enabled_errors = false no_pivot = false snapshotter = "overlayfs" [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime] base_runtime_spec = "" cni_conf_dir = "" cni_max_conf_num = 0 container_annotations = [] pod_annotations = [] privileged_without_host_devices = false runtime_engine = "" runtime_path = "" runtime_root = "" runtime_type = "" [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime.options] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] base_runtime_spec = "" cni_conf_dir = "" cni_max_conf_num = 0 container_annotations = [] pod_annotations = [] privileged_without_host_devices = false runtime_engine = "" runtime_path = "" runtime_root = "" runtime_type = "io.containerd.runc.v2" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] BinaryName = "" CriuImagePath = "" CriuPath = "" CriuWorkPath = "" IoGid = 0 IoUid = 0 NoNewKeyring = false NoPivotRoot = false Root = "" ShimCgroup = "" SystemdCgroup = true [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime] base_runtime_spec = "" cni_conf_dir = "" cni_max_conf_num = 0 container_annotations = [] pod_annotations = [] privileged_without_host_devices = false runtime_engine = "" runtime_path = "" runtime_root = "" runtime_type = "" [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime.options] [plugins."io.containerd.grpc.v1.cri".image_decryption] key_model = "node" [plugins."io.containerd.grpc.v1.cri".registry] config_path = "/etc/containerd/certs.d" [plugins."io.containerd.grpc.v1.cri".registry.auths] [plugins."io.containerd.grpc.v1.cri".registry.configs] {% for item in registry_namespaces %} {% if item.auth is defined %} [plugins."io.containerd.grpc.v1.cri".registry.configs."{{ item.namespace }}".auth] auth = "{{ item.auth }}" {% endif %} {% endfor %} [plugins."io.containerd.grpc.v1.cri".registry.headers] [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming] tls_cert_file = "" tls_key_file = "" [plugins."io.containerd.internal.v1.opt"] path = "/opt/containerd" [plugins."io.containerd.internal.v1.restart"] interval = "10s" [plugins."io.containerd.internal.v1.tracing"] sampling_ratio = 1.0 service_name = "containerd" [plugins."io.containerd.metadata.v1.bolt"] content_sharing_policy = "shared" [plugins."io.containerd.monitor.v1.cgroups"] no_prometheus = false [plugins."io.containerd.runtime.v1.linux"] no_shim = false runtime = "runc" runtime_root = "" shim = "containerd-shim" shim_debug = false [plugins."io.containerd.runtime.v2.task"] platforms = ["linux/amd64"] sched_core = false [plugins."io.containerd.service.v1.diff-service"] default = ["walking"] [plugins."io.containerd.service.v1.tasks-service"] rdt_config_file = "" [plugins."io.containerd.snapshotter.v1.aufs"] root_path = "" [plugins."io.containerd.snapshotter.v1.btrfs"] root_path = "" [plugins."io.containerd.snapshotter.v1.devmapper"] async_remove = false base_image_size = "" discard_blocks = false fs_options = "" fs_type = "" pool_name = "" root_path = "" [plugins."io.containerd.snapshotter.v1.native"] root_path = "" [plugins."io.containerd.snapshotter.v1.overlayfs"] root_path = "" upperdir_label = false [plugins."io.containerd.snapshotter.v1.zfs"] root_path = "" [plugins."io.containerd.tracing.processor.v1.otlp"] endpoint = "" insecure = false protocol = "" [proxy_plugins] [stream_processors] [stream_processors."io.containerd.ocicrypt.decoder.v1.tar"] accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"] args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] path = "ctd-decoder" returns = "application/vnd.oci.image.layer.v1.tar" [stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"] accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"] args = ["--decryption-keys-path", "/etc/containerd/ocicrypt/keys"] env = ["OCICRYPT_KEYPROVIDER_CONFIG=/etc/containerd/ocicrypt/ocicrypt_keyprovider.conf"] path = "ctd-decoder" returns = "application/vnd.oci.image.layer.v1.tar+gzip" [timeouts] "io.containerd.timeout.bolt.open" = "0s" "io.containerd.timeout.shim.cleanup" = "5s" "io.containerd.timeout.shim.load" = "5s" "io.containerd.timeout.shim.shutdown" = "3s" "io.containerd.timeout.task.state" = "2s" [ttrpc] address = "" gid = 0 uid = 0 ================================================ FILE: roles/deploy-env/files/daemon.json ================================================ { "data-root": "{{ docker.root_path }}", "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, {% if registry_mirror is defined %} "registry-mirrors": ["{{ registry_mirror }}"], {% endif %} {% if insecure_registries is defined %} "insecure-registries": ["{{ insecure_registries }}"], {% endif %} "storage-driver": "overlay2", "live-restore": true } ================================================ FILE: roles/deploy-env/files/etc_default_kubelet.j2 ================================================ KUBELET_EXTRA_ARGS="{% if overlay_network_setup %}--node-ip {{ overlay_network_bridge_ip }}{% endif %}" ================================================ FILE: roles/deploy-env/files/hosts ================================================ 127.0.0.1 localhost {{ ansible_default_ipv4['address'] }} {{ ansible_hostname }} {% if buildset_registry is defined and (buildset_registry.host | ipaddr) %} {{ buildset_registry.host }} zuul-jobs.buildset-registry {% endif %} ================================================ FILE: roles/deploy-env/files/hosts.toml ================================================ {% if item.skip_server is not defined or not item.skip_server %} server = "{{ item.server | default('https://' + item.namespace) }}" {% endif %} [host."{{ item.mirror }}"] capabilities = ["pull", "resolve", "push"] {% if item.ca is defined %} ca = "{{ item.ca }}" {% endif %} {% if item.skip_verify is defined and item.skip_verify %} skip_verify = true {% endif %} ================================================ FILE: roles/deploy-env/files/kubeadm_config.yaml.j2 ================================================ --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs ipvs: strictARP: true ... --- apiVersion: kubeadm.k8s.io/v1beta4 kind: ClusterConfiguration networking: serviceSubnet: "{{ kubeadm.service_cidr }}" # --service-cidr podSubnet: "{{ kubeadm.pod_network_cidr }}" # --pod-network-cidr dnsDomain: "cluster.local" apiServer: ControlPlaneComponent: extraArgs: - name: kubelet-preferred-address-types value: "InternalIP,Hostname,InternalDNS,ExternalIP,ExternalDNS" ... --- apiVersion: kubeadm.k8s.io/v1beta4 kind: InitConfiguration nodeRegistration: criSocket: unix:///run/containerd/containerd.sock taints: [] ignorePreflightErrors: - NumCPU localAPIEndpoint: {% if overlay_network_setup %} advertiseAddress: "{{ overlay_network_prefix }}{{ (groups['all'] | sort).index(groups['k8s_control_plane'][0]) + 1 }}" {% endif %} bindPort: 6443 ... --- apiVersion: kubeadm.k8s.io/v1beta4 kind: JoinConfiguration nodeRegistration: criSocket: unix:///run/containerd/containerd.sock taints: [] ignorePreflightErrors: - NumCPU ... ================================================ FILE: roles/deploy-env/files/loop-setup.service ================================================ [Unit] Description=Setup loop devices DefaultDependencies=no Conflicts=umount.target Before=local-fs.target After=systemd-udevd.service Requires=systemd-udevd.service [Service] Type=oneshot ExecStart=/sbin/losetup {{ loopback_device }} '{{ loopback_image }}' ExecStop=/sbin/losetup -d {{ loopback_device }} TimeoutSec=60 RemainAfterExit=yes [Install] WantedBy=local-fs.target Also=systemd-udevd.service ================================================ FILE: roles/deploy-env/files/nginx_tcp_proxy.conf ================================================ user nginx; worker_processes auto; error_log /dev/stdout warn; pid /var/run/nginx.pid; events { worker_connections 1024; } stream { access_log off; # Ingress controller proxy (for services not using Gateway API) server { listen {{ tcpproxy_ingress_openstack_cidr | ipaddr('address') }}:80; proxy_pass {{ metallb_ingress_openstack_endpoint_cidr | ipaddr('address') }}:80; proxy_bind {{ tcpproxy_ingress_openstack_cidr | ipaddr('address') }} transparent; } server { listen {{ tcpproxy_ingress_openstack_cidr | ipaddr('address') }}:443; proxy_pass {{ metallb_ingress_openstack_endpoint_cidr | ipaddr('address') }}:443; proxy_bind {{ tcpproxy_ingress_openstack_cidr | ipaddr('address') }} transparent; } # Gateway API proxy (for services using HTTPRoute) server { listen {{ tcpproxy_gatewayapi_cidr | ipaddr('address') }}:80; proxy_pass {{ metallb_gatewayapi_endpoint_cidr | ipaddr('address') }}:80; proxy_bind {{ tcpproxy_gatewayapi_cidr | ipaddr('address') }} transparent; } server { listen {{ tcpproxy_gatewayapi_cidr | ipaddr('address') }}:443; proxy_pass {{ metallb_gatewayapi_endpoint_cidr | ipaddr('address') }}:443; proxy_bind {{ tcpproxy_gatewayapi_cidr | ipaddr('address') }} transparent; } } ================================================ FILE: roles/deploy-env/files/resolv.conf ================================================ nameserver {{ nameserver_ip }} ================================================ FILE: roles/deploy-env/files/ssh_config ================================================ StrictHostKeyChecking no ================================================ FILE: roles/deploy-env/handlers/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Systemd reload shell: systemctl daemon-reload - name: Restart loop-setup service: name: loop-setup state: started ... ================================================ FILE: roles/deploy-env/tasks/buildset_registry_alias.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Set buildset_registry alias variable when using ip set_fact: buildset_registry_alias: zuul-jobs.buildset-registry when: - buildset_registry.host | ipaddr - name: Set buildset_registry alias variable when using name set_fact: buildset_registry_alias: "{{ buildset_registry.host }}" when: - not ( buildset_registry.host | ipaddr ) ... ================================================ FILE: roles/deploy-env/tasks/calico.yaml ================================================ --- # We download Calico manifest on all nodes because we then want to download # Calico images BEFORE deploying it, so that `kubectl wait` timeout # for `k8s-app=kube-dns` isn't reached by slow download speeds - name: Prepare Calico configuration become: false block: - name: Download Calico manifest get_url: url: "{{ calico_manifest_url }}" dest: /tmp/calico.yaml register: calico_config - name: Change registry URL shell: sed -i -e 's#docker.io/calico/#quay.io/calico/#g' {{ calico_config.dest }} - name: Amend settings for VXLAN setup when: overlay_network_setup shell: sed -i '/CALICO_IPV4POOL_IPIP/{n;s/Always/Never/}' {{ calico_config.dest }} - name: Download Calico images on K8s nodes beforehand when: inventory_hostname in (groups['k8s_cluster'] | default([])) shell: awk '/image:/ { print $2 }' {{ calico_config.dest }} | xargs -I{} crictl pull {} environment: CONTAINER_RUNTIME_ENDPOINT: "unix:///run/containerd/containerd.sock" IMAGE_SERVICE_ENDPOINT: "unix:///run/containerd/containerd.sock" args: executable: /bin/bash - name: Deploy Calico from Control Plane node become: false when: inventory_hostname in (groups['primary'] | default([])) block: - name: Deploy Calico command: kubectl apply -f {{ calico_config.dest }} - name: Sleep before trying to check Calico pods pause: seconds: 30 - name: Wait for Calico pods ready command: kubectl -n kube-system wait --timeout=20s --for=condition=Ready pods -l k8s-app=calico-node register: calico_pods_wait until: calico_pods_wait is succeeded retries: 10 - name: Prepare Calico patch copy: src: files/calico_patch.yaml dest: /tmp/calico_patch.yaml register: calico_patch_config - name: Patch Calico command: kubectl -n kube-system patch daemonset calico-node --patch-file {{ calico_patch_config.dest }} - name: Delete Calico pods (for hard restart) command: kubectl -n kube-system delete pods -l k8s-app=calico-node - name: Wait for Calico pods ready (after patch) command: kubectl -n kube-system wait --timeout=20s --for=condition=Ready pods -l k8s-app=calico-node register: calico_pods_wait until: calico_pods_wait is succeeded retries: 10 ... ================================================ FILE: roles/deploy-env/tasks/cilium.yaml ================================================ --- - name: Download Cilium shell: | CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt) CLI_ARCH=amd64 curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum} sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum} args: executable: /bin/bash chdir: /tmp when: inventory_hostname in (groups['primary'] | default([])) - name: Deploy Cilium become: false shell: | cilium install --version {{ cilium_version }} args: executable: /bin/bash when: inventory_hostname in (groups['primary'] | default([])) ... ================================================ FILE: roles/deploy-env/tasks/client_cluster_ssh.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Set client user home directory set_fact: client_user_home_directory: /home/{{ client_ssh_user }} when: client_ssh_user != "root" - name: Set client user home directory set_fact: client_user_home_directory: /root when: client_ssh_user == "root" - name: Set cluster user home directory set_fact: cluster_user_home_directory: /home/{{ cluster_ssh_user }} when: cluster_ssh_user != "root" - name: Set cluster user home directory set_fact: cluster_user_home_directory: /root when: cluster_ssh_user == "root" - name: Setup ssh keys become_user: "{{ client_ssh_user }}" block: - name: Generate ssh key pair shell: | ssh-keygen -t ed25519 -q -N "" -f {{ client_user_home_directory }}/.ssh/id_ed25519 args: creates: "{{ client_user_home_directory }}/.ssh/id_ed25519.pub" when: (inventory_hostname in (groups['primary'] | default([]))) - name: Read ssh public key command: cat "{{ client_user_home_directory }}/.ssh/id_ed25519.pub" register: ssh_public_key when: (inventory_hostname in (groups['primary'] | default([]))) - name: Setup passwordless ssh from primary and cluster nodes become_user: "{{ cluster_ssh_user }}" block: - name: Set primary ssh public key set_fact: client_ssh_public_key: "{{ (groups['primary'] | map('extract', hostvars, ['ssh_public_key', 'stdout']))[0] }}" when: inventory_hostname in (groups['k8s_cluster'] | default([])) - name: Put keys to .ssh/authorized_keys lineinfile: path: "{{ cluster_user_home_directory }}/.ssh/authorized_keys" state: present line: "{{ client_ssh_public_key }}" when: inventory_hostname in (groups['k8s_cluster'] | default([])) - name: Disable strict host key checking template: src: "files/ssh_config" dest: "{{ client_user_home_directory }}/.ssh/config" owner: "{{ client_ssh_user }}" mode: 0644 backup: true when: (inventory_hostname in (groups['primary'] | default([]))) ... ================================================ FILE: roles/deploy-env/tasks/client_cluster_tunnel.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Set cluster IP set_fact: cluster_default_ip: "{{ (groups['k8s_control_plane'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']))[0] }}" - name: Set client IP set_fact: client_default_ip: "{{ (groups['primary'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']))[0] }}" - name: Setup wireguard keys when: (groups['primary'] | difference(groups['k8s_control_plane']) | length > 0) block: - name: Generate wireguard key pair shell: | wg genkey | tee /root/wg-private-key | wg pubkey > /root/wg-public-key chmod 600 /root/wg-private-key when: (inventory_hostname in (groups['primary'] | default([]))) or (inventory_hostname in (groups['k8s_control_plane'] | default([]))) - name: Register public wireguard key variable command: cat /root/wg-public-key register: wg_public_key when: (inventory_hostname in (groups['primary'] | default([]))) or (inventory_hostname in (groups['k8s_control_plane'] | default([]))) - name: Setup wireguard tunnel between primary and cluster control-plane node when: (groups['primary'] | difference(groups['k8s_control_plane']) | length > 0) block: - name: Set primary wireguard public key set_fact: client_wg_public_key: "{{ (groups['primary'] | map('extract', hostvars, ['wg_public_key', 'stdout']))[0] }}" when: inventory_hostname in (groups['k8s_control_plane'] | default([])) - name: Set cluster wireguard public key set_fact: cluster_wg_public_key: "{{ (groups['k8s_control_plane'] | map('extract', hostvars, ['wg_public_key', 'stdout']))[0] }}" when: inventory_hostname in (groups['primary'] | default([])) - name: Set up wireguard tunnel on cluster control-plane node shell: | cat > /tmp/configure_cluster_tunnel.sh < /tmp/configure_client_tunnel.sh < /tmp/coredns_configmap.yaml < /tmp/inventory_default_dev.txt echo -n > /tmp/inventory_k8s_control_plane.txt {% for host in (groups['k8s_control_plane'] | default([])) %} echo {{ hostvars[host].ansible_hostname }} >> /tmp/inventory_k8s_control_plane.txt {% endfor %} echo -n > /tmp/inventory_k8s_nodes.txt {% for host in (groups['k8s_nodes'] | default([])) %} echo {{ hostvars[host].ansible_hostname }} >> /tmp/inventory_k8s_nodes.txt {% endfor %} ... ================================================ FILE: roles/deploy-env/tasks/flannel.yaml ================================================ --- - name: Add Flannel Helm repo become_user: "{{ kubectl.user }}" when: inventory_hostname in (groups['primary'] | default([])) block: - name: Add Flannel chart repo shell: | helm repo add flannel https://flannel-io.github.io/flannel/ - name: Install Flannel shell: | helm upgrade --install flannel flannel/flannel \ --version {{ flannel_version }} \ --namespace kube-flannel \ --create-namespace \ --set podCidr="{{ kubeadm.pod_network_cidr }}" ... ================================================ FILE: roles/deploy-env/tasks/floating_network.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Set cluster device set_fact: # cluster_default_dev: "{{ (groups['k8s_control_plane'] | map('extract', hostvars, ['ansible_default_ipv4', 'interface']))[0] }}" cluster_default_dev: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['interface'] }}" - name: Set up TAP interface on cluster control-plane node shell: | ip tuntap add name provider1 mode tap ip link set provider1 up ip addr add {{ floating_network_gateway_cidr }} dev provider1 - name: Set up SNAT for packets going outside the cluster shell: | iptables -t nat -A POSTROUTING -o {{ cluster_default_dev }} -s {{ floating_network_cidr }} -j MASQUERADE - name: Set up FORWARD for packets going from VMs shell: | iptables -t filter -I FORWARD -s {{ floating_network_cidr }} -j ACCEPT - name: Set up tcp proxy TAP interfaces on cluster control-plane node shell: | ip tuntap add name tcpproxy1 mode tap ip link set tcpproxy1 up ip addr add {{ tcpproxy_gatewayapi_cidr }} dev tcpproxy1 ip addr add {{ tcpproxy_ingress_openstack_cidr }} dev tcpproxy1 # We use tcp proxy to forward traffic to make it possible to connect # to the Openstack public endpoint (managed by Metallb) from VMs. - name: Setup TCP proxy when: metallb_setup block: - name: Prepare nginx tcp proxy config template: src: files/nginx_tcp_proxy.conf dest: /tmp/nginx_tcp_proxy.conf owner: root group: root mode: 0644 - name: Start provider network tcp proxy docker_container: name: nginx_tcp_proxy image: "{{ nginx_image }}" network_mode: host capabilities: - NET_ADMIN - NET_RAW mounts: - source: /tmp/nginx_tcp_proxy.conf target: /etc/nginx/nginx.conf type: bind entrypoint: nginx command: | -g 'daemon off;' state: started recreate: yes - name: Start provider network dnsmasq docker_container: name: provider_dnsmasq image: "{{ dnsmasq_image }}" network_mode: host capabilities: - NET_ADMIN entrypoint: dnsmasq command: >- --keep-in-foreground --no-hosts --bind-interfaces --address="/openstack-helm.org/{{ tcpproxy_gatewayapi_cidr | ipaddr('address') }}" --listen-address="{{ floating_network_gateway_cidr | ipaddr('address') }}" --no-resolv --server={{ dnsmasq_dns_server }} {{ dnsmasq_extra_args | default('') }} state: started recreate: yes ... ================================================ FILE: roles/deploy-env/tasks/gatewayapi_envoy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Deploy Envoy Gateway become: false block: - name: Install Envoy Gateway become_user: "{{ kubectl.user }}" shell: | helm upgrade --install envoy-gateway oci://docker.io/envoyproxy/gateway-helm \ --version {{ gatewayapi_envoy_version }} \ --namespace envoy-gateway-system \ --create-namespace \ --wait - name: Sleep before checking Envoy Gateway pods pause: seconds: 30 - name: Wait for Envoy Gateway pods to be ready command: kubectl -n envoy-gateway-system wait --timeout=5m --for=condition=Available deployment/envoy-gateway - name: Create GatewayClass for Envoy Gateway shell: | tee > /tmp/gatewayapi_envoy_class.yaml < 0 - name: Install Kubernetes binaries apt: state: present update_cache: true allow_downgrade: true pkg: - "kubelet={{ kube_version }}" - "kubeadm={{ kube_version }}" - "kubectl={{ kube_version }}" - name: Restart kubelet service: name: kubelet daemon_reload: yes state: restarted - name: Configure resolv.conf template: src: files/resolv.conf dest: /etc/resolv.conf owner: root group: root mode: 0644 vars: nameserver_ip: "8.8.8.8" - name: Disable systemd-resolved service: name: systemd-resolved enabled: false state: stopped ignore_errors: true - name: Disable unbound service: name: unbound enabled: false state: stopped ignore_errors: true ... ================================================ FILE: roles/deploy-env/tasks/k8s_control_plane.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Mount tmpfs to /var/lib/etcd mount: path: /var/lib/etcd src: tmpfs fstype: tmpfs opts: size=1g state: mounted - name: Prepare kubeadm config template: src: files/kubeadm_config.yaml.j2 dest: /tmp/kubeadm_config.yaml - name: Initialize the Kubernetes cluster using kubeadm command: kubeadm init --config /tmp/kubeadm_config.yaml - name: Generate join command command: kubeadm token create --print-join-command register: join_command - name: "Copy kube config to localhost" synchronize: mode: pull src: /etc/kubernetes/admin.conf dest: /tmp/kube_config ... ================================================ FILE: roles/deploy-env/tasks/loopback_devices.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Create loop device image shell: | mkdir -p {{ loopback_image | dirname }} truncate -s {{ loopback_image_size }} {{ loopback_image }} - name: Create loop device shell: | mknod {{ loopback_device }} b $(grep loop /proc/devices | cut -c3) {{ loopback_device | regex_search('[0-9]+') }} - name: Create loop-setup systemd unit template: src: files/loop-setup.service dest: /etc/systemd/system/loop-setup.service notify: - Systemd reload - name: Systemd reload shell: systemctl daemon-reload - name: Configure loop-setup systemd unit service: name: loop-setup enabled: yes state: started notify: - Systemd reload - Restart loop-setup - name: Check {{ loopback_device }} is attached shell: | losetup | grep -i {{ loopback_device }} ... ================================================ FILE: roles/deploy-env/tasks/loopback_devices_mount.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Format loop device filesystem: fstype: "{{ loopback_format_fs_type }}" dev: "{{ loopback_device }}" when: loopback_format - name: Mount loop device mount: src: "{{ loopback_device }}" path: "{{ loopback_mount_path }}" fstype: "{{ loopback_format_fs_type }}" state: mounted when: loopback_mount ... ================================================ FILE: roles/deploy-env/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Include prerequisites tasks include_tasks: file: prerequisites.yaml - name: Overlay network include_tasks: file: overlay.yaml when: overlay_network_setup - name: Configure /etc/hosts template: src: files/hosts dest: /etc/hosts - name: Loop devices include_tasks: file: loopback_devices.yaml when: loopback_setup and inventory_hostname in (groups['k8s_cluster'] | default([])) - name: Loop device mount include_tasks: file: loopback_devices_mount.yaml when: loopback_setup and inventory_hostname in (groups['k8s_cluster'] | default([])) - name: Deploy Containerd include_tasks: file: containerd.yaml - name: Include K8s common tasks include_tasks: file: k8s_common.yaml when: inventory_hostname in (groups['k8s_cluster'] | default([])) - name: Include K8s control-plane tasks include_tasks: file: k8s_control_plane.yaml when: inventory_hostname in (groups['k8s_control_plane'] | default([])) - name: Prepare kubeadm config template: src: files/etc_default_kubelet.j2 dest: /etc/default/kubelet when: inventory_hostname in (groups['k8s_cluster'] | default([])) - name: Join workload nodes to cluster command: "{{ (groups['k8s_control_plane'] | map('extract', hostvars, ['join_command', 'stdout_lines', 0]))[0] }}" when: inventory_hostname in (groups['k8s_nodes'] | default([])) - name: Include K8s client tasks include_tasks: file: k8s_client.yaml when: inventory_hostname in (groups['primary'] | default([])) - name: Include Calico tasks include_tasks: file: calico.yaml when: calico_setup - name: Include Cilium tasks include_tasks: file: cilium.yaml when: cilium_setup - name: Include Flannel tasks include_tasks: file: flannel.yaml when: flannel_setup - name: Include coredns resolver tasks include_tasks: file: coredns_resolver.yaml when: coredns_resolver_setup - name: Include floating network tasks include_tasks: file: floating_network.yaml when: - floating_network_setup - inventory_hostname in (groups['k8s_control_plane'] | default([])) - name: Include Metallb tasks include_tasks: file: metallb.yaml when: metallb_setup - name: Include client-to-cluster tunnel tasks include_tasks: file: client_cluster_tunnel.yaml when: (groups['primary'] | difference(groups['k8s_control_plane']) | length > 0) - name: Include client-to-cluster ssh key tasks include_tasks: file: client_cluster_ssh.yaml when: client_cluster_ssh_setup - name: Include Ingress-nginx tasks include_tasks: file: ingress_nginx.yaml when: - ingress_setup - ingress_implementation == "nginx" - inventory_hostname in (groups['primary'] | default([])) - name: Include HAProxy ingress tasks include_tasks: file: ingress_haproxy.yaml when: - ingress_setup - ingress_implementation == "haproxy" - inventory_hostname in (groups['primary'] | default([])) - name: Include Envoy Gateway tasks include_tasks: file: gatewayapi_envoy.yaml when: - gatewayapi_setup - gatewayapi_implementation == "envoy" - inventory_hostname in (groups['primary'] | default([])) - name: Include public endpoints tasks include_tasks: file: public_endpoints.yaml when: - ingress_setup or gatewayapi_setup - metallb_setup - name: Include env inventory tasks include_tasks: file: env_inventory.yaml when: - inventory_hostname in (groups['primary'] | default([])) ... ================================================ FILE: roles/deploy-env/tasks/metallb.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Deploy MetalLB become: false when: inventory_hostname in (groups['primary'] | default([])) block: - name: Add MetalLB chart repo become_user: "{{ kubectl.user }}" shell: | helm repo add metallb https://metallb.github.io/metallb - name: Install MetalLB become_user: "{{ kubectl.user }}" shell: | helm upgrade --install metallb metallb/metallb \ --version {{ metallb_version }} \ --namespace metallb-system \ --create-namespace \ --wait --timeout 5m - name: Wait for MetalLB webhook to become ready command: kubectl -n metallb-system wait --timeout=120s --for=condition=Ready pods -l 'app.kubernetes.io/component=controller' - name: Create MetalLB address pool shell: | tee > /tmp/metallb_ipaddresspool.yaml < /tmp/metallb_l2advertisement.yaml < /tmp/ingress_openstack_endpoint_service.yaml < /tmp/ingress_osh_infra_endpoint_service.yaml < /tmp/gatewayapi_envoy_default.yaml <- {{ overlay_network_prefix ~ ((groups['all'] | sort).index(groups['primary'][0]) + 1) if overlay_network_setup | bool else (groups['primary'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | first) }} - debug: msg: "nameserver_ip = {{ nameserver_ip }}" - name: Start dnsmasq when: - inventory_hostname in (groups['primary'] | default([])) docker_container: name: endpoint_dnsmasq image: "{{ dnsmasq_image }}" network_mode: host capabilities: - NET_ADMIN entrypoint: dnsmasq command: >- --keep-in-foreground --no-hosts --bind-interfaces --address="/openstack-helm.org/{{ metallb_gatewayapi_endpoint_cidr | ipaddr('address') }}" --listen-address="{{ nameserver_ip }}" --no-resolv --server={{ dnsmasq_dns_server }} {{ dnsmasq_extra_args | default('') }} state: started recreate: yes - name: Configure /etc/resolv.conf template: src: files/resolv.conf dest: /etc/resolv.conf owner: root group: root mode: 0644 vars: nameserver_ip: "{{ nameserver_ip }}" - name: Restart coredns to re-read resolv.conf changes become: false shell: | kubectl rollout restart -n kube-system deployment/coredns kubectl rollout status -n kube-system deployment/coredns --timeout=120s when: inventory_hostname in (groups['primary'] | default([])) ... ================================================ FILE: roles/deploy-jq/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - block: - name: ensuring jq is deployed on host when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' or ansible_distribution == 'Fedora' include_role: name: deploy-package tasks_from: dist vars: packages: deb: - jq rpm: - jq - name: installing jq 1.5 binary for centos become: true become_user: root when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' get_url: url: https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 dest: /usr/bin/jq mode: 365 force: yes ... ================================================ FILE: roles/deploy-package/defaults/main.yml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- proxy: http: null https: null noproxy: null ... ================================================ FILE: roles/deploy-package/tasks/dist.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: managing distro packages for ubuntu become: true become_user: root when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' vars: state: present apt: name: "{{ item }}" state: "{{ state }}" with_items: "{{ packages.deb }}" - name: managing distro packages for centos become: true become_user: root when: ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' vars: state: present yum: name: "{{ item }}" state: "{{ state }}" with_items: "{{ packages.rpm }}" - name: managing distro packages for fedora become: true become_user: root when: ansible_distribution == 'Fedora' vars: state: present dnf: name: "{{ item }}" state: "{{ state }}" with_items: "{{ packages.rpm }}" ... ================================================ FILE: roles/deploy-package/tasks/pip.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: managing pip packages become: true become_user: root environment: http_proxy: "{{ proxy.http }}" https_proxy: "{{ proxy.https }}" no_proxy: "{{ proxy.noproxy }}" vars: state: present pip: name: "{{ item }}" state: "{{ state }}" with_items: "{{ packages }}" ... ================================================ FILE: roles/deploy-python/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: ensuring python3 is present on all hosts raw: test -e /usr/bin/python3 || (sudo apt -y update && sudo apt install -y python3-minimal) || (sudo yum install -y python3) || (sudo dnf install -y python3) ... ================================================ FILE: roles/deploy-python-pip/defaults/main.yml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- proxy: http: null https: null noproxy: null ... ================================================ FILE: roles/deploy-python-pip/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: check if pip installed command: pip3 --version register: pip_version_output ignore_errors: yes changed_when: false - name: ensuring python pip package is present for ubuntu when: ( pip_version_output is failed ) and ( ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' ) apt: name: python3-pip state: present - name: ensuring python pip package is present for centos when: ( pip_version_output is failed ) and ( ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' ) block: - name: ensuring epel-release package is present for centos as python3-pip is in the epel repo yum: name: epel-release state: present - name: ensuring python pip package is present for centos yum: name: python3-pip state: present - name: ensuring python pip package is present for fedora via the python3-pip rpm when: ( pip_version_output is failed ) and ( ansible_distribution == 'Fedora' ) dnf: name: python3-pip state: present - name: ensuring pip is the latest version become: true become_user: root environment: http_proxy: "{{ proxy.http }}" https_proxy: "{{ proxy.https }}" no_proxy: "{{ proxy.noproxy }}" pip: name: pip state: latest executable: pip3 ... ================================================ FILE: roles/deploy-selenium/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Create selenium configuration directory file: path: /etc/selenium state: directory - name: Install selenium and dependencies dependencies when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' apt: name: "{{ packages }}" vars: packages: - unzip - wget - xvfb - jq - python3-selenium - name: Add google chrome signing key get_url: url: https://dl-ssl.google.com/linux/linux_signing_key.pub dest: /etc/apt/trusted.gpg.d/google-chrome.asc timeout: 120 retries: 10 delay: 5 - name: Add google chrome repository apt_repository: repo: "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/google-chrome.asc] http://dl.google.com/linux/chrome/deb/ stable main" filename: google-chrome state: present - name: Update apt acquire config shell: | tee /etc/apt/apt.conf.d/99retries-timeouts < "${DIR}/${NAME}.yaml" kubectl describe ${OBJECT} ${NAME} > "${DIR}/${NAME}.txt" } export -f get_objects list_objects | \ xargs -r -n 1 -P ${PARALLELISM_FACTOR} -I {} bash -c 'name_objects "$@"' _ {} | \ xargs -r -n 1 -P ${PARALLELISM_FACTOR} -I {} bash -c 'get_objects "$@"' _ {} args: executable: /bin/bash ignore_errors: True - name: "creating directory for namespace scoped objects" file: path: "{{ logs_dir }}/objects/namespaced" state: directory - name: "Gathering descriptions for namespace scoped objects" shell: |- set -e export OBJECT_TYPE=configmaps,cronjobs,daemonsets,deployment,endpoints,ingresses,jobs,networkpolicies,pods,podsecuritypolicies,persistentvolumeclaims,rolebindings,roles,secrets,serviceaccounts,services,statefulsets export PARALLELISM_FACTOR=2 function get_namespaces () { kubectl get namespaces -o name | awk -F '/' '{ print $NF }' } function list_namespaced_objects () { export NAMESPACE=$1 printf ${OBJECT_TYPE} | xargs -d ',' -I {} -P1 -n1 bash -c 'echo "${NAMESPACE} $@"' _ {} } export -f list_namespaced_objects function name_objects () { input=($1) export NAMESPACE=${input[0]} export OBJECT=${input[1]} kubectl get -n ${NAMESPACE} ${OBJECT} -o name | xargs -L1 -I {} -P1 -n1 bash -c 'echo "${NAMESPACE} ${OBJECT} $@"' _ {} } export -f name_objects function get_objects () { input=($1) export NAMESPACE=${input[0]} export OBJECT=${input[1]} export NAME=${input[2]#*/} echo "${NAMESPACE}/${OBJECT}/${NAME}" DIR="{{ logs_dir }}/objects/namespaced/${NAMESPACE}/${OBJECT}" mkdir -p ${DIR} kubectl get -n ${NAMESPACE} ${OBJECT} ${NAME} -o yaml > "${DIR}/${NAME}.yaml" kubectl describe -n ${NAMESPACE} ${OBJECT} ${NAME} > "${DIR}/${NAME}.txt" } export -f get_objects get_namespaces | \ xargs -r -n 1 -P ${PARALLELISM_FACTOR} -I {} bash -c 'list_namespaced_objects "$@"' _ {} | \ xargs -r -n 1 -P ${PARALLELISM_FACTOR} -I {} bash -c 'name_objects "$@"' _ {} | \ xargs -r -n 1 -P ${PARALLELISM_FACTOR} -I {} bash -c 'get_objects "$@"' _ {} args: executable: /bin/bash ignore_errors: True - name: "Downloads logs to executor" synchronize: src: "{{ logs_dir }}/objects" dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}" mode: pull ignore_errors: yes ... ================================================ FILE: roles/disable-local-nameserver/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # NOTE(portdirect): We disable the local nameserver as it interferes with the # k8s dns-service and other local resolvers used for development use. # See the following for the original config: # * https://github.com/openstack/project-config/blob/0332c33dd134033e0620645c252f82b77e4c16f5/nodepool/elements/nodepool-base/finalise.d/89-unbound --- - name: Disable local nameserver and systemd-resolved service when: ansible_distribution == 'Ubuntu' block: - name: update rc.local blockinfile: path: /etc/rc.local mode: 365 block: | #!/bin/bash set -o xtrace # Some providers inject dynamic network config statically. Work around this # for DNS nameservers. This is expected to fail on some nodes so remove -e. set +e sed -i -e 's/^\(DNS[0-9]*=[.0-9]\+\)/#\1/g' /etc/sysconfig/network-scripts/ifcfg-* sed -i -e 's/^NETCONFIG_DNS_POLICY=.*/NETCONFIG_DNS_POLICY=""/g' /etc/sysconfig/network/config set -e echo 'nameserver 208.67.222.222' > /etc/resolv.conf echo 'nameserver 8.8.8.8' >> /etc/resolv.conf exit 0 - name: write resolv.conf blockinfile: path: /etc/resolv.conf mode: 644 block: | nameserver 208.67.222.222 nameserver 8.8.8.8 - name: stop unbound service systemd: state: stopped enabled: no masked: yes daemon_reload: yes name: unbound - name: stop systemd-resolved service systemd: state: stopped enabled: no masked: yes daemon_reload: yes name: systemd-resolved ... ================================================ FILE: roles/enable-hugepages/defaults/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- hugepages: enabled: false # This parameter sets the size of the huge pages, available options: 2M and 1G size: "2M" # This parameter sets the number of huge pages to allocate number: 1024 grub_default_config: "/etc/default/grub" ... ================================================ FILE: roles/enable-hugepages/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Set up 1G hugepages become: true block: - name: Configure grub lineinfile: dest: "{{ grub_default_config }}" line: 'GRUB_CMDLINE_LINUX="default_hugepagesz={{ hugepages.size }} hugepagesz={{ hugepages.size }} hugepages={{ hugepages.number }}"' regexp: '^GRUB_CMDLINE_LINUX="' - name: Update grub configuration command: update-grub2 - name: Reboot host reboot: reboot_timeout: 600 when: hugepages.size == "1G" - name: Set up 2M hugepages become: true sysctl: name: vm.nr_hugepages value: "{{ hugepages.number }}" sysctl_set: true reload: true when: hugepages.size == "2M" ... ================================================ FILE: roles/ensure-chart-testing/README.rst ================================================ Ensure chart-testing is installed **Role Variables** .. zuul:rolevar:: chart_testing_version Version of chart-testing to install. .. zuul:rolevar:: ensure_chart_testing_repo_name_helm_chart :default: https://github.com/helm/chart-testing/releases/download The root location to get the chart testing helm chart. .. zuul:rolevar:: ensure_chart_testing_repo_name_config :default: https://raw.githubusercontent.com/helm/chart-testing The root location to get the chart testing configuration files. ================================================ FILE: roles/ensure-chart-testing/defaults/main.yaml ================================================ --- chart_testing_version: 2.4.0 ensure_chart_testing_repo_name_helm_chart: "https://github.com/helm/chart-testing/releases/download" ensure_chart_testing_repo_name_config: "https://raw.githubusercontent.com/helm/chart-testing" virtualenv: "{{ ansible_user_dir }}/venv" ================================================ FILE: roles/ensure-chart-testing/tasks/main.yaml ================================================ --- - name: Install pip include_role: name: ensure-pip - name: Install Python dependencies become: false pip: name: - yamale - yamllint virtualenv: "{{ virtualenv }}" virtualenv_command: python3 -m venv - name: Install chart-testing become: true unarchive: remote_src: true src: "{{ ensure_chart_testing_repo_name_helm_chart }}/v{{ chart_testing_version }}/chart-testing_{{ chart_testing_version }}_linux_amd64.tar.gz" dest: /usr/local/bin - name: Setup /etc/ct become: true file: path: /etc/ct state: directory mode: 0755 - name: Install configuration files become: true get_url: url: "{{ ensure_chart_testing_repo_name_config }}/v{{ chart_testing_version }}/etc/{{ zj_item }}" dest: "/etc/ct/{{ zj_item }}" loop: - chart_schema.yaml - lintconf.yaml loop_control: loop_var: zj_item ================================================ FILE: roles/gather-host-logs/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: "creating directory for system status" file: path: "{{ logs_dir }}/system" state: directory - name: "Get logs for each host" become: yes shell: |- set -x systemd-cgls --full --all --no-pager > {{ logs_dir }}/system/systemd-cgls.txt ip addr > {{ logs_dir }}/system/ip-addr.txt ip route > {{ logs_dir }}/system/ip-route.txt lsblk > {{ logs_dir }}/system/lsblk.txt mount > {{ logs_dir }}/system/mount.txt docker images > {{ logs_dir }}/system/docker-images.txt brctl show > {{ logs_dir }}/system/brctl-show.txt ps aux --sort=-%mem > {{ logs_dir }}/system/ps.txt dpkg -l > {{ logs_dir }}/system/packages.txt CONTAINERS=($(docker ps -a --format {% raw %}'{{ .Names }}'{% endraw %} --filter label=zuul)) if [ ! -z "$CONTAINERS" ]; then mkdir -p "{{ logs_dir }}/system/containers" for CONTAINER in ${CONTAINERS}; do docker logs "${CONTAINER}" > "{{ logs_dir }}/system/containers/${CONTAINER}.txt" done fi args: executable: /bin/bash ignore_errors: True - name: "Downloads logs to executor" synchronize: src: "{{ logs_dir }}/system" dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}" mode: pull ignore_errors: True ... ================================================ FILE: roles/gather-pod-logs/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: "creating directory for pod logs" file: path: "{{ logs_dir }}/pod-logs" state: directory - name: "creating directory for failed pod logs" file: path: "{{ logs_dir }}/pod-logs/failed-pods" state: directory - name: "retrieve all kubernetes logs, current and previous (if they exist)" shell: |- set -e function get_namespaces () { kubectl get namespaces -o name | awk -F '/' '{ print $NF }' } function get_pods () { NAMESPACE=$1 kubectl get pods -n ${NAMESPACE} -o name | awk -F '/' '{ print $NF }' | xargs -I {} echo ${NAMESPACE} {} } export -f get_pods function get_pod_logs () { NAMESPACE=${1% *} POD=${1#* } INIT_CONTAINERS=$(kubectl get pod $POD -n ${NAMESPACE} -o json | jq -r '.spec.initContainers[]?.name') CONTAINERS=$(kubectl get pod $POD -n ${NAMESPACE} -o json | jq -r '.spec.containers[].name') for CONTAINER in ${INIT_CONTAINERS} ${CONTAINERS}; do echo "${NAMESPACE}/${POD}/${CONTAINER}" mkdir -p "{{ logs_dir }}/pod-logs/${NAMESPACE}/${POD}" mkdir -p "{{ logs_dir }}/pod-logs/failed-pods/${NAMESPACE}/${POD}" kubectl logs ${POD} -n ${NAMESPACE} -c ${CONTAINER} > "{{ logs_dir }}/pod-logs/${NAMESPACE}/${POD}/${CONTAINER}.txt" kubectl logs --previous ${POD} -n ${NAMESPACE} -c ${CONTAINER} > "{{ logs_dir }}/pod-logs/failed-pods/${NAMESPACE}/${POD}/${CONTAINER}.txt" done } export -f get_pod_logs get_namespaces | \ xargs -r -I {} bash -c 'get_pods "$@"' _ {} | \ xargs -r -I {} bash -c 'get_pod_logs "$@"' _ {} args: executable: /bin/bash ignore_errors: True - name: "Downloads pod logs to executor" synchronize: src: "{{ logs_dir }}/pod-logs" dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}" mode: pull ignore_errors: True ... ================================================ FILE: roles/gather-prom-metrics/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: "creating directory for helm release descriptions" file: path: "{{ logs_dir }}/prometheus" state: directory - name: "Get metrics from exporter services in all namespaces" shell: |- set -e NAMESPACES=$(kubectl get namespaces -o json | jq -r '.items[].metadata.name') for NS in $NAMESPACES; do SERVICES=$(kubectl get svc -n $NS -o json | jq -r '.items[] | select(.spec.ports[].name=="metrics") | .metadata.name') for SVC in $SERVICES; do PORT=$(kubectl get svc $SVC -n $NS -o json | jq -r '.spec.ports[] | select(.name=="metrics") | .port') echo "Scraping $SVC.$NS:$PORT/metrics:" curl "$SVC.$NS:$PORT/metrics" >> "{{ logs_dir }}"/prometheus/$NS-$SVC.txt || true done done args: executable: /bin/bash ignore_errors: True - name: "Get ceph metrics from ceph-mgr" shell: |- set -e mgr_endpoints=$(kubectl get endpoints -n ceph -l component=manager -o json | jq -r '.items[].subsets[].addresses[].ip') echo "ceph-mgr endpoints: $mgr_endpoints" for endpoint in $mgr_endpoints; do echo "checking ceph-mgr at $endpoint" metrics_curl="curl $endpoint:9283/metrics" op=$(eval "$metrics_curl") if [[ -n $op ]]; then curl $endpoint:9283/metrics >> "{{ logs_dir }}"/prometheus/ceph-ceph-mgr.txt break else echo "$endpoint is a standby ceph-mgr. Trying next endpoint" fi done args: executable: /bin/bash ignore_errors: True - name: "Get metrics from fluentd pods" shell: |- set -e NAMESPACE="osh-infra" APP_LABEL="fluentd" PODS=$(kubectl get pods -n $NAMESPACE -l application=$APP_LABEL -o json | jq -r '.items[].metadata.name') for POD in $PODS; do IP=$(kubectl get pod -n $NAMESPACE $POD -o json | jq -r '.status.podIP') PORT=$(kubectl get pod -n $NAMESPACE $POD -o json | jq -r '.spec.containers[0].ports[] | select(.name=="metrics") | .containerPort') echo "Scraping $POD at $IP:$PORT/metrics" curl "$IP:$PORT/metrics" >> "{{ logs_dir }}"/prometheus/$POD.txt || true done args: executable: /bin/bash ignore_errors: True - name: "Downloads logs to executor" synchronize: src: "{{ logs_dir }}/prometheus" dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}" mode: pull ignore_errors: True ... ================================================ FILE: roles/gather-selenium-data/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: "creating directory for helm release descriptions" file: path: "{{ logs_dir }}/selenium" state: directory - name: "Get selenium data" shell: |- set -x cp /tmp/artifacts/* {{ logs_dir }}/selenium/. args: executable: /bin/bash ignore_errors: True - name: "Downloads logs to executor" synchronize: src: "{{ logs_dir }}/selenium" dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}" mode: pull ignore_errors: True ... ================================================ FILE: roles/helm-release-status/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: "creating directory for helm release status" file: path: "{{ logs_dir }}/helm/{{ directory }}" state: directory loop_control: loop_var: directory with_items: - values - releases - name: "Gather get release status for helm charts" shell: |- set -e for namespace in $(kubectl get namespaces --no-headers --output custom-columns=":metadata.name"); do # get all Helm releases including pending and failed releases for release in $(helm list --all --short --namespace $namespace); do # Make respective directories only when a Helm release actually exists in the namespace # to prevent uploading a bunch of empty directories for namespaces without a Helm release. mkdir -p {{ logs_dir }}/helm/releases/$namespace mkdir -p {{ logs_dir }}/helm/values/$namespace helm status $release --namespace $namespace >> {{ logs_dir }}/helm/releases/$namespace/$release.txt helm get values $release --namespace $namespace --all >> {{ logs_dir }}/helm/values/$namespace/$release.yaml done done args: executable: /bin/bash ignore_errors: True - name: "Downloads logs to executor" synchronize: src: "{{ logs_dir }}/helm" dest: "{{ zuul.executor.log_root }}/{{ inventory_hostname }}" mode: pull ignore_errors: True ... ================================================ FILE: roles/mount-extra-volume/defaults/main.yml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- extra_volume: size: 80G type: Linux mount_point: /opt/ext_vol ... ================================================ FILE: roles/mount-extra-volume/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Mount additional {{ extra_volume.size }} volume if available when: - ansible_distribution == 'Ubuntu' - (ansible_mounts|selectattr("mount", "equalto", "/")|list)[0].size_available < 50000000000 block: - name: Mount additional {{ extra_volume.size }} volume if available shell: | set -ex sudo fdisk --list df -h sudo mkdir -p ${EXTRA_VOLUME_MOUNT_POINT} BIG_VOLUME=$(sudo fdisk -l 2>&1 | grep -E ${EXTRA_VOLUME_SIZE} | grep ${EXTRA_VOLUME_TYPE} | awk '{print $1}') if ! mount | grep "${BIG_VOLUME}" then sudo mkfs.ext4 "${BIG_VOLUME}" sudo mount "${BIG_VOLUME}" ${EXTRA_VOLUME_MOUNT_POINT} df -h fi environment: EXTRA_VOLUME_MOUNT_POINT: "{{ extra_volume.mount_point }}" EXTRA_VOLUME_SIZE: "{{ extra_volume.size }}" EXTRA_VOLUME_TYPE: "{{ extra_volume.type }}" ... ================================================ FILE: roles/osh-bandit/defaults/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- work_dir: "{{ zuul.project.src_dir }}" helm_version: "3.18.1" bandit_version: "1.7.1" ... ================================================ FILE: roles/osh-bandit/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Install Helm include_role: name: ensure-helm - name: Install binary packages become: true apt: name: - jq state: present update_cache: yes - name: Install yq bandit pip: name: - yq - bandit=={{ bandit_version }} - setuptools - pbr virtualenv: "{{ virtualenv }}" virtualenv_command: python3 -m venv - name: Template out python files shell: | set -xe; source "{{ virtualenv }}/bin/activate" make all SKIP_CHANGELOG=1 mkdir -p python-files EXCLUDES="helm-toolkit doc tests tools logs tmp roles playbooks releasenotes zuul.d python-files" DIRS=`ls -d */ | cut -f1 -d'/'` for EX in $EXCLUDES; do DIRS=`echo $DIRS | sed "s/\b$EX\b//g"` done for DIR in $DIRS; do PYFILES=$(helm template $DIR | yq 'select(.data != null) | .data | to_entries | map(select(.key | test(".*\\.py"))) | select(length > 0) | values[] | {(.key) : (.value)}' | jq -s add) PYKEYS=$(echo "$PYFILES" | jq -r 'select(. != null) | keys[]') for KEY in $PYKEYS; do echo "$PYFILES" | jq -r --arg KEY "$KEY" '.[$KEY]' > ./python-files/"$DIR-$KEY" done done args: chdir: "{{ work_dir }}" executable: /bin/bash - name: Run bandit against python files shell: | source "{{ virtualenv }}/bin/activate" bandit -r ./python-files -s B404,B603 args: chdir: "{{ work_dir }}" executable: /bin/bash ... ================================================ FILE: roles/osh-run-script/defaults/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- ceph_osd_data_device: "/dev/loop0" kubeadm: pod_network_cidr: "10.244.0.0/16" osh_params: container_distro_name: ubuntu container_distro_version: jammy osh_values_overrides_path: "../openstack-helm/values_overrides" gate_scripts_relative_path: "../openstack-helm" ... ================================================ FILE: roles/osh-run-script/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: "Run script {{ workload[0] }}" shell: | set -xe; env {{ gate_script_path }} vars: gate_script_path: "{{ workload[0] }}" args: chdir: "{{ zuul.project.src_dir }}/{{ gate_scripts_relative_path }}" environment: CEPH_OSD_DATA_DEVICE: "{{ ceph_osd_data_device }}" POD_NETWORK_CIDR: "{{ kubeadm.pod_network_cidr }}" zuul_site_mirror_fqdn: "{{ zuul_site_mirror_fqdn }}" OSH_EXTRA_HELM_ARGS: "{{ zuul_osh_extra_helm_args | default('') }}" OSH_HELM_REPO: "{{ osh_helm_repo | default('../openstack-helm') }}" DOWNLOAD_OVERRIDES: "{{ download_overrides | default('') }}" OSH_PATH: "{{ zuul_osh_relative_path | default('../openstack-helm/') }}" OSH_VALUES_OVERRIDES_PATH: "{{ osh_values_overrides_path }}" OPENSTACK_RELEASE: "{{ osh_params.openstack_release | default('') }}" CONTAINER_DISTRO_NAME: "{{ osh_params.container_distro_name | default('') }}" CONTAINER_DISTRO_VERSION: "{{ osh_params.container_distro_version | default('') }}" FEATURES: "{{ osh_params.feature_gates | default('') | regex_replace(',', ' ') }} {{ osh_params.openstack_release | default('') }} {{ osh_params.container_distro_name | default('') }}_{{ osh_params.container_distro_version | default('') }} {{ osh_params.container_distro_name | default('') }}" RUN_HELM_TESTS: "{{ run_helm_tests | default('yes') }}" ... ================================================ FILE: roles/osh-run-script-set/defaults/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- ceph_osd_data_device: "/dev/loop0" kubeadm: pod_network_cidr: "10.244.0.0/16" osh_params: container_distro_name: ubuntu container_distro_version: jammy osh_values_overrides_path: "../openstack-helm/values_overrides" gate_scripts_relative_path: "../openstack-helm" ... ================================================ FILE: roles/osh-run-script-set/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - block: - name: "Run script set {{ workload }}" shell: | set -xe; env {{ gate_script_path }} loop: "{{ workload }}" loop_control: loop_var: gate_script_path pause: 5 args: chdir: "{{ zuul.project.src_dir }}/{{ gate_scripts_relative_path }}" environment: CEPH_OSD_DATA_DEVICE: "{{ ceph_osd_data_device }}" POD_NETWORK_CIDR: "{{ kubeadm.pod_network_cidr }}" zuul_site_mirror_fqdn: "{{ zuul_site_mirror_fqdn }}" OSH_EXTRA_HELM_ARGS: "{{ zuul_osh_extra_helm_args | default('') }}" OSH_HELM_REPO: "{{ osh_helm_repo | default('../openstack-helm/') }}" DOWNLOAD_OVERRIDES: "{{ download_overrides | default('') }}" OSH_PATH: "{{ zuul_osh_relative_path | default('../openstack-helm/') }}" OSH_VALUES_OVERRIDES_PATH: "{{ osh_values_overrides_path }}" OPENSTACK_RELEASE: "{{ osh_params.openstack_release | default('') }}" CONTAINER_DISTRO_NAME: "{{ osh_params.container_distro_name | default('') }}" CONTAINER_DISTRO_VERSION: "{{ osh_params.container_distro_version | default('') }}" FEATURES: "{{ osh_params.feature_gates | default('') | regex_replace(',', ' ') }} {{ osh_params.openstack_release | default('') }} {{ osh_params.container_distro_name | default('') }}_{{ osh_params.container_distro_version | default('') }} {{ osh_params.container_distro_name | default('') }}" RUN_HELM_TESTS: "{{ run_helm_tests | default('yes') }}" # NOTE(aostapenko) using bigger than async_status timeout due to async_status issue with # not recognizing timed out jobs: https://github.com/ansible/ansible/issues/25637 async: 3600 poll: 0 register: async_results - name: Wait for script set to finish async_status: jid: '{{ item.ansible_job_id }}' register: jobs until: jobs.finished delay: 5 retries: 360 loop: "{{ async_results.results }}" always: - name: Print script set output shell: | # NOTE(aostapenko) safely retrieving items for the unlikely case if jobs timed out in async_status echo 'STDOUT:\n{{ item.get("stdout") | regex_replace("\'", "") }}\nSTDERR:\n{{ item.get("stderr") | regex_replace("\'", "") }}' loop: "{{ jobs.results }}" ... ================================================ FILE: roles/override-images/defaults/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- work_dir: "{{ zuul.project.src_dir }}" ... ================================================ FILE: roles/override-images/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Use buildset registry include_role: name: use-buildset-registry - name: Print zuul debug: var: zuul - name: Override proposed images from artifacts shell: > find {{ override_paths | join(" ") }} -type f -exec sed -Ei "s#['\"]?docker\.io/({{ repo }}):({{ tag }})['\"]?\$#{{ buildset_registry_alias }}:{{ buildset_registry.port }}/\1:\2#g" {} + loop: "{{ zuul.artifacts | default([]) }}" args: chdir: "{{ work_dir }}" loop_control: loop_var: zj_zuul_artifact when: "'metadata' in zj_zuul_artifact and zj_zuul_artifact.metadata.type | default('') == 'container_image'" vars: tag: "{{ zj_zuul_artifact.metadata.tag }}" repo: "{{ zj_zuul_artifact.metadata.repository }}" override_paths: - ../openstack-helm*/*/values* - ../openstack-helm/tools/deployment/ - name: Diff shell: | set -ex; for dir in openstack-helm; do path="{{ work_dir }}/../${dir}/" if [ ! -d "${path}" ]; then continue; fi echo "${dir} diff" cd "${path}"; git diff; cd -; done ... ================================================ FILE: roles/setup-firewall/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # NOTE(portdirect): This needs refinement but drops the firewall on zuul nodes --- - name: deploy iptables packages include_role: name: deploy-package tasks_from: dist vars: packages: deb: - iptables rpm: - iptables - command: iptables -S - command: iptables -F - command: iptables -P INPUT ACCEPT - command: iptables -S ... ================================================ FILE: roles/upgrade-host/defaults/main.yml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- ubuntu_kernel_hwe: false ... ================================================ FILE: roles/upgrade-host/tasks/main.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- - name: Upgrade to HWE kernel on Ubuntu Hosts when: - ansible_distribution == 'Ubuntu' - ubuntu_kernel_hwe == true block: - name: Deploy HWE kernel on Ubuntu Hosts include_role: name: deploy-package tasks_from: dist vars: packages: deb: - linux-generic-hwe-16.04 - name: Reboot Host following kernel upgrade shell: sleep 2 && reboot become: yes async: 30 poll: 0 ignore_errors: true args: executable: /bin/bash - name: Wait for hosts to come up following reboot wait_for: host: '{{ hostvars[item].ansible_host }}' port: 22 state: started delay: 60 timeout: 240 with_items: '{{ play_hosts }}' connection: local ... ================================================ FILE: skyline/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Skyline name: skyline version: 2025.2.0 home: https://docs.openstack.org/skyline-apiserver/latest/ sources: - https://opendev.org/openstack/skyline-apiserver - https://opendev.org/openstack/skyline-console - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: skyline/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # FIXME: Add db sync executable endpoint to skyline-apiserver package and use it here site_packages_dir=$(python -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])') alembic -c ${site_packages_dir}/skyline_apiserver/db/alembic/alembic.ini upgrade head ================================================ FILE: skyline/templates/bin/_skyline-apiserver-init.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex GENERATOR_ARGS="--output-file /etc/nginx/nginx.conf" skyline-nginx-generator ${GENERATOR_ARGS} ================================================ FILE: skyline/templates/bin/_skyline-apiserver.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex gunicorn -c /etc/skyline/gunicorn.py skyline_apiserver.main:app ================================================ FILE: skyline/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates -}} {{ dict "envAll" . "service" "skyline" "type" "internal" | include "helm-toolkit.manifests.certificates" }} {{- end -}} ================================================ FILE: skyline/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: skyline-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} skyline-apiserver-init.sh: | {{ tuple "bin/_skyline-apiserver-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} skyline-apiserver.sh: | {{ tuple "bin/_skyline-apiserver.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: skyline/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if (.Values.global).subchart_release_name }} {{- $_ := set . "deployment_name" .Chart.Name }} {{- else }} {{- $_ := set . "deployment_name" .Release.Name }} {{- end }} {{- define "skyline.configmap.etc" }} {{- $configMapName := index . 0 }} {{- $envAll := index . 1 }} {{- with $envAll }} {{- if empty .Values.conf.skyline.openstack.keystone_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.skyline.openstack "keystone_url" -}} {{- end -}} {{- if empty .Values.conf.skyline.openstack.default_region -}} {{- $_ := set .Values.conf.skyline.openstack "default_region" .Values.endpoints.identity.auth.skyline.region_name -}} {{- end -}} {{- if empty .Values.conf.skyline.openstack.system_project -}} {{- $_ := set .Values.conf.skyline.openstack "system_project" .Values.endpoints.identity.auth.skyline.project_name -}} {{- end -}} {{- if empty .Values.conf.skyline.openstack.system_project_domain -}} {{- $_ := set .Values.conf.skyline.openstack "system_project_domain" .Values.endpoints.identity.auth.skyline.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.skyline.openstack.system_user_domain -}} {{- $_ := set .Values.conf.skyline.openstack "system_user_domain" .Values.endpoints.identity.auth.skyline.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.skyline.openstack.system_user_name -}} {{- $_ := set .Values.conf.skyline.openstack "system_user_name" .Values.endpoints.identity.auth.skyline.username -}} {{- end -}} {{- if empty .Values.conf.skyline.openstack.system_user_password -}} {{- $_ := set .Values.conf.skyline.openstack "system_user_password" .Values.endpoints.identity.auth.skyline.password -}} {{- end -}} {{- if empty .Values.conf.skyline.default.database_url -}} {{- $connection := tuple "oslo_db" "skyline" "skyline" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.skyline.default.database_url "connection" -}} {{- else -}} {{- $_ := set .Values.conf.skyline.default "database_url" $connection -}} {{- end -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: {{ $configMapName }} type: Opaque data: skyline.yaml: {{ .Values.conf.skyline | toYaml | b64enc }} gunicorn.py: {{ .Values.conf.gunicorn | b64enc }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- list "skyline-etc" . | include "skyline.configmap.etc" }} {{- end }} ================================================ FILE: skyline/templates/deployment.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment }} {{- $envAll := . }} {{- $mounts_skyline := .Values.pod.mounts.skyline.skyline }} {{- $mounts_skyline_init := .Values.pod.mounts.skyline.init_container }} {{- $serviceAccountName := "skyline" }} {{ tuple $envAll "skyline" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: skyline annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "skyline" "skyline" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.skyline }} selector: matchLabels: {{ tuple $envAll "skyline" "skyline" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "skyline" "skyline" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "skyline" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "skyline" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} nodeSelector: {{ .Values.labels.skyline.node_selector_key }}: {{ .Values.labels.skyline.node_selector_value }} initContainers: {{ tuple $envAll "skyline" $mounts_skyline_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: api-init {{ tuple $envAll "skyline" | include "helm-toolkit.snippets.image" | indent 10 }} command: - /bin/sh - -c - /tmp/skyline-apiserver-init.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: skyline-bin mountPath: /tmp/skyline-apiserver-init.sh subPath: skyline-apiserver-init.sh readOnly: true - name: skyline-etc mountPath: /etc/skyline/skyline.yaml subPath: skyline.yaml readOnly: true - name: skyline-etc mountPath: /etc/skyline/gunicorn.py subPath: gunicorn.py readOnly: true - name: nginx-etc mountPath: /etc/nginx {{ if $mounts_skyline_init.volumeMounts }}{{ toYaml $mounts_skyline_init.volumeMounts | indent 12 }}{{ end }} containers: - name: nginx command: - /bin/sh - -c - cp /etc/nginx/.skyline/nginx.conf /etc/nginx/nginx.conf && nginx -g 'daemon off;' {{ tuple $envAll "skyline_nginx" | include "helm-toolkit.snippets.image" | indent 10 }} ports: - name: api containerPort: {{ tuple "skyline" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: nginx-etc mountPath: /etc/nginx/.skyline - name: skyline-var-lib mountPath: /var/lib/skyline - name: skyline {{ tuple $envAll "skyline" | include "helm-toolkit.snippets.image" | indent 10 }} {{ dict "envAll" $envAll "application" "skyline" "container" "skyline" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /tmp/skyline-apiserver.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: skyline-var-lib mountPath: /var/lib/skyline - name: skyline-etc mountPath: /etc/skyline/skyline.yaml subPath: skyline.yaml readOnly: true - name: skyline-etc mountPath: /etc/skyline/gunicorn.py subPath: gunicorn.py readOnly: true - name: skyline-bin mountPath: /tmp/skyline-apiserver.sh subPath: skyline-apiserver.sh readOnly: true {{ if $mounts_skyline.volumeMounts }}{{ toYaml $mounts_skyline.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: nginx-etc emptyDir: {} - name: skyline-var-lib emptyDir: {} - name: skyline-bin configMap: name: skyline-bin defaultMode: 0555 - name: skyline-etc secret: secretName: skyline-etc defaultMode: 0444 {{ if $mounts_skyline.volumes}}{{ toYaml $mounts_skyline.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: skyline/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: skyline/templates/ingress.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.skyline.ingress.public }} {{- $envAll := . -}} {{- $ingressOpts := dict "envAll" $envAll "backendService" "skyline" "backendServiceType" "skyline" "backendPort" "api" -}} {{- $secretName := $envAll.Values.secrets.tls.skyline.skyline.internal -}} {{- if and .Values.manifests.certificates $secretName }} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.skyline.host_fqdn_override.default.tls.issuerRef.name -}} {{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: skyline/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "skyline" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.skyline.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: skyline/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbToInit := dict "inputType" "secret" "adminSecret" .Values.secrets.oslo_db.admin "userSecret" .Values.secrets.oslo_db.skyline -}} {{- $dbInitJob := dict "envAll" . "serviceName" "skyline" "dbToInit" $dbToInit -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.skyline.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: skyline/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- define "skyline.templates.job_db_sync" -}} {{- $envAll := index . 0 }} {{- with $envAll }} {{- $serviceName := "skyline" -}} {{- $nodeSelector := dict .Values.labels.job.node_selector_key .Values.labels.job.node_selector_value -}} {{- $configMapEtc := (printf "%s-%s" $serviceName "etc" ) -}} {{- $dbAdminTlsSecret := .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- $serviceAccountName := printf "%s-%s" $serviceName "db-sync" }} {{ tuple . "db_sync" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: skyline-db-sync labels: {{ tuple . $serviceName "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: {{ tuple $serviceAccountName . | include "helm-toolkit.snippets.custom_job_annotations" | indent 4 -}} {{ include "metadata.annotations.job.db_sync" . | indent 4 }} spec: backoffLimit: 1000 template: metadata: labels: {{ tuple . $serviceName "db-sync" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple . | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure {{ tuple . "db_sync" | include "helm-toolkit.snippets.kubernetes_image_pull_secrets" | indent 6 }} nodeSelector: {{ toYaml $nodeSelector | indent 8 }} {{- if .Values.pod.tolerations.skyline.enabled }} {{ tuple . $serviceName | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end}} initContainers: {{ tuple . "db_sync" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: skyline-db-sync image: {{ .Values.images.tags.skyline_db_sync | quote }} imagePullPolicy: {{ .Values.images.pull_policy | quote }} {{ tuple . .Values.pod.resources.jobs.db_sync | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" . "application" "skyline" "container" "db_sync" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/sh - -c - /tmp/db-sync.sh volumeMounts: - name: skyline-bin mountPath: /tmp/db-sync.sh subPath: db-sync.sh readOnly: true - name: pod-tmp mountPath: /tmp - name: etc-service mountPath: /etc/skyline - name: db-sync-conf mountPath: /etc/skyline/skyline.yaml subPath: skyline.yaml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" $dbAdminTlsSecret "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: etc-service emptyDir: {} - name: skyline-bin configMap: name: skyline-bin defaultMode: 0555 - name: db-sync-conf secret: secretName: {{ $configMapEtc | quote }} defaultMode: 0444 {{- dict "enabled" $envAll.Values.manifests.certificates "name" $dbAdminTlsSecret | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} {{- end }} {{- if .Values.manifests.job_db_sync }} {{- tuple . | include "skyline.templates.job_db_sync" }} {{- end }} ================================================ FILE: skyline/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "skyline" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.skyline.skyline.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.skyline.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: skyline/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "skyline" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: skyline/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "skyline" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: skyline/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: skyline/templates/service-ingress.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress .Values.network.skyline.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "skyline" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: skyline/templates/service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "skyline" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: api port: {{ tuple "skyline" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.skyline.node_port.enabled }} nodePort: {{ .Values.network.skyline.node_port.port }} {{ end }} selector: {{ tuple . "skyline" "skyline" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.skyline.node_port.enabled }} type: NodePort {{ if .Values.network.skyline.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: skyline/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- release_group: null labels: skyline: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled images: pull_policy: IfNotPresent tags: skyline_db_sync: quay.io/airshipit/skyline:2025.2-ubuntu_noble skyline: quay.io/airshipit/skyline:2025.2-ubuntu_noble skyline_nginx: quay.io/airshipit/skyline:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble local_registry: active: false exclude: - dep_check - image_repo_sync secrets: identity: admin: skyline-keystone-admin skyline: skyline-keystone-user oslo_db: admin: skyline-db-admin skyline: skyline-db-user tls: skyline: skyline: public: skyline-tls-public internal: skyline-tls-internal oci_image_registry: skyline: skyline-oci-image-registry tls: identity: false oslo_db: false network: skyline: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30779 endpoints: cluster_domain_suffix: cluster.local oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct skyline: username: skyline password: password hosts: default: mariadb host_fqdn_override: default: null path: /skyline scheme: default: mysql+pymysql skyline: mysql+pymysql port: mysql: default: 3306 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false skyline: username: skyline password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default skyline: role: admin region_name: RegionOne username: skyline password: password project_name: admin user_domain_name: default project_domain_name: default hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 skyline: name: skyline hosts: default: skyline-api public: skyline host_fqdn_override: default: null scheme: default: 'http' service: 'http' port: api: default: 9999 public: 80 pod: replicas: skyline: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 1 security_context: skyline: pod: runAsUser: 0 container: skyline: readOnlyRootFilesystem: false mounts: skyline: init_container: null skyline: volumes: volumeMounts: tolerations: skyline: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule resources: enabled: false skyline: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - skyline-image-repo-sync services: - endpoint: node service: local_image_registry static: skyline: jobs: - skyline-db-sync - skyline-ks-user services: - endpoint: internal service: oslo_db - endpoint: internal service: identity db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - skyline-db-init services: - endpoint: internal service: oslo_db ks_user: services: - endpoint: internal service: identity conf: skyline: default: debug: true log_dir: /var/log log_file: /dev/stdout # These two params are only available in the custom skyline image access_log_file: /dev/stdout error_log_file: /dev/stdout openstack: interface_type: internal default_region: RegionOne gunicorn: | import multiprocessing bind = "unix:/var/lib/skyline/skyline.sock" workers = (1 + multiprocessing.cpu_count()) // 2 worker_class = "uvicorn.workers.UvicornWorker" timeout = 300 keepalive = 5 reuse_port = False proc_name = "skyline" log_level = "info" disable_redirect_access_to_syslog = True access_logfile = "-" error_logfile = "-" manifests: certificates: false configmap_etc: true configmap_bin: true deployment: true job_db_init: true job_db_sync: true job_db_drop: false secret_db: true secret_keystone: true job_ks_user: true service: true ingress: true service_ingress: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: swift/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 name: swift description: Openstack-Helm Swift version: 2025.2.0 home: https://docs.openstack.org/swift/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Swift/OpenStack_Project_Swift_vertical.jpg sources: - https://opendev.org/openstack/swift - https://opendev.org/openstack/openstack-helm maintainers: - name: Openstack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: swift/templates/bin/_account-start.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "swift.bin.account_start" }} #!/bin/bash set -ex export HOME=/tmp # Wait for ring files echo "Waiting for account ring file..." while [ ! -f /etc/swift/account.ring.gz ]; do echo "Account ring file not found, waiting..." sleep 5 done echo "Account ring file found" # Create required directories mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock # Set permissions chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true # Start account services echo "Starting account services..." swift-account-server /etc/swift/account-server.conf & swift-account-auditor /etc/swift/account-server.conf & swift-account-reaper /etc/swift/account-server.conf & swift-account-replicator /etc/swift/account-server.conf & echo "Swift account services started" # Wait for any process to exit wait {{- end }} ================================================ FILE: swift/templates/bin/_bootstrap.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "swift.bin.bootstrap" }} #!/bin/bash set -ex echo "Swift bootstrap started" # Source credentials export OS_AUTH_URL={{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} export OS_IDENTITY_API_VERSION=3 export OS_USERNAME={{ .Values.endpoints.identity.auth.admin.username }} export OS_PASSWORD={{ .Values.endpoints.identity.auth.admin.password }} export OS_PROJECT_NAME={{ .Values.endpoints.identity.auth.admin.project_name }} export OS_USER_DOMAIN_NAME={{ .Values.endpoints.identity.auth.admin.user_domain_name }} export OS_PROJECT_DOMAIN_NAME={{ .Values.endpoints.identity.auth.admin.project_domain_name }} export OS_INTERFACE=internal # Wait for Swift proxy to be ready SWIFT_ENDPOINT={{ tuple "object_store" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }} echo "Waiting for Swift endpoint at ${SWIFT_ENDPOINT}..." count=0 while ! curl -s -o /dev/null -w '%{http_code}' "${SWIFT_ENDPOINT}/healthcheck" | grep -q "200"; do if [ $count -ge 60 ]; then echo "Timeout waiting for Swift endpoint" exit 1 fi echo "Waiting for Swift endpoint..." sleep 5 count=$((count+1)) done echo "Swift endpoint is healthy" # Run any custom bootstrap script {{ .Values.bootstrap.script | default "" }} echo "Swift bootstrap complete" {{- end }} ================================================ FILE: swift/templates/bin/_container-start.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "swift.bin.container_start" }} #!/bin/bash set -ex export HOME=/tmp # Wait for ring files echo "Waiting for container ring file..." while [ ! -f /etc/swift/container.ring.gz ]; do echo "Container ring file not found, waiting..." sleep 5 done echo "Container ring file found" # Create required directories mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock # Set permissions chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true # Start container services echo "Starting container services..." swift-container-server /etc/swift/container-server.conf & swift-container-auditor /etc/swift/container-server.conf & swift-container-replicator /etc/swift/container-server.conf & swift-container-updater /etc/swift/container-server.conf & swift-container-sync /etc/swift/container-server.conf & echo "Swift container services started" # Wait for any process to exit wait {{- end }} ================================================ FILE: swift/templates/bin/_ks-endpoints.sh.tpl ================================================ #!/bin/bash set -ex {{ include "helm-toolkit.scripts.keystone_endpoints" . }} ================================================ FILE: swift/templates/bin/_ks-service.sh.tpl ================================================ #!/bin/bash set -ex {{ include "helm-toolkit.scripts.keystone_service" . }} ================================================ FILE: swift/templates/bin/_ks-user.sh.tpl ================================================ #!/bin/bash set -ex {{ include "helm-toolkit.scripts.keystone_user" . }} ================================================ FILE: swift/templates/bin/_object-start.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "swift.bin.object_start" }} #!/bin/bash set -ex export HOME=/tmp # Wait for ring files echo "Waiting for object ring file..." while [ ! -f /etc/swift/object.ring.gz ]; do echo "Object ring file not found, waiting..." sleep 5 done echo "Object ring file found" # Create required directories mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock # Set permissions chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true # Start rsync daemon (object replication uses rsync) echo "Starting rsync daemon..." rsync --daemon --config=/etc/swift/rsyncd.conf # Start object services echo "Starting object services..." swift-object-server /etc/swift/object-server.conf & swift-object-auditor /etc/swift/object-server.conf & swift-object-replicator /etc/swift/object-server.conf & swift-object-updater /etc/swift/object-server.conf & swift-object-reconstructor /etc/swift/object-server.conf 2>/dev/null & echo "Swift object services started" # Wait for any process to exit wait {{- end }} ================================================ FILE: swift/templates/bin/_proxy-start.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "swift.bin.proxy_start" }} #!/bin/bash set -ex export HOME=/tmp # Wait for ring files echo "Waiting for ring files..." while [ ! -f /etc/swift/account.ring.gz ] || [ ! -f /etc/swift/container.ring.gz ] || [ ! -f /etc/swift/object.ring.gz ]; do echo "Ring files not found, waiting..." sleep 5 done echo "Ring files found" ls -la /etc/swift/*.ring.gz # Create required directories mkdir -p /var/cache/swift /var/run/swift /var/log/swift # Set permissions chown -R swift:swift /etc/swift /var/cache/swift /var/run/swift /var/log/swift 2>/dev/null || true # Resolve DNS and add to /etc/hosts to work around eventlet DNS issues echo "Resolving service endpoints for eventlet compatibility..." {{- $identityHost := tuple "identity" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{- $cacheHost := tuple "oslo_cache" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} # Resolve keystone KEYSTONE_HOST="{{ $identityHost }}" if [ -n "$KEYSTONE_HOST" ] && [ "$KEYSTONE_HOST" != "null" ]; then KEYSTONE_IP=$(getent hosts "$KEYSTONE_HOST" | awk '{print $1}' | head -1) if [ -n "$KEYSTONE_IP" ]; then echo "$KEYSTONE_IP $KEYSTONE_HOST" >> /etc/hosts echo "Added $KEYSTONE_IP $KEYSTONE_HOST to /etc/hosts" fi fi # Resolve memcached MEMCACHE_HOST="{{ $cacheHost }}" if [ -n "$MEMCACHE_HOST" ] && [ "$MEMCACHE_HOST" != "null" ]; then MEMCACHE_IP=$(getent hosts "$MEMCACHE_HOST" | awk '{print $1}' | head -1) if [ -n "$MEMCACHE_IP" ]; then echo "$MEMCACHE_IP $MEMCACHE_HOST" >> /etc/hosts echo "Added $MEMCACHE_IP $MEMCACHE_HOST to /etc/hosts" fi fi echo "Starting Swift Proxy Server..." exec swift-proxy-server /etc/swift/proxy-server.conf --verbose {{- end }} ================================================ FILE: swift/templates/bin/_ring-builder.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "swift.bin.ring_builder" }} #!/bin/bash set -ex export HOME=/tmp cd /etc/swift PARTITION_POWER={{ .Values.ring.partition_power }} REPLICAS={{ .Values.ring.replicas }} MIN_PART_HOURS={{ .Values.ring.min_part_hours }} # Get the storage service IP (for Kubernetes, use the storage service) STORAGE_IP=${SWIFT_STORAGE_IP:-"127.0.0.1"} echo "Building Swift rings with partition_power=$PARTITION_POWER, replicas=$REPLICAS, min_part_hours=$MIN_PART_HOURS" echo "Storage IP: $STORAGE_IP" # Create ring builder files if they don't exist if [ ! -f account.builder ]; then swift-ring-builder account.builder create $PARTITION_POWER $REPLICAS $MIN_PART_HOURS fi if [ ! -f container.builder ]; then swift-ring-builder container.builder create $PARTITION_POWER $REPLICAS $MIN_PART_HOURS fi if [ ! -f object.builder ]; then swift-ring-builder object.builder create $PARTITION_POWER $REPLICAS $MIN_PART_HOURS fi # Add devices from values {{- range $index, $device := .Values.ring.devices }} DEVICE_NAME="{{ $device.name }}" DEVICE_WEIGHT="{{ $device.weight }}" # Check if device already exists in account ring if ! swift-ring-builder account.builder search --ip $STORAGE_IP --device $DEVICE_NAME 2>/dev/null | grep -q "$DEVICE_NAME"; then swift-ring-builder account.builder add \ --region 1 --zone 1 --ip $STORAGE_IP --port 6202 \ --device $DEVICE_NAME --weight $DEVICE_WEIGHT || true fi # Check if device already exists in container ring if ! swift-ring-builder container.builder search --ip $STORAGE_IP --device $DEVICE_NAME 2>/dev/null | grep -q "$DEVICE_NAME"; then swift-ring-builder container.builder add \ --region 1 --zone 1 --ip $STORAGE_IP --port 6201 \ --device $DEVICE_NAME --weight $DEVICE_WEIGHT || true fi # Check if device already exists in object ring if ! swift-ring-builder object.builder search --ip $STORAGE_IP --device $DEVICE_NAME 2>/dev/null | grep -q "$DEVICE_NAME"; then swift-ring-builder object.builder add \ --region 1 --zone 1 --ip $STORAGE_IP --port 6200 \ --device $DEVICE_NAME --weight $DEVICE_WEIGHT || true fi {{- end }} # Show ring status echo "Account Ring:" swift-ring-builder account.builder echo "Container Ring:" swift-ring-builder container.builder echo "Object Ring:" swift-ring-builder object.builder # Rebalance rings swift-ring-builder account.builder rebalance || true swift-ring-builder container.builder rebalance || true swift-ring-builder object.builder rebalance || true # Copy ring files to shared location cp /etc/swift/*.ring.gz /etc/swift-rings/ 2>/dev/null || true cp /etc/swift/*.builder /etc/swift-rings/ 2>/dev/null || true echo "Ring files created successfully" ls -la /etc/swift/*.ring.gz /etc/swift/*.builder {{- end }} ================================================ FILE: swift/templates/bin/_ring-copy.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "swift.bin.ring_copy" }} #!/bin/bash set -ex echo "=== Swift Copy rings from shared storage ===" for base in account container object; do if [[ ! -f /etc/swift/${base}.ring.gz ]]; then echo "Ring file /etc/swift/${base}.ring.gz not found in /etc/swift, attempting to copy from shared storage." cp /etc/swift-rings/${base}.ring.gz /etc/swift/ echo "Copied ${base}.ring.gz from shared storage." fi if [[ ! -f /etc/swift/${base}.builder ]]; then echo "Builder file /etc/swift/${base}.builder not found in /etc/swift, attempting to copy from shared storage." cp /etc/swift-rings/${base}.builder /etc/swift/ echo "Copied ${base}.builder from shared storage." fi done {{- end }} ================================================ FILE: swift/templates/bin/_storage-init.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "swift.bin.storage_init" }} #!/bin/bash set -e export HOME=/tmp echo "=== Swift Storage Validation ===" # Create swift user if it doesn't exist getent group swift >/dev/null || groupadd -r swift getent passwd swift >/dev/null || useradd -r -g swift -d /var/lib/swift -s /sbin/nologin swift # Create required directories mkdir -p /var/cache/swift /var/run/swift /var/lock /var/log/swift # Validate storage devices from values.yaml ERRORS=0 {{- range $device := .Values.ring.devices }} DEVICE_NAME="{{ $device.name }}" STOREDIR="/srv/node/${DEVICE_NAME}" echo "Checking device: $DEVICE_NAME at $STOREDIR" if [ ! -d "$STOREDIR" ]; then echo "ERROR: Storage directory $STOREDIR does not exist!" echo " Please mount your storage device to $STOREDIR before deploying Swift." ERRORS=$((ERRORS + 1)) continue fi # Check if it's a mountpoint or at least writable if ! touch "$STOREDIR/.swift_test" 2>/dev/null; then echo "ERROR: Storage directory $STOREDIR is not writable!" ERRORS=$((ERRORS + 1)) continue fi rm -f "$STOREDIR/.swift_test" echo " ✓ $STOREDIR is valid and writable" {{- end }} if [ $ERRORS -gt 0 ]; then echo "" echo "==========================================" echo "STORAGE VALIDATION FAILED" echo "==========================================" echo "" echo "Swift requires pre-mounted storage devices." echo "Please prepare your storage before deploying:" echo "" echo "For production (real disks):" echo " mkfs.xfs /dev/sdX" echo " mkdir -p /srv/node/sdX" echo " mount /dev/sdX /srv/node/sdX" echo "" echo "For testing (loop devices):" echo " truncate -s 1G /var/lib/swift/sdb1.img" echo " losetup /dev/loop0 /var/lib/swift/sdb1.img" echo " mkfs.xfs /dev/loop0" echo " mkdir -p /srv/node/sdb1" echo " mount /dev/loop0 /srv/node/sdb1" echo "" exit 1 fi # Set permissions chown -R swift:swift /srv/node /var/cache/swift /var/run/swift /var/lock /var/log/swift chmod -R 755 /srv/node /var/cache/swift echo "" echo "=== Storage directories ===" ls -la /srv/node/ echo "" echo "=== Mount points ===" mount | grep /srv/node || echo "(No dedicated mounts found - using directory storage)" echo "" echo "Storage validation complete - all devices ready" {{- end }} ================================================ FILE: swift/templates/bin/_storage-start.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "swift.bin.storage_start" }} #!/bin/bash set -ex export HOME=/tmp # Wait for ring files echo "Waiting for ring files..." while [ ! -f /etc/swift/account.ring.gz ] || [ ! -f /etc/swift/container.ring.gz ] || [ ! -f /etc/swift/object.ring.gz ]; do echo "Ring files not found, waiting..." sleep 5 done echo "Ring files found" ls -la /etc/swift/*.ring.gz # Create required directories mkdir -p /var/cache/swift /var/run/swift /var/log/swift /var/lock # Set permissions chown -R swift:swift /etc/swift /srv/node /var/cache/swift /var/run/swift /var/log/swift /var/lock 2>/dev/null || true # Start rsync daemon echo "Starting rsync daemon..." rsync --daemon --config=/etc/swift/rsyncd.conf # Start account services echo "Starting account services..." swift-account-server /etc/swift/account-server.conf & swift-account-auditor /etc/swift/account-server.conf & swift-account-reaper /etc/swift/account-server.conf & swift-account-replicator /etc/swift/account-server.conf & # Start container services echo "Starting container services..." swift-container-server /etc/swift/container-server.conf & swift-container-auditor /etc/swift/container-server.conf & swift-container-replicator /etc/swift/container-server.conf & swift-container-updater /etc/swift/container-server.conf & # Start object services echo "Starting object services..." swift-object-server /etc/swift/object-server.conf & swift-object-auditor /etc/swift/object-server.conf & swift-object-replicator /etc/swift/object-server.conf & swift-object-updater /etc/swift/object-server.conf & echo "All Swift storage services started" # Wait for any process to exit wait {{- end }} ================================================ FILE: swift/templates/bin/_swift-test.sh.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "swift.bin.swift_test" }} #!/bin/bash set -ex export HOME=/tmp echo "===== Swift Functional Test =====" # Get authentication token echo "Getting Keystone token..." TOKEN=$(openstack token issue -f value -c id) echo "Token obtained successfully" # Get Swift endpoint SWIFT_URL=$(openstack endpoint list --service swift --interface public -f value -c URL | head -1) echo "Swift URL: $SWIFT_URL" # Test Swift stat echo "" echo "Testing swift stat..." swift stat # Create test container CONTAINER="test-container-$(date +%s)" echo "" echo "Creating container: $CONTAINER" swift post $CONTAINER # List containers echo "" echo "Listing containers..." swift list # Upload a test file echo "Hello from OpenStack Swift!" > /tmp/testfile.txt echo "" echo "Uploading test file..." swift upload $CONTAINER /tmp/testfile.txt --object-name hello.txt # List objects in container echo "" echo "Listing objects in $CONTAINER..." swift list $CONTAINER # Download and verify echo "" echo "Downloading test file..." swift download $CONTAINER hello.txt -o /tmp/downloaded.txt cat /tmp/downloaded.txt # Cleanup echo "" echo "Cleaning up..." swift delete $CONTAINER hello.txt swift delete $CONTAINER echo "" echo "===== Swift Test Complete =====" {{- end }} ================================================ FILE: swift/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{/* Certificates template requires proper TLS configuration in endpoints. To enable, you must set: - manifests.certificates: true - secrets.tls.object_store.api.public: - endpoints.object_store.host_fqdn_override.default.tls (with crt, key, ca) */}} {{- if .Values.manifests.certificates -}} {{- $secretName := .Values.secrets.tls.object_store.api.public -}} {{- $fqdnOverride := index .Values.endpoints.object_store.host_fqdn_override "default" | default dict -}} {{- if and $secretName (hasKey $fqdnOverride "tls") -}} {{ dict "envAll" . "service" "object_store" "type" "public" | include "helm-toolkit.manifests.certificates" }} {{- end -}} {{- end -}} ================================================ FILE: swift/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "swift.configmap.bin" }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: swift-bin labels: {{ tuple $envAll "swift" "bin" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} data: storage-init.sh: | {{ include "swift.bin.storage_init" . | indent 4 }} ring-builder.sh: | {{ include "swift.bin.ring_builder" . | indent 4 }} ring-copy.sh: | {{ include "swift.bin.ring_copy" . | indent 4 }} proxy-start.sh: | {{ include "swift.bin.proxy_start" . | indent 4 }} storage-start.sh: | {{ include "swift.bin.storage_start" . | indent 4 }} account-start.sh: | {{ include "swift.bin.account_start" . | indent 4 }} container-start.sh: | {{ include "swift.bin.container_start" . | indent 4 }} object-start.sh: | {{ include "swift.bin.object_start" . | indent 4 }} bootstrap.sh: | {{ include "swift.bin.bootstrap" . | indent 4 }} ks-service.sh: | {{ tuple "bin/_ks-service.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-endpoints.sh: | {{ tuple "bin/_ks-endpoints.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-user.sh: | {{ tuple "bin/_ks-user.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} swift-test.sh: | {{ include "swift.bin.swift_test" . | indent 4 }} {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- end }} {{- if .Values.manifests.configmap_bin }} {{- include "swift.configmap.bin" . }} {{- end }} ================================================ FILE: swift/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "swift.configmap.etc" }} {{- $envAll := . }} {{- if empty .Values.conf.proxy_server.DEFAULT.swift_dir -}} {{- $_ := set .Values.conf.proxy_server.DEFAULT "swift_dir" "/etc/swift" -}} {{- end -}} {{- if empty (index .Values.conf.proxy_server "filter:authtoken" "www_authenticate_uri") -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "www_authenticate_uri" -}} {{- end -}} {{- if empty (index .Values.conf.proxy_server "filter:authtoken" "auth_url") -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "auth_url" -}} {{- end -}} {{- if empty (index .Values.conf.proxy_server "filter:authtoken" "memcached_servers") -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "memcached_servers" -}} {{- end -}} {{- if empty (index .Values.conf.proxy_server "filter:cache" "memcache_servers") -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:cache") "memcache_servers" -}} {{- end -}} {{- if empty (index .Values.conf.proxy_server "filter:authtoken" "password") -}} {{- $_ := .Values.endpoints.identity.auth.swift.password | set (index .Values.conf.proxy_server "filter:authtoken") "password" -}} {{- end -}} {{- if empty (index .Values.conf.proxy_server "filter:authtoken" "memcache_secret_key") -}} {{- $_ := (default (randAlphaNum 64) .Values.endpoints.oslo_cache.auth.memcache_secret_key) | set (index .Values.conf.proxy_server "filter:authtoken") "memcache_secret_key" -}} {{- end -}} {{- if empty (index .Values.conf.proxy_server "filter:authtoken" "memcache_servers") -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set (index .Values.conf.proxy_server "filter:authtoken") "memcache_servers" -}} {{- end -}} --- apiVersion: v1 kind: ConfigMap metadata: name: swift-etc labels: {{ tuple $envAll "swift" "etc" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} data: swift.conf: | [swift-hash] swift_hash_path_suffix = {{ .Values.conf.swift.swift_hash_path_suffix }} swift_hash_path_prefix = {{ .Values.conf.swift.swift_hash_path_prefix }} {{- range $policy := .Values.conf.swift.storage_policies }} [storage-policy:{{ $policy.index }}] name = {{ $policy.name }} {{- if $policy.default }} default = {{ $policy.default }} {{- end }} {{- if $policy.deprecated }} deprecated = {{ $policy.deprecated }} {{- end }} {{- end }} proxy-server.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.proxy_server | indent 4 }} account-server.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.account_server | indent 4 }} container-server.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.container_server | indent 4 }} object-server.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.object_server | indent 4 }} rsyncd.conf: | uid = {{ .Values.conf.rsyncd.uid }} gid = {{ .Values.conf.rsyncd.gid }} log file = {{ .Values.conf.rsyncd.log_file }} pid file = {{ .Values.conf.rsyncd.pid_file }} address = {{ .Values.conf.rsyncd.address }} [account] max connections = {{ .Values.conf.rsyncd.account.max_connections }} path = {{ .Values.conf.rsyncd.account.path }} read only = {{ .Values.conf.rsyncd.account.read_only }} lock file = {{ .Values.conf.rsyncd.account.lock_file }} [container] max connections = {{ .Values.conf.rsyncd.container.max_connections }} path = {{ .Values.conf.rsyncd.container.path }} read only = {{ .Values.conf.rsyncd.container.read_only }} lock file = {{ .Values.conf.rsyncd.container.lock_file }} [object] max connections = {{ .Values.conf.rsyncd.object.max_connections }} path = {{ .Values.conf.rsyncd.object.path }} read only = {{ .Values.conf.rsyncd.object.read_only }} lock file = {{ .Values.conf.rsyncd.object.lock_file }} container-sync-realms.conf: | {{ include "helm-toolkit.utils.to_ini" .Values.conf.swift.container_sync_realms | indent 4 }} {{- end }} {{- if .Values.manifests.configmap_etc }} {{- include "swift.configmap.etc" . }} {{- end }} ================================================ FILE: swift/templates/daemonset-storage.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.daemonset_storage }} {{- $envAll := . }} {{- $mounts_swift_storage := .Values.pod.mounts.swift_storage.swift_storage }} {{- $mounts_swift_storage_init := .Values.pod.mounts.swift_storage.init_container }} {{- $serviceAccountName := "swift-storage" }} {{ tuple $envAll "storage" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: DaemonSet metadata: name: swift-storage annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll "storage" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }} template: metadata: labels: {{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "swift-storage" "containerNames" (list "swift-account" "swift-container" "swift-object" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} hostNetwork: true hostPID: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: {{ .Values.labels.storage.node_selector_key }}: {{ .Values.labels.storage.node_selector_value }} {{- if .Values.pod.tolerations.swift.enabled }} {{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.storage.timeout | default 30 }} initContainers: {{ tuple $envAll "storage" $mounts_swift_storage_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: storage-init {{ tuple $envAll "swift_storage_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "swift_storage_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/storage-init.sh terminationMessagePath: /tmp/termination-log terminationMessagePolicy: File volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/storage-init.sh subPath: storage-init.sh readOnly: true - name: srv-node mountPath: /srv/node - name: swift-data mountPath: /var/lib/swift {{- if .Values.manifests.pvc }} - name: ring-copy {{ tuple $envAll "swift_storage_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "swift_ring_copy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/ring-copy.sh terminationMessagePath: /tmp/termination-log terminationMessagePolicy: File volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/ring-copy.sh subPath: ring-copy.sh readOnly: true - name: srv-node mountPath: /srv/node - name: swift-data mountPath: /var/lib/swift - name: swift-rings-host mountPath: /etc/swift - name: swift-rings mountPath: {{ .Values.ring.shared_storage.mount_path }} {{- end }} containers: - name: swift-account {{ tuple $envAll "swift_account" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "swift_account" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/account-start.sh ports: - name: account containerPort: {{ .Values.conf.account_server.DEFAULT.bind_port }} hostPort: {{ .Values.conf.account_server.DEFAULT.bind_port }} readinessProbe: exec: command: - /bin/bash - -c - "pgrep -f swift-account-server" initialDelaySeconds: 30 periodSeconds: 15 livenessProbe: exec: command: - /bin/bash - -c - "pgrep -f swift-account-server" initialDelaySeconds: 30 periodSeconds: 30 volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/account-start.sh subPath: account-start.sh readOnly: true - name: swift-etc mountPath: /etc/swift/swift.conf subPath: swift.conf readOnly: true - name: swift-etc mountPath: /etc/swift/account-server.conf subPath: account-server.conf readOnly: true - name: srv-node mountPath: /srv/node - name: swift-rings-host mountPath: /etc/swift/account.ring.gz subPath: account.ring.gz readOnly: true {{- if $mounts_swift_storage.volumeMounts }}{{ toYaml $mounts_swift_storage.volumeMounts | indent 12 }}{{ end }} - name: swift-container {{ tuple $envAll "swift_container" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "swift_container" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/container-start.sh ports: - name: container containerPort: {{ .Values.conf.container_server.DEFAULT.bind_port }} hostPort: {{ .Values.conf.container_server.DEFAULT.bind_port }} readinessProbe: exec: command: - /bin/bash - -c - "pgrep -f swift-container-server" initialDelaySeconds: 30 periodSeconds: 15 livenessProbe: exec: command: - /bin/bash - -c - "pgrep -f swift-container-server" initialDelaySeconds: 30 periodSeconds: 30 volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/container-start.sh subPath: container-start.sh readOnly: true - name: swift-etc mountPath: /etc/swift/swift.conf subPath: swift.conf readOnly: true - name: swift-etc mountPath: /etc/swift/container-server.conf subPath: container-server.conf readOnly: true - name: srv-node mountPath: /srv/node - name: swift-rings-host mountPath: /etc/swift/container.ring.gz subPath: container.ring.gz readOnly: true {{- if $mounts_swift_storage.volumeMounts }}{{ toYaml $mounts_swift_storage.volumeMounts | indent 12 }}{{ end }} - name: swift-object {{ tuple $envAll "swift_object" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.storage | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "swift_object" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/object-start.sh ports: - name: object containerPort: {{ .Values.conf.object_server.DEFAULT.bind_port }} hostPort: {{ .Values.conf.object_server.DEFAULT.bind_port }} - name: rsync containerPort: 873 hostPort: 873 readinessProbe: exec: command: - /bin/bash - -c - "pgrep -f swift-object-server" initialDelaySeconds: 30 periodSeconds: 15 livenessProbe: exec: command: - /bin/bash - -c - "pgrep -f swift-object-server && pgrep -f rsync" initialDelaySeconds: 30 periodSeconds: 30 volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/object-start.sh subPath: object-start.sh readOnly: true - name: swift-etc mountPath: /etc/swift/swift.conf subPath: swift.conf readOnly: true - name: swift-etc mountPath: /etc/swift/object-server.conf subPath: object-server.conf readOnly: true - name: swift-etc mountPath: /etc/swift/rsyncd.conf subPath: rsyncd.conf readOnly: true - name: srv-node mountPath: /srv/node - name: swift-rings-host mountPath: /etc/swift/object.ring.gz subPath: object.ring.gz readOnly: true {{- if $mounts_swift_storage.volumeMounts }}{{ toYaml $mounts_swift_storage.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: swift-bin configMap: name: swift-bin defaultMode: 0555 - name: swift-etc configMap: name: swift-etc defaultMode: 0444 - name: srv-node hostPath: path: /srv/node type: DirectoryOrCreate - name: swift-data hostPath: path: /var/lib/swift type: DirectoryOrCreate - name: swift-rings-host hostPath: path: /etc/swift type: DirectoryOrCreate {{- if .Values.manifests.pvc }} - name: swift-rings persistentVolumeClaim: claimName: {{ .Values.ring.shared_storage.name }} {{- end }} {{- if $mounts_swift_storage.volumes }}{{ toYaml $mounts_swift_storage.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: swift/templates/deployment-proxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_proxy }} {{- $envAll := . }} {{- $mounts_swift_proxy := .Values.pod.mounts.swift_proxy.swift_proxy }} {{- $mounts_swift_proxy_init := .Values.pod.mounts.swift_proxy.init_container }} {{- $serviceAccountName := "swift-proxy" }} {{ tuple $envAll "proxy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: swift-proxy annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.proxy }} selector: matchLabels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ dict "envAll" $envAll "podName" "swift-proxy" "containerNames" (list "swift-proxy" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} dnsPolicy: ClusterFirst dnsConfig: options: - name: ndots value: "2" - name: single-request-reopen affinity: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{- if .Values.pod.tolerations.swift.enabled }} {{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.proxy.timeout | default 30 }} initContainers: {{ tuple $envAll "proxy" $mounts_swift_proxy_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: swift-proxy {{ tuple $envAll "swift_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "swift_proxy" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/proxy-start.sh ports: - name: swift-api containerPort: {{ .Values.conf.proxy_server.DEFAULT.bind_port }} readinessProbe: httpGet: path: /healthcheck port: {{ .Values.conf.proxy_server.DEFAULT.bind_port }} initialDelaySeconds: 15 periodSeconds: 10 livenessProbe: httpGet: path: /healthcheck port: {{ .Values.conf.proxy_server.DEFAULT.bind_port }} initialDelaySeconds: 30 periodSeconds: 30 volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/proxy-start.sh subPath: proxy-start.sh readOnly: true - name: swift-etc mountPath: /etc/swift/swift.conf subPath: swift.conf readOnly: true - name: swift-etc mountPath: /etc/swift/proxy-server.conf subPath: proxy-server.conf readOnly: true - name: swift-etc mountPath: /etc/swift/container-sync-realms.conf subPath: container-sync-realms.conf readOnly: true - name: swift-rings mountPath: /etc/swift/account.ring.gz subPath: account.ring.gz readOnly: true - name: swift-rings mountPath: /etc/swift/container.ring.gz subPath: container.ring.gz readOnly: true - name: swift-rings mountPath: /etc/swift/object.ring.gz subPath: object.ring.gz readOnly: true {{- if $mounts_swift_proxy.volumeMounts }}{{ toYaml $mounts_swift_proxy.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: swift-bin configMap: name: swift-bin defaultMode: 0555 - name: swift-etc configMap: name: swift-etc defaultMode: 0444 - name: swift-rings hostPath: path: /etc/swift type: DirectoryOrCreate {{- if $mounts_swift_proxy.volumes }}{{ toYaml $mounts_swift_proxy.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: swift/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: swift/templates/ingress-proxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_proxy .Values.network.proxy.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "proxy" "backendServiceType" "object_store" "backendPort" "swift-api" -}} {{- $secretName := $envAll.Values.secrets.tls.object_store.api.public -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $fqdnOverride := index .Values.endpoints.object_store.host_fqdn_override "default" | default dict -}} {{- if and $fqdnOverride (hasKey $fqdnOverride "tls") -}} {{- $tlsConfig := index $fqdnOverride "tls" | default dict -}} {{- if and $tlsConfig (hasKey $tlsConfig "issuerRef") -}} {{- $issuerRef := index $tlsConfig "issuerRef" | default dict -}} {{- if and $issuerRef (hasKey $issuerRef "name") -}} {{- $_ := set $ingressOpts "certIssuer" $issuerRef.name -}} {{- end -}} {{- end -}} {{- end -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: swift/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_bootstrap }} {{- $envAll := . }} {{- $serviceAccountName := "swift-bootstrap" }} {{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: swift-bootstrap annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "swift" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "swift" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{- if .Values.pod.tolerations.swift.enabled }} {{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end }} initContainers: {{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: swift-bootstrap {{ tuple $envAll "bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "bootstrap" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} command: - /bin/bash - -c - /tmp/bootstrap.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/bootstrap.sh subPath: bootstrap.sh readOnly: true env: {{- with $env := dict "ksUserSecret" "swift-keystone-admin" "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: swift-bin configMap: name: swift-bin defaultMode: 0555 {{- end }} ================================================ FILE: swift/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "swift" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} {{- if .Values.pod.tolerations.swift.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: swift/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "swift" "serviceTypes" ( tuple "object-store" ) -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: swift/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "swift" "serviceTypes" ( tuple "object-store" ) -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: swift/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "swift" -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) }} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: swift/templates/job-ring-builder.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ring_builder }} {{- $envAll := . }} {{- $serviceAccountName := "swift-ring-builder" }} {{ tuple $envAll "ring_builder" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: swift-ring-builder annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "swift" "ring-builder" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: template: metadata: labels: {{ tuple $envAll "swift" "ring-builder" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: {{ dict "envAll" $envAll "application" "swift" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} restartPolicy: OnFailure nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} {{- if .Values.pod.tolerations.swift.enabled }} {{ tuple $envAll "swift" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{- end }} initContainers: {{ tuple $envAll "ring_builder" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: ring-builder {{ tuple $envAll "swift_ring_builder" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ring_builder | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "swift" "container" "swift_ring_builder" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: - name: SWIFT_STORAGE_IP valueFrom: fieldRef: fieldPath: status.hostIP command: - /bin/bash - -c - /tmp/ring-builder.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/ring-builder.sh subPath: ring-builder.sh readOnly: true - name: swift-rings-host mountPath: /etc/swift - name: swift-etc mountPath: /etc/swift/swift.conf subPath: swift.conf readOnly: true {{- if .Values.manifests.pvc }} - name: swift-rings mountPath: {{ .Values.ring.shared_storage.mount_path }} {{- end }} volumes: - name: pod-tmp emptyDir: {} - name: swift-bin configMap: name: swift-bin defaultMode: 0555 - name: swift-etc configMap: name: swift-etc defaultMode: 0444 - name: swift-rings-host hostPath: path: /etc/swift type: DirectoryOrCreate {{- if .Values.manifests.pvc }} - name: swift-rings persistentVolumeClaim: claimName: {{ .Values.ring.shared_storage.name }} {{- end }} {{- end }} ================================================ FILE: swift/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy }} {{- $envAll := . }} --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: swift-network-policy labels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: podSelector: matchLabels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} policyTypes: - Ingress - Egress ingress: {{ toYaml .Values.network_policy.swift.ingress | indent 4 }} egress: {{ toYaml .Values.network_policy.swift.egress | indent 4 }} {{- end }} ================================================ FILE: swift/templates/pdb-proxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_proxy }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: swift-proxy-pdb labels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: minAvailable: {{ .Values.pod.pdb.proxy.minAvailable | default 1 }} selector: matchLabels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: swift/templates/pdb-storage.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_storage }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: swift-storage-pdb labels: {{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: minAvailable: {{ .Values.pod.pdb.storage.minAvailable | default 1 }} selector: matchLabels: {{ tuple $envAll "swift" "storage" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: swift/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $serviceAccountName := "swift-test" }} {{ tuple $envAll "test" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{ .Release.Name }}-test" annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} "helm.sh/hook": test-success labels: {{ tuple $envAll "swift" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceAccountName: {{ $serviceAccountName }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never initContainers: {{ tuple $envAll "test" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: swift-test image: {{ .Values.images.tags.test }} imagePullPolicy: {{ .Values.images.pull_policy }} command: - /bin/bash - -c - /tmp/swift-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: swift-bin mountPath: /tmp/swift-test.sh subPath: swift-test.sh readOnly: true env: {{- with $env := dict "ksUserSecret" "swift-keystone-user" "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SWIFT_TEST_CONTAINER value: "test-container-{{ randAlphaNum 8 | lower }}" volumes: - name: pod-tmp emptyDir: {} - name: swift-bin configMap: name: swift-bin defaultMode: 0555 {{- end }} ================================================ FILE: swift/templates/pvc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{ define "swift.pvc" }} {{- $name := index . 0 }} {{- $size := index . 1 }} {{- $storageClassName := index . 2 }} --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: {{ $name }} spec: accessModes: - "ReadWriteMany" resources: requests: storage: {{ $size }} storageClassName: {{ $storageClassName }} {{- end }} {{- if .Values.manifests.pvc }} {{ tuple .Values.ring.shared_storage.name .Values.ring.shared_storage.size .Values.ring.shared_storage.storageClassName | include "swift.pvc" }} {{- end }} ================================================ FILE: swift/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "swift" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: swift/templates/service-ingress-proxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_proxy .Values.network.proxy.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "object_store" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: swift/templates/service-proxy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_proxy }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "object_store" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} labels: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{- if .Values.network.proxy.node_port.enabled }} type: NodePort {{- if .Values.network.proxy.external_policy_local }} externalTrafficPolicy: Local {{- end }} {{- else }} type: ClusterIP {{- end }} selector: {{ tuple $envAll "swift" "proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} ports: - name: swift-api port: {{ .Values.endpoints.object_store.port.api.default }} targetPort: {{ .Values.conf.proxy_server.DEFAULT.bind_port }} {{- if .Values.network.proxy.node_port.enabled }} nodePort: {{ .Values.network.proxy.node_port.port }} {{- end }} {{- end }} ================================================ FILE: swift/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- release_group: null labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled storage: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: bootstrap: quay.io/airshipit/swift:2025.2-ubuntu_noble test: quay.io/airshipit/swift:2025.2-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy swift_proxy: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_account: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_container: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_object: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_storage: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_storage_init: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_ring_builder: quay.io/airshipit/swift:2025.2-ubuntu_noble ks_user: quay.io/airshipit/heat:2025.2-ubuntu_noble ks_service: quay.io/airshipit/heat:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/heat:2025.2-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 pull_policy: Always local_registry: active: false exclude: - dep_check - image_repo_sync pod: security_context: swift: pod: runAsUser: 0 container: swift_proxy: readOnlyRootFilesystem: false allowPrivilegeEscalation: true privileged: true swift_account: readOnlyRootFilesystem: false allowPrivilegeEscalation: true privileged: true swift_container: readOnlyRootFilesystem: false allowPrivilegeEscalation: true privileged: true swift_object: readOnlyRootFilesystem: false allowPrivilegeEscalation: true privileged: true swift_storage_init: readOnlyRootFilesystem: false allowPrivilegeEscalation: true privileged: true swift_ring_builder: readOnlyRootFilesystem: false allowPrivilegeEscalation: true privileged: true swift_ring_copy: readOnlyRootFilesystem: false allowPrivilegeEscalation: true privileged: true bootstrap: readOnlyRootFilesystem: false allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname replicas: # Number of proxy replicas (Deployment) proxy: 3 # Note: storage uses DaemonSet, so this is not used. # Storage pods run on all nodes matching the storage node selector. lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 daemonsets: storage: enabled: true min_ready_seconds: 0 max_unavailable: 1 termination_grace_period: proxy: timeout: 30 storage: timeout: 30 resources: enabled: true proxy: requests: memory: "256Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" storage: requests: memory: "256Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ring_builder: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tolerations: swift: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule mounts: swift_proxy: init_container: null swift_proxy: volumeMounts: volumes: swift_storage: init_container: null swift_storage: volumeMounts: volumes: pdb: proxy: minAvailable: 1 storage: minAvailable: 1 network_policy: swift: ingress: - {} egress: - {} network: proxy: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/proxy-body-size: "0" external_policy_local: false node_port: enabled: false port: 30808 bootstrap: enabled: false script: null # Ring Configuration # partition_power: 2^N partitions (10=1024, 14=16384) # replicas: number of data copies (production=3, minimum for HA) # min_part_hours: minimum hours between partition moves (production=24) # devices: list of storage devices used by Swift # - name: device name (must match mountpoint under /srv/node/) # - weight: relative capacity weight (100 = standard, higher = more data) # # IMPORTANT: Devices must be pre-mounted before deploying Swift. # For production: mount real block devices (e.g., /dev/sdb1 -> /srv/node/sdb1) # For development: use loop devices or directories # # Example production config: # devices: # - name: sdb1 # weight: 100 # - name: sdc1 # weight: 100 # ring: partition_power: 10 replicas: 3 min_part_hours: 24 devices: [] # Example: # devices: # - name: sdb1 # weight: 100 # - name: sdb2 # weight: 100 shared_storage: name: swift-shared-storage storageClassName: nfs-provisioner size: 1Gi mount_path: "/etc/swift-rings" conf: swift: swift_hash_path_suffix: CHANGE_ME_SUFFIX swift_hash_path_prefix: CHANGE_ME_PREFIX storage_policies: - name: Policy-0 index: 0 default: "yes" container_sync_realms: DEFAULT: mtime_check_interval: 300 proxy_server: DEFAULT: bind_ip: 0.0.0.0 bind_port: 8080 workers: 2 user: swift swift_dir: /etc/swift log_level: INFO log_name: proxy-server log_facility: log_address: loggers: keys: root,swift handlers: keys: console formatters: keys: simple logger_root: level: INFO handlers: console logger_swift: level: INFO handlers: console qualname: swift propagate: 0 handler_console: class: StreamHandler level: INFO formatter: simple args: (sys.stdout,) formatter_simple: format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" "pipeline:main": pipeline: catch_errors gatekeeper healthcheck proxy-logging cache listing_formats container_sync bulk ratelimit authtoken keystoneauth copy container-quotas account-quotas slo dlo versioned_writes symlink proxy-logging proxy-server "app:proxy-server": use: egg:swift#proxy account_autocreate: "true" allow_account_management: "true" "filter:authtoken": paste.filter_factory: keystonemiddleware.auth_token:filter_factory delay_auth_decision: "True" www_authenticate_uri: null auth_url: null auth_type: password memcached_servers: null memcache_security_strategy: ENCRYPT memcache_secret_key: null username: swift password: null project_name: service user_domain_name: default project_domain_name: default service_token_roles_required: "true" "filter:keystoneauth": use: egg:swift#keystoneauth operator_roles: admin,member,swiftoperator reseller_prefix: AUTH_ reseller_admin_role: ResellerAdmin "filter:healthcheck": use: egg:swift#healthcheck "filter:cache": use: egg:swift#memcache memcache_servers: null "filter:account-quotas": use: egg:swift#account_quotas "filter:container-quotas": use: egg:swift#container_quotas "filter:proxy-logging": use: egg:swift#proxy_logging "filter:bulk": use: egg:swift#bulk "filter:slo": use: egg:swift#slo "filter:dlo": use: egg:swift#dlo "filter:versioned_writes": use: egg:swift#versioned_writes allow_versioned_writes: "true" "filter:copy": use: egg:swift#copy "filter:container_sync": use: egg:swift#container_sync "filter:ratelimit": use: egg:swift#ratelimit "filter:catch_errors": use: egg:swift#catch_errors "filter:gatekeeper": use: egg:swift#gatekeeper "filter:listing_formats": use: egg:swift#listing_formats "filter:symlink": use: egg:swift#symlink account_server: DEFAULT: bind_ip: 0.0.0.0 bind_port: 6202 workers: 2 user: swift swift_dir: /etc/swift devices: /srv/node mount_check: "true" log_level: INFO log_name: account-server log_facility: log_address: loggers: keys: root,swift handlers: keys: console formatters: keys: simple logger_root: level: INFO handlers: console logger_swift: level: INFO handlers: console qualname: swift propagate: 0 handler_console: class: StreamHandler level: INFO formatter: simple args: (sys.stdout,) formatter_simple: format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" "pipeline:main": pipeline: healthcheck recon account-server "app:account-server": use: egg:swift#account "filter:healthcheck": use: egg:swift#healthcheck "filter:recon": use: egg:swift#recon recon_cache_path: /var/cache/swift "account-replicator": concurrency: 2 "account-auditor": {} "account-reaper": {} container_server: DEFAULT: bind_ip: 0.0.0.0 bind_port: 6201 workers: 2 user: swift swift_dir: /etc/swift devices: /srv/node mount_check: "true" log_level: INFO log_name: container-server log_facility: log_address: loggers: keys: root,swift handlers: keys: console formatters: keys: simple logger_root: level: INFO handlers: console logger_swift: level: INFO handlers: console qualname: swift propagate: 0 handler_console: class: StreamHandler level: INFO formatter: simple args: (sys.stdout,) formatter_simple: format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" "pipeline:main": pipeline: healthcheck recon container-server "app:container-server": use: egg:swift#container "filter:healthcheck": use: egg:swift#healthcheck "filter:recon": use: egg:swift#recon recon_cache_path: /var/cache/swift "container-replicator": concurrency: 2 "container-updater": concurrency: 2 "container-auditor": {} "container-sync": {} object_server: DEFAULT: bind_ip: 0.0.0.0 bind_port: 6200 workers: 2 user: swift swift_dir: /etc/swift devices: /srv/node mount_check: "true" log_level: INFO log_name: object-server log_facility: log_address: loggers: keys: root,swift handlers: keys: console formatters: keys: simple logger_root: level: INFO handlers: console logger_swift: level: INFO handlers: console qualname: swift propagate: 0 handler_console: class: StreamHandler level: INFO formatter: simple args: (sys.stdout,) formatter_simple: format: "%%(asctime)s %%(levelname)s [%%(process)d] %%(name)s: %%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" "pipeline:main": pipeline: healthcheck recon object-server "app:object-server": use: egg:swift#object "filter:healthcheck": use: egg:swift#healthcheck "filter:recon": use: egg:swift#recon recon_cache_path: /var/cache/swift recon_lock_path: /var/lock "object-replicator": concurrency: 2 "object-updater": concurrency: 2 "object-auditor": {} rsyncd: uid: swift gid: swift log_file: /var/log/rsyncd.log pid_file: /var/run/rsyncd.pid address: 0.0.0.0 account: max_connections: 4 path: /srv/node/ read_only: "False" lock_file: /var/lock/account.lock container: max_connections: 4 path: /srv/node/ read_only: "False" lock_file: /var/lock/container.lock object: max_connections: 4 path: /srv/node/ read_only: "False" lock_file: /var/lock/object.lock secrets: identity: admin: swift-keystone-admin swift: swift-keystone-user tls: object_store: api: public: swift-tls-public dependencies: dynamic: common: local_image_registry: jobs: - swift-image-repo-sync services: - endpoint: node service: local_image_registry static: ring_builder: jobs: null services: null # storage_init: # jobs: # - swift-ring-builder # services: null storage: # jobs: # - swift-storage-init services: null proxy: daemonset: - swift-storage # jobs: # - swift-storage-init services: - endpoint: internal service: identity - endpoint: internal service: oslo_cache ks_endpoints: jobs: - swift-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity bootstrap: jobs: - swift-ks-user - swift-ks-endpoints services: - endpoint: internal service: identity - endpoint: internal service: object_store tests: services: - endpoint: internal service: identity - endpoint: internal service: object_store endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default swift: role: admin region_name: RegionOne username: swift password: password project_name: service user_domain_name: default project_domain_name: default hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 object_store: name: swift hosts: default: swift-proxy public: swift host_fqdn_override: default: null # NOTE: This chart supports TLS for FQDN over-ridden public # endpoints using the following format: # public: # host: swift.example.com # tls: # crt: | # # key: | # # ca: | # path: default: /v1/AUTH_%(tenant_id)s scheme: default: http # Set to 'https' when TLS is enabled # public: https port: api: default: 8080 public: 80 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 manifests: configmap_bin: true configmap_etc: true deployment_proxy: true daemonset_storage: true job_bootstrap: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_ring_builder: true pdb_proxy: true pdb_storage: true secret_keystone: true ingress_proxy: true service_ingress_proxy: true service_proxy: true network_policy: false pod_test: false certificates: false pvc: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: tacker/.helmignore ================================================ # Patterns to ignore when building packages. # This supports shell glob matching, relative path matching, and # negation (prefixed with !). Only one pattern per line. .DS_Store # Common VCS dirs .git/ .gitignore .bzr/ .bzrignore .hg/ .hgignore .svn/ # Common backup files *.swp *.bak *.tmp *.orig *~ # Various IDEs .project .idea/ *.tmproj .vscode/ ================================================ FILE: tacker/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Tacker name: tacker version: 2025.2.0 home: https://docs.openstack.org/tacker/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Tacker/OpenStack_Project_Tacker_vertical.png sources: - https://opendev.org/openstack/tacker - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: tacker/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex tacker-db-manage --config-file /etc/tacker/tacker.conf upgrade head ================================================ FILE: tacker/templates/bin/_tacker-test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex openstack secret list openstack --help openstack vim list openstack vnflcm list --os-tacker-api-version 1 ================================================ FILE: tacker/templates/bin/_tacker_conductor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} pip install python-cinderclient pip install retrying pip install boto3 apt update apt install curl -y -f --install-suggests curl -o /tmp/helm.tar.gz https://get.helm.sh/helm-v3.11.2-linux-amd64.tar.gz tar zxf /tmp/helm.tar.gz -C /tmp/;mv /tmp/linux-amd64/helm /usr/local/bin/helm tacker-conductor --config-file /etc/tacker/tacker.conf ================================================ FILE: tacker/templates/bin/_tacker_server.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} pip install python-cinderclient pip install retrying pip install boto3 apt update apt install curl -y -f --install-suggests curl -o /tmp/helm.tar.gz https://get.helm.sh/helm-v3.11.2-linux-amd64.tar.gz tar zxf /tmp/helm.tar.gz -C /tmp/;mv /tmp/linux-amd64/helm /usr/local/bin/helm tacker-server --config-file /etc/tacker/tacker.conf ================================================ FILE: tacker/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 data: tacker-server.sh: | {{ tuple "bin/_tacker_server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} tacker-conductor.sh: | {{ tuple "bin/_tacker_conductor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} tacker-test.sh: | {{ tuple "bin/_tacker-test.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" .| indent 4 }} kind: ConfigMap metadata: name: tacker-bin {{- end }} ================================================ FILE: tacker/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if and (not (kindIs "invalid" .Values.conf.tacker.database.connection)) (empty .Values.conf.tacker.database.connection) -}} {{- $connection := tuple "oslo_db" "internal" "tacker" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" -}} {{- if .Values.manifests.certificates -}} {{- $_ := (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | set .Values.conf.tacker.database "connection" -}} {{- else -}} {{- $_ := set .Values.conf.tacker.database "connection" $connection -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.tacker.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "tacker" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.tacker.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.tacker.oslo_messaging_notifications.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "tacker" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.tacker.oslo_messaging_notifications "transport_url" -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.www_authenticate_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.tacker.keystone_authtoken "www_authenticate_uri" -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.tacker.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.tacker.keystone_authtoken "region_name" .Values.endpoints.identity.auth.tacker.region_name -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.tacker.keystone_authtoken "project_name" .Values.endpoints.identity.auth.tacker.project_name -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.tacker.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.tacker.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.tacker.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.tacker.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.username -}} {{- $_ := set .Values.conf.tacker.keystone_authtoken "username" .Values.endpoints.identity.auth.tacker.username -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.password -}} {{- $_ := set .Values.conf.tacker.keystone_authtoken "password" .Values.endpoints.identity.auth.tacker.password -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.tacker.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.tacker.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.tacker.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if empty .Values.conf.tacker.alarm_auth.url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.tacker.alarm_auth "url" -}} {{- end -}} {{- if empty .Values.conf.tacker.alarm_auth.project_name -}} {{- $_ := set .Values.conf.tacker.alarm_auth "project_name" .Values.endpoints.identity.auth.tacker.project_name -}} {{- end -}} {{- if empty .Values.conf.tacker.alarm_auth.username -}} {{- $_ := set .Values.conf.tacker.alarm_auth "username" .Values.endpoints.identity.auth.tacker.username -}} {{- end -}} {{- if empty .Values.conf.tacker.alarm_auth.password -}} {{- $_ := set .Values.conf.tacker.alarm_auth "password" .Values.endpoints.identity.auth.tacker.password -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: tacker-etc namespace: openstack type: Opaque data: config.json: {{ toPrettyJson .Values.conf.server | b64enc }} config-conductor.json: {{ toPrettyJson .Values.conf.conductor | b64enc }} tacker.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.tacker | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} {{- end }} ================================================ FILE: tacker/templates/deployment-conductor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_conductor }} {{- $envAll := . }} {{- $serviceAccountName := "tacker-conductor" }} {{ tuple $envAll "conductor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: tacker-conductor labels: {{ tuple $envAll "tacker" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "tacker" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} replicas: {{ .Values.pod.replicas.conductor }} template: metadata: labels: {{ tuple $envAll "tacker" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: nodeSelector: {{ .Values.labels.conductor.node_selector_key }}: {{ .Values.labels.conductor.node_selector_value }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "conductor" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: application operator: In values: - tacker - key: component operator: In values: - server topologyKey: kubernetes.io/hostname terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.conductor.timeout | default "30" }} containers: - name: tacker-conductor image: {{ .Values.images.tags.tacker_conductor }} imagePullPolicy: {{ .Values.images.pull_policy }} command: - /bin/bash - -c - /tmp/tacker-conductor.sh volumeMounts: - name: localtime mountPath: "/etc/localtime" readOnly: yes - name: tacker-etc mountPath: "/etc/tacker/config.json" readOnly: yes subPath: config-conductor.json - name: tacker-etc mountPath: "/etc/tacker/api-paste.ini" readOnly: yes subPath: api-paste.ini - name: tacker-etc mountPath: "/etc/tacker/tacker.conf" readOnly: yes subPath: tacker.conf - name: tacker-etc mountPath: "/etc/tacker/logging.conf" readOnly: yes subPath: logging.conf {{- range $key, $volume := $envAll.Values.storage.volumes }} - name: {{ $key | replace "_" "-" }} mountPath: {{ $volume.mount_path | quote }} readOnly: false {{- end }} - name: tacker-conductor-sh mountPath: /tmp/tacker-conductor.sh subPath: tacker-conductor.sh readOnly: true - name: oslo-lock-path mountPath: {{ .Values.conf.tacker.oslo_concurrency.lock_path }} ports: - name: conductor containerPort: 5672 initContainers: {{ tuple $envAll "server" tuple | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} volumes: - name: localtime hostPath: path: "/etc/localtime" - name: tacker-etc secret: defaultMode: 292 secretName: tacker-etc {{- range $key, $volume := $envAll.Values.storage.volumes }} - name: {{ $key | replace "_" "-" }} persistentVolumeClaim: claimName: {{ $volume.name }} {{- end }} - name: tacker-conductor-sh configMap: name: tacker-bin defaultMode: 0555 - name: oslo-lock-path emptyDir: {} {{- end }} ================================================ FILE: tacker/templates/deployment-server.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_server }} {{- $envAll := . }} {{- $serviceAccountName := "tacker-server" }} {{ tuple $envAll "server" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: tacker-server labels: {{ tuple $envAll "tacker" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: selector: matchLabels: {{ tuple $envAll "tacker" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} replicas: {{ .Values.pod.replicas.server }} template: metadata: labels: {{ tuple $envAll "tacker" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: nodeSelector: {{ .Values.labels.server.node_selector_key }}: {{ .Values.labels.server.node_selector_value }} serviceAccountName: tacker-server {{ dict "envAll" $envAll "application" "server" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.server.timeout | default "30" }} containers: - name: tacker-server image: {{ .Values.images.tags.tacker_server }} imagePullPolicy: {{ .Values.images.pull_policy }} command: - /bin/bash - -c - /tmp/tacker-server.sh volumeMounts: - name: localtime mountPath: "/etc/localtime" readOnly: yes - name: tacker-etc mountPath: "/etc/tacker/config.json" readOnly: yes subPath: config-server.json - name: tacker-etc mountPath: "/etc/tacker/api-paste.ini" readOnly: yes subPath: api-paste.ini - name: tacker-etc mountPath: "/etc/tacker/tacker.conf" readOnly: yes subPath: tacker.conf - name: tacker-etc mountPath: "/etc/tacker/logging.conf" readOnly: yes subPath: logging.conf {{- range $key, $volume := $envAll.Values.storage.volumes }} - name: {{ $key | replace "_" "-" }} mountPath: {{ $volume.mount_path | quote }} readOnly: false {{- end }} - name: tacker-server-sh mountPath: /tmp/tacker-server.sh subPath: tacker-server.sh readOnly: true - name: oslo-lock-path mountPath: {{ .Values.conf.tacker.oslo_concurrency.lock_path }} ports: - name: t-api containerPort: 9890 initContainers: {{ tuple $envAll "server" tuple | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} volumes: - name: localtime hostPath: path: "/etc/localtime" - name: tacker-etc secret: defaultMode: 292 secretName: tacker-etc {{- range $key, $volume := $envAll.Values.storage.volumes }} - name: {{ $key | replace "_" "-" }} persistentVolumeClaim: claimName: {{ $volume.name }} {{- end }} - name: tacker-server-sh configMap: name: tacker-bin defaultMode: 0555 - name: oslo-lock-path emptyDir: {} {{- end }} ================================================ FILE: tacker/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: tacker/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "nfv_orchestration" "backendPort" "t-api" -}} {{- $secretName := $envAll.Values.secrets.tls.nfv_orchestration.api.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.nfv_orchestratio.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: tacker/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $serviceName := "tacker" -}} {{- $dbToDrop := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName "tacker" ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" -}} {{- $dbDropJob := dict "envAll" . "serviceName" $serviceName "dbToDrop" $dbToDrop -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbToDrop "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.tacker.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: tacker/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $serviceName := "tacker" -}} {{- $dbToInit := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" -}} {{- $dbInitJob := dict "envAll" . "serviceName" $serviceName "dbToInit" $dbToInit -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.tacker.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: tacker/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $serviceName := "tacker" }} {{- $dbSyncJob := dict "envAll" . "serviceName" $serviceName "podVolMounts" .Values.pod.mounts.tacker_db_sync.tacker_db_sync.volumeMounts "podVols" .Values.pod.mounts.tacker_db_sync.tacker_db_sync.volumes -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.tacker.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: tacker/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "tacker" "serviceTypes" ( tuple "nfv-orchestration" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.nfv_orchestration.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.tacker.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: tacker/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "tacker" "serviceTypes" ( tuple "nfv-orchestration" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.nfv_orchestration.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.tacker.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: tacker/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "tacker" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.nfv_orchestration.api.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) }} {{- if .Values.pod.tolerations.tacker.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: tacker/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "tacker" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $rmqUserJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $rmqUserJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{- if .Values.pod.tolerations.tacker.enabled -}} {{- $_ := set $rmqUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: tacker/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $dependencies := .Values.dependencies.static.tests }} {{- $mounts_tacker_tests := .Values.pod.mounts.tacker_tests.tacker_tests }} {{- $mounts_tacker_tests_init := .Values.pod.mounts.tacker_tests.init_container }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{.Release.Name}}-test" labels: {{ tuple $envAll "tacker" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "tacker-test" "containerNames" (list "init" "tacker-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.tacker.enabled }} {{ tuple $envAll "tacker" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" $mounts_tacker_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: tacker-test {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "tacker_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} command: - /tmp/tacker-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: tacker-bin mountPath: /tmp/tacker-test.sh subPath: tacker-test.sh readOnly: true {{ if $mounts_tacker_tests.volumeMounts }}{{ toYaml $mounts_tacker_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: tacker-bin configMap: name: tacker-bin defaultMode: 0555 {{ if $mounts_tacker_tests.volumes }}{{ toYaml $mounts_tacker_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: tacker/templates/pvc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{ define "tacker.pvc" }} {{- $name := index . 0 }} {{- $size := index . 1 }} {{- $storageClass := index . 2 }} --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: {{ $name }} spec: accessModes: - "ReadWriteMany" resources: requests: storage: {{ $size }} storageClassName: {{ $storageClass }} {{- end }} {{- if .Values.manifests.pvc }} {{- $storageClass := .Values.storage.storageClass }} {{- range .Values.storage.volumes }} {{ tuple .name .size $storageClass | include "tacker.pvc" }} {{- end }} {{- end }} ================================================ FILE: tacker/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "tacker" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} ================================================ FILE: tacker/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "tacker" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: tacker/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "tacker" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: tacker/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "nfv_orchestration" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: t-api port: {{ tuple "nfv_orchestration" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "tacker" "server" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: tacker/templates/service-conductor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_conductor }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "nfv_orchestration" "conductor" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: conductor port: {{ tuple "nfv_orchestration" "internal" "conductor" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.conductor.node_port.enabled }} nodePort: {{ .Values.network.conductor.node_port.port }} {{ end }} selector: {{ tuple $envAll "tacker" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.conductor.node_port.enabled }} type: NodePort {{ if .Values.network.conductor.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: tacker/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "nfv_orchestration" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: tacker/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- labels: server: node_selector_key: openstack-control-plane node_selector_value: enabled conductor: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled images: pull_policy: IfNotPresent tags: tacker_server: quay.io/airshipit/tacker:2025.1-ubuntu_noble tacker_conductor: quay.io/airshipit/tacker:2025.1-ubuntu_noble scripted_test: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble tacker_db_sync: quay.io/airshipit/tacker:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy local_registry: active: false exclude: - dep_check - image_repo_sync dependencies: static: server: jobs: - tacker-db-sync - tacker-ks-user - tacker-ks-endpoints - tacker-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: key_manager conductor: jobs: - tacker-db-sync - tacker-ks-user - tacker-ks-endpoints - tacker-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: key_manager tests: services: - endpoint: internal service: identity db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - tacker-db-init services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - tacker-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity pod: security_context: server: pod: runAsUser: 0 runAsNonRoot: false conductor: pod: runAsUser: 0 runAsNonRoot: false test: pod: runAsUser: 0 runAsNonRoot: false container: tacker_test: allowPrivilegeEscalation: false readOnlyRootFilesystem: true lifecycle: termination_grace_period: server: timeout: 30 conductor: timeout: 30 replicas: conductor: 1 server: 1 tolerations: tacker: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule resources: enabled: false jobs: db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" mounts: tacker_db_sync: tacker_db_sync: volumeMounts: volumes: tacker_tests: init_container: null tacker_tests: volumeMounts: volumes: storage: storageClass: general volumes: csar_files: name: tacker-csar-files size: 2Gi mount_path: "/var/lib/tacker/csar_files" vnfpackages: name: tacker-vnfpackages size: 2Gi mount_path: "/var/lib/tacker/vnfpackages" logs: name: tacker-logs size: 2Gi mount_path: "/var/log/openstackhelm/tacker" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30900 conductor: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30901 secrets: identity: admin: tacker-keystone-admin tacker: tacker-keystone-user oslo_db: admin: tacker-db-admin tacker: tacker-db-user oslo_messaging: admin: tacker-rabbitmq-admin tacker: tacker-rabbitmq-user oci_image_registry: tacker: tacker-oci-image-registry tls: nfv_orchestration: api: public: tacker-tls-public internal: tacker-tls-internal endpoints: cluster_domain_suffix: cluster.local oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct tacker: username: tacker password: password hosts: default: mariadb host_fqdn_override: default: null path: /tacker scheme: mysql+pymysql port: mysql: default: 3306 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default tacker: role: admin region_name: RegionOne username: tacker password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct tacker: username: tacker password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /tacker scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 nfv_orchestration: name: tacker hosts: default: tacker-api conductor: tacker-conductor public: tacker host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 9890 public: 80 conductor: default: 5672 key_manager: name: barbican hosts: default: barbican-api public: barbican host_fqdn_override: default: null path: default: /v1 scheme: default: http port: api: default: 9311 public: 80 conf: tacker: DEFAULT: log_config_append: /etc/tacker/logging.conf debug: false log_dir: /var/log/openstackhelm/tacker api_workers: 5 service_plugins: "nfvo,vnfm" nfvo: vim_drivers: openstack openstack_vim: stack_retries: 60 stack_retry_wait: 10 vim_keys: use_barbican: true tacker: monitor_driver: "ping,http_ping" alarm_monitor_driver: ceilometer cors: enabled: true allowed_origin: "*" max_age: 3600 allow_methods: "GET,POST,PUT,DELETE,PATCH,OPTIONS" allow_headers: "Content-Type,Version,Accept,X-Auth-Token" expose_headers: "Content-Type,Accept,Cache-Control,Content-Language,X-Subject-Token" database: connection_recycle_time: 10 max_pool_size: 1 max_retries: "-1" # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: service_type: nfv-orchestration auth_type: password auth_version: v3 service_token_roles_required: true cafile: "" memcache_security_strategy: ENCRYPT alarm_auth: {} ceilometer: host: tacker-api.openstack.svc.cluster.local port: 9890 oslo_messaging_notifications: driver: noop oslo_concurrency: lock_path: /var/lock glance_store: filesystem_store_datadir: /var/lib/tacker/csar_files server: command: "tacker-server --config-file /etc/tacker/tacker.conf" config_files: - source: "/etc/tacker/tacker.conf" dest: "/etc/tacker/tacker.conf" owner: "tacker" perm: "0600" permissions: - path: "/var/log/openstackhelm/tacker" owner: "tacker:tacker" recurse: true - path: "/var/lib/tacker/csar_files" owner: "tacker:tacker" conductor: command: "tacker-conductor --config-file /etc/tacker/tacker.conf" config_files: - source: "/etc/tacker/tacker.conf" dest: "/etc/tacker/tacker.conf" owner: "tacker" perm: "0600" permissions: - path: "/var/log/openstackhelm/tacker" owner: "tacker:tacker" recurse: true - path: "/var/lib/tacker/vnfpackages" owner: "tacker:tacker" - path: "/var/lib/tacker/csar_files" owner: "tacker:tacker" paste: composite:tacker: use: egg:Paste#urlmap /: tackerversions /v1.0: tackerapi_v1_0 /vnfpkgm/v1: vnfpkgmapi_v1 /vnflcm: vnflcm_versions /vnflcm/v1: vnflcm_v1 /vnflcm/v2: vnflcm_v2 /vnffm/v1: vnffm_v1 /vnfpm/v2: vnfpm_v2 /alert/vnf_instances: prometheus_auto_scaling /alert: prometheus_fm /pm_event: prometheus_pm /server_notification: server_notification composite:tackerapi_v1_0: use: call:tacker.auth:pipeline_factory noauth: cors request_id catch_errors extensions tackerapiapp_v1_0 keystone: cors request_id catch_errors authtoken keystonecontext extensions tackerapiapp_v1_0 composite:vnfpkgmapi_v1: use: call:tacker.auth:pipeline_factory noauth: cors request_id catch_errors vnfpkgmapp_v1 keystone: cors request_id catch_errors authtoken keystonecontext vnfpkgmapp_v1 composite:vnflcm_v1: use: call:tacker.auth:pipeline_factory noauth: cors request_id catch_errors vnflcmaapp_v1 keystone: cors request_id catch_errors authtoken keystonecontext vnflcmaapp_v1 composite:vnflcm_v2: use: call:tacker.auth:pipeline_factory noauth: cors request_id catch_errors vnflcmaapp_v2 keystone: cors request_id catch_errors authtoken keystonecontext vnflcmaapp_v2 composite:vnfpm_v2: use: call:tacker.auth:pipeline_factory noauth: cors request_id catch_errors vnfpmaapp_v2 keystone: cors request_id catch_errors authtoken keystonecontext vnfpmaapp_v2 composite:vnflcm_versions: use: call:tacker.auth:pipeline_factory noauth: cors request_id catch_errors vnflcm_api_versions keystone: cors request_id catch_errors authtoken keystonecontext vnflcm_api_versions composite:vnffm_v1: use: call:tacker.auth:pipeline_factory noauth: cors request_id catch_errors vnffmaapp_v1 keystone: cors request_id catch_errors authtoken keystonecontext vnffmaapp_v1 filter:cors: paste.filter_factory: oslo_middleware.cors:filter_factory oslo_config_project: tacker filter:request_id: paste.filter_factory: oslo_middleware:RequestId.factory filter:catch_errors: paste.filter_factory: oslo_middleware:CatchErrors.factory filter:keystonecontext: paste.filter_factory: tacker.auth:TackerKeystoneContext.factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:extensions: paste.filter_factory: tacker.api.extensions:extension_middleware_factory app:tackerversions: paste.app_factory: tacker.api.versions:Versions.factory app:tackerapiapp_v1_0: paste.app_factory: tacker.api.v1.router:APIRouter.factory app:vnfpkgmapp_v1: paste.app_factory: tacker.api.vnfpkgm.v1.router:VnfpkgmAPIRouter.factory app:vnflcmaapp_v1: paste.app_factory: tacker.api.vnflcm.v1.router:VnflcmAPIRouter.factory app:vnflcmaapp_v2: paste.app_factory: tacker.sol_refactored.api.router:VnflcmAPIRouterV2.factory app:vnfpmaapp_v2: paste.app_factory: tacker.sol_refactored.api.router:VnfPmAPIRouterV2.factory app:vnflcm_api_versions: paste.app_factory: tacker.sol_refactored.api.router:VnflcmVersions.factory app:vnffmaapp_v1: paste.app_factory: tacker.sol_refactored.api.router:VnffmAPIRouterV1.factory app:prometheus_auto_scaling: paste.app_factory: tacker.sol_refactored.api.router:AutoScalingRouter.factory app:prometheus_fm: paste.app_factory: tacker.sol_refactored.api.router:FmAlertRouter.factory app:prometheus_pm: paste.app_factory: tacker.sol_refactored.api.router:PmEventRouter.factory app:server_notification: paste.app_factory: tacker.sol_refactored.api.router:ServerNotificationRouter.factory logging: loggers: keys: - root - tacker handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_tacker: level: INFO handlers: - stdout qualname: tacker logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" tls: identity: false oslo_messaging: false oslo_db: false manifests: certificates: false configmap_etc: true configmap_bin: true deployment_server: true deployment_conductor: true job_db_init: true job_db_drop: false job_db_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pod_test: true pvc: true secret_db: true secret_keystone: true secret_rabbitmq: true service_api: true service_conductor: true ingress_api: true service_ingress_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: tempest/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Tempest name: tempest version: 2025.2.0 home: https://docs.openstack.org/tempest/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/tempest/OpenStack_Project_tempest_vertical.png sources: - https://opendev.org/openstack/tempest - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: tempest/templates/_helpers.tpl ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} # This function helps define blacklist and whitelist files for tempest # It ingests a list and creates the appropriate regex files for the whitelist # and blacklist {{- define "tempest.utils.to_regex_file" -}} {{- range $test_regex := . -}} {{ $test_regex }} {{ end -}} {{- end -}} ================================================ FILE: tempest/templates/bin/_run-tests.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ if .Values.conf.cleanup.enabled }} tempest cleanup --init-saved-state if [ "true" == "{{- .Values.conf.cleanup.force -}}" ]; then trap "tempest cleanup; exit" 1 ERR fi {{- end }} {{ .Values.conf.script }} {{ if .Values.conf.cleanup.enabled }} tempest cleanup {{- end }} ================================================ FILE: tempest/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} --- apiVersion: v1 kind: ConfigMap metadata: name: tempest-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} run-tests.sh: | {{ tuple "bin/_run-tests.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} ================================================ FILE: tempest/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.tempest.auth.admin_username -}} {{- $_ := set .Values.conf.tempest.auth "admin_username" .Values.endpoints.identity.auth.admin.username -}} {{- end -}} {{- if empty .Values.conf.tempest.auth.admin_password -}} {{- $_ := set .Values.conf.tempest.auth "admin_password" .Values.endpoints.identity.auth.admin.password -}} {{- end -}} {{- if empty .Values.conf.tempest.auth.admin_project_name -}} {{- $_ := set .Values.conf.tempest.auth "admin_project_name" .Values.endpoints.identity.auth.admin.project_name -}} {{- end -}} {{- if empty .Values.conf.tempest.auth.admin_domain_name -}} {{- $_ := set .Values.conf.tempest.auth "admin_domain_name" .Values.endpoints.identity.auth.admin.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.tempest.identity.uri_v3 -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.tempest.identity "uri_v3" -}} {{- end -}} {{- if empty .Values.conf.tempest.identity.region -}} {{- $_ := set .Values.conf.tempest.identity "region" .Values.endpoints.identity.auth.admin.region_name -}} {{- end -}} {{- if .Values.conf.tempest.service_available.heat -}} {{- if empty .Values.conf.tempest.heat_plugin.username -}} {{- $_ := set .Values.conf.tempest.heat_plugin "username" .Values.endpoints.identity.auth.tempest.username -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.password -}} {{- $_ := set .Values.conf.tempest.heat_plugin "password" .Values.endpoints.identity.auth.tempest.password -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.project_name -}} {{- $_ := set .Values.conf.tempest.heat_plugin "project_name" .Values.endpoints.identity.auth.tempest.project_name -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.admin_username -}} {{- $_ := set .Values.conf.tempest.heat_plugin "admin_username" .Values.endpoints.identity.auth.admin.username -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.admin_password -}} {{- $_ := set .Values.conf.tempest.heat_plugin "admin_password" .Values.endpoints.identity.auth.admin.password -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.admin_project_name -}} {{- $_ := set .Values.conf.tempest.heat_plugin "admin_project_name" .Values.endpoints.identity.auth.admin.project_name -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.tempest.heat_plugin "auth_url" -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.region -}} {{- $_ := set .Values.conf.tempest.heat_plugin "region" .Values.endpoints.identity.auth.admin.region_name -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.project_domain_name -}} {{- $_ := set .Values.conf.tempest.heat_plugin "project_domain_name" .Values.endpoints.identity.auth.tempest.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.tempest.heat_plugin.user_domain_name -}} {{- $_ := set .Values.conf.tempest.heat_plugin "user_domain_name" .Values.endpoints.identity.auth.tempest.user_domain_name -}} {{- end -}} {{- end -}} {{- if empty .Values.conf.tempest.dashboard.dashboard_url -}} {{- $endpointScheme := tuple "dashboard" "public" "web" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- $endpointHost := tuple "dashboard" "public" . | include "helm-toolkit.endpoints.endpoint_host_lookup" }} {{- $endpointPort := tuple "dashboard" "public" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $endpointPath := tuple "dashboard" "public" "web" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} {{/* When CSRF protection is enabled Refferer and Host header should match. Common browsers doesn't add default ports like 80 and 443 to the headers Use the same logic here to make sure test passed when CSRF protection is enabled and we using default port numbers. More info may be found here: * https://code.djangoproject.com/ticket/26037 * https://stackoverflow.com/questions/27533011/django-csrf-error-casused-by-nginx-x-forwarded-host */}} {{- if eq $endpointPort "80" "443" }} {{- $_ := set .Values.conf.tempest.dashboard "dashboard_url" (printf "%s://%s%s" $endpointScheme $endpointHost $endpointPath) }} {{- else }} {{- $_ := set .Values.conf.tempest.dashboard "dashboard_url" (printf "%s://%s:%s%s" $endpointScheme $endpointHost $endpointPort $endpointPath) }} {{- end }} {{- end }} --- apiVersion: v1 kind: Secret metadata: name: tempest-etc type: Opaque data: tempest.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.tempest | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.tempest_logging | b64enc }} {{- if not (empty .Values.conf.blacklist) }} test-blacklist: {{ include "tempest.utils.to_regex_file" .Values.conf.blacklist | b64enc }} {{- end }} {{- if not (empty .Values.conf.whitelist) }} test-whitelist: {{ include "tempest.utils.to_regex_file" .Values.conf.whitelist | b64enc }} {{- end }} {{- end }} ================================================ FILE: tempest/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: tempest/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "tempest" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: tempest/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "tempest" -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.identity.api.internal -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: tempest/templates/job-run-tests.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_run_tests }} {{- $envAll := . }} {{- $serviceAccountName := "tempest-run-tests" }} {{ tuple $envAll "run_tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: Job metadata: name: {{ .Release.Name }}-run-tests annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} helm.sh/hook: post-install,post-upgrade spec: backoffLimit: {{ .Values.jobs.run_tests.backoffLimit }} template: metadata: labels: {{ tuple $envAll "tempest" "run-tests" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} restartPolicy: {{ .Values.jobs.run_tests.restartPolicy }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "run_tests" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} - name: tempest-run-tests-init {{ tuple $envAll "tempest_run_tests" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.run_tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: 0 command: - chown - -R - "root:" - /var/lib/tempest/data volumeMounts: - name: pod-tmp mountPath: /tmp - name: tempest-reports mountPath: /var/lib/tempest/data containers: - name: tempest-run-tests {{ tuple $envAll "tempest_run_tests" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.run_tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} command: - /tmp/run-tests.sh env: {{- if or .Values.manifests.certificates .Values.tls.identity }} - name: REQUESTS_CA_BUNDLE value: "/etc/tempest/certs/ca.crt" {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: tempest-bin mountPath: /tmp/run-tests.sh subPath: run-tests.sh readOnly: true - name: etctempest mountPath: /etc/tempest - name: tempest-etc mountPath: /etc/tempest/tempest.conf subPath: tempest.conf readOnly: true - name: tempest-etc mountPath: /etc/tempest/logging.conf subPath: logging.conf readOnly: true {{ if not (empty .Values.conf.blacklist) }} - name: tempest-etc mountPath: /etc/tempest/test-blacklist subPath: test-blacklist readOnly: true {{- end }} {{ if not (empty .Values.conf.whitelist) }} - name: tempest-etc mountPath: /etc/tempest/test-whitelist subPath: test-whitelist readOnly: true {{- end }} - name: tempest-reports mountPath: /var/lib/tempest/data {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.identity.api.internal "path" "/etc/tempest/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} - name: etctempest emptyDir: {} - name: tempest-etc secret: secretName: tempest-etc defaultMode: 0444 - name: tempest-bin configMap: name: tempest-bin defaultMode: 0555 - name: tempest-reports {{- if not .Values.pvc.enabled }} emptyDir: {} {{- else }} persistentVolumeClaim: claimName: {{ .Values.pvc.name }} {{- end }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} ================================================ FILE: tempest/templates/pvc-tempest.yaml ================================================ # {{/* # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # */}} {{- if .Values.pvc.enabled }} kind: PersistentVolumeClaim apiVersion: v1 metadata: name: {{ .Values.pvc.name }} spec: accessModes: - ReadWriteOnce resources: requests: storage: {{ .Values.pvc.requests.storage }} storageClassName: {{ .Values.pvc.storage_class }} {{- end }} ================================================ FILE: tempest/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "tempest" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: tempest/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: tempest/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for tempest. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: job: node_selector_key: openstack-control-plane node_selector_value: enabled images: tags: dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy tempest_run_tests: quay.io/airshipit/tempest:latest-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync jobs: run_tests: backoffLimit: 6 restartPolicy: OnFailure pod: user: tempest: uid: 1000 resources: enabled: false jobs: ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" run_tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" dependencies: dynamic: common: local_image_registry: jobs: - tempest-image-repo-sync services: - endpoint: node service: local_image_registry static: ks_user: services: - service: identity endpoint: internal run_tests: jobs: - tempest-ks-user services: - service: identity endpoint: internal image_repo_sync: services: - endpoint: internal service: local_image_registry conf: script: | tempest run --config-file /etc/tempest/tempest.conf -w 4 --smoke # The following sections can be used to blacklist and whitelist specific tests. # If either section is not empty, it will be used to create an entry in the # tempest-etc configmap and will be mounted into the tempest-run-tests pod # blacklist: # - (?:tempest\.api\.identity\.admin\.v3\.test_groups\.GroupsV3TestJSON\.test_list_groups) # - (?:tempest\.api\.image\.v2\.test_images\.ListSharedImagesTest\.test_list_images_param_member_status) # - (?:tempest\.scenario\.test_encrypted_cinder_volumes\.TestEncryptedCinderVolumes\.test_encrypted_cinder_volumes_cryptsetup) # - (?:tempest\.scenario\.test_encrypted_cinder_volumes\.TestEncryptedCinderVolumes\.test_encrypted_cinder_volumes_luks) # - (?:tempest\.api\.network\.test_networks\.NetworksIpV6Test\.test_external_network_visibility) # - (?:tempest\.api\.network\.test_networks\.NetworksTest\.test_external_network_visibility) # - (?:tempest\.scenario\.test_network_v6\.TestGettingAddress\.test_dualnet_multi_prefix_slaac) # - (?:tempest\.scenario\.test_network_v6\.TestGettingAddress\.test_dualnet_multi_prefix_dhcpv6_stateless) # - (?:tempest\.scenario\.test_network_basic_ops\.TestNetworkBasicOps\.test_update_router_admin_state) # - (?:tempest\.scenario\.test_network_basic_ops\.TestNetworkBasicOps\.test_router_rescheduling) # - (?:tempest\.scenario\.test_network_basic_ops\.TestNetworkBasicOps\.test_update_instance_port_admin_state) # whitelist: # - (?:tempest\.api\.identity\.admin\.v3\.test_groups\.GroupsV3TestJSON\.test_list_groups) # - (?:tempest\.api\.image\.v2\.test_images\.ListSharedImagesTest\.test_list_images_param_member_status) # - (?:tempest\.scenario\.test_encrypted_cinder_volumes\.TestEncryptedCinderVolumes\.test_encrypted_cinder_volumes_cryptsetup) # - (?:tempest\.scenario\.test_encrypted_cinder_volumes\.TestEncryptedCinderVolumes\.test_encrypted_cinder_volumes_luks) # - (?:tempest\.api\.network\.test_networks\.NetworksIpV6Test\.test_external_network_visibility) # - (?:tempest\.api\.network\.test_networks\.NetworksTest\.test_external_network_visibility) # - (?:tempest\.scenario\.test_network_v6\.TestGettingAddress\.test_dualnet_multi_prefix_slaac) # - (?:tempest\.scenario\.test_network_v6\.TestGettingAddress\.test_dualnet_multi_prefix_dhcpv6_stateless) # - (?:tempest\.scenario\.test_network_basic_ops\.TestNetworkBasicOps\.test_update_router_admin_state) # - (?:tempest\.scenario\.test_network_basic_ops\.TestNetworkBasicOps\.test_router_rescheduling) # - (?:tempest\.scenario\.test_network_basic_ops\.TestNetworkBasicOps\.test_update_instance_port_admin_state) tempest: auth: # admin_username value set by configmap-etc admin_username: null # admin_password value set by configmap-etc admin_password: null # admin_project_name value set by configmap-etc admin_project_name: null # admin_domain_name value set by configmap-etc admin_domain_name: null use_dynamic_credentials: true dashboard: {} heat_plugin: # Username to use for non admin API requests username: null # Non admin API key to use when authenticating. password: null project_name: null # Username to use for admin API requests admin_username: null # Admin API key to use when authentication admin_password: null # Admin project name to use for admin API requests admin_project_name: null auth_version: 3 auth_url: null user_domain_name: null project_domain_name: null region: null identity: admin_domain_scope: false auth_version: v3 # region value set by configmap-etc region: null # uri_v3 value set by configmap-etc uri_v3: null identity-feature-enabled: api_v3: true # this value should be the same as the keystone chart conf.keystone.identity.domain_specific_drivers_enabled domain_specific_drivers: true image: http_image: "http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img" container_formats: bare disk_formats: raw network: project_networks_reachable: false shared_physical_network: true network-feature-enabled: floating_ips: true api_extensions: - default-subnetpools - network-ip-availability - network_availability_zone - auto-allocated-topology - ext-gw-mode - binding - agent - subnet_allocation - l3_agent_scheduler - tag - external-net - flavors - net-mtu - availability_zone - quotas - l3-ha - provider - multi-provider - address-scope - extraroute - subnet-service-types - standard-attr-timestamp - service-type - l3-flavors - port-security - extra_dhcp_opt - standard-attr-revisions - pagination - sorting - security-group - dhcp_agent_scheduler - router_availability_zone - rbac-policies - standard-attr-description - router - allowed-address-pairs - project-id - dvr service_available: cinder: true glance: true # The following services are marked as unavailable by default. The default # tempest image used includes a bug resulting in failed network tests that # wasn't fixed in newton. Swift is disabled by default as the swift chart # isn't complete heat: false neutron: false nova: false swift: false validation: connect_method: floating volume: disk_formats: raw backend_names: rbd1 storage_protocol: rbd catalog_type: volumev3 cleanup: force: false enabled: true tempest_logging: loggers: keys: - root - tempest handlers: keys: - stdout - "null" formatters: keys: - tests - default logger_root: level: DEBUG handlers: - 'null' logger_tempest: level: WARN propagate: 0 handlers: - stdout qualname: tempest handler_stdout: class: StreamHandler level: WARN args: (sys.stdout,) formatter: tests handler_null: class: logging.NullHandler formatter: default args: () formatter_tests: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" pvc: enabled: true name: pvc-tempest requests: storage: 2Gi storage_class: general secrets: identity: admin: tempest-keystone-admin tempest: tempest-keystone-user oci_image_registry: tempest: tempest-oci-image-registry tls: identity: api: public: keystone-tls-public internal: keystone-tls-api endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false tempest: username: tempest password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default tempest: role: admin region_name: RegionOne username: tempest password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 dashboard: name: horizon hosts: default: horizon-int public: horizon host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: null scheme: default: http port: web: default: 80 tls: identity: false manifests: configmap_bin: true configmap_etc: true job_image_repo_sync: true job_ks_user: true job_run_tests: true secret_keystone: true secret_registry: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: tests/dns-test.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v1 kind: Pod metadata: name: dns-test namespace: kube-system spec: containers: - image: busybox command: - sleep - "3600" imagePullPolicy: IfNotPresent name: busybox restartPolicy: Always ... ================================================ FILE: tests/pvc-test.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: batch/v1 kind: Job metadata: labels: version: v0.1.0 test: ceph name: ceph-test-job spec: template: spec: restartPolicy: OnFailure containers: - name: test image: docker.io/alpine:latest imagePullPolicy: Always command: - /bin/sh - -ec - | echo "Ceph PVC Mount Test Passed" volumeMounts: - name: ceph-mount mountPath: /mnt/ceph volumes: - name: ceph-mount persistentVolumeClaim: claimName: ceph-test ... --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: ceph-test spec: storageClassName: general accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi ... ================================================ FILE: tools/changelog.py ================================================ import argparse import os.path from collections import defaultdict from reno import config from reno import loader BEFORE_2024_2_0_NOTE = """Before 2024.2.0 all the OpenStack-Helm charts were versioned independently. Here we provide all the release notes for the chart for all versions before 2024.2.0. """ def _indent_for_list(text, prefix=' '): lines = text.splitlines() return '\n'.join([lines[0]] + [ prefix + l for l in lines[1:] ]) def chart_reports(loader, config, versions_to_include, title=None, charts=None): reports = defaultdict(list) file_contents = {} for version in versions_to_include: for filename, sha in loader[version]: body = loader.parse_note_file(filename, sha) file_contents[filename] = body for chart in charts: if title: reports[chart].append(f"# {title}") reports[chart].append('') for version in versions_to_include: if '-' in version: version_title = config.unreleased_version_title or version else: version_title = version reports[chart].append(f"## {version_title}") reports[chart].append('') if version == "2024.2.0": reports[chart].append(BEFORE_2024_2_0_NOTE) if config.add_release_date: reports[chart].append('Release Date: ' + loader.get_version_date(version)) reports[chart].append('') notefiles = loader[version] # Prepare not named section # 1. Get all files named *.yaml # and get section from all these files # 2. Get all files named common*.yaml and get # section from all these files is_content = False for fn, sha in notefiles: if os.path.basename(fn).startswith(chart) or \ os.path.basename(fn).startswith("common"): notes = file_contents[fn].get(chart, []) for n in notes: is_content = True reports[chart].append(f"- {_indent_for_list(n)}") # Add new line after unnamed section if it is not empty if is_content: reports[chart].append("") # Prepare named sections # 1. Get all files named *.yaml # and get all sections from all these files except # 2. Get all files named common*.yaml # and get all sections from all these files except for section in config.sections: is_content = False # Skip chart specific sections if section.name not in ["features", "isseus", "upgrade", "api", "security", "fixes"]: continue for fn, sha in notefiles: if os.path.basename(fn).startswith(chart) or \ os.path.basename(fn).startswith("common"): notes = file_contents[fn].get(section.name, []) if notes and not is_content: reports[chart].append(f"### {section.title}") reports[chart].append("") if notes: is_content = True for n in notes: reports[chart].append(f"- {_indent_for_list(n)}") # Add new line after the section if it is not empty if is_content: reports[chart].append("") report = reports[chart] reports[chart] = '\n'.join(report) return reports def main(): parser = argparse.ArgumentParser() parser.add_argument("--charts", nargs="+", default=[], help="Charts to generate release notes for") args = parser.parse_args() conf = config.Config(".", "releasenotes") with loader.Loader(conf) as ldr: versions = ldr.versions reports = chart_reports( ldr, conf, versions, title="Release notes", charts=args.charts, ) for chart in reports: with open(f"{chart}/CHANGELOG.md", "w") as f: f.write(reports[chart]) return if __name__ == "__main__": main() ================================================ FILE: tools/chart_version.sh ================================================ #!/bin/bash set -euo pipefail if [[ $# -lt 2 ]]; then echo "Usage: $0 " echo " - The chart directory." echo " - The base version must be .." echo " For example 2024.2.0" echo " Will be modified to 2024.2.+" echo " where is the number of commits since the tag" echo " equal to . If no such tag exists," echo " will be taken from ." exit 1 fi CHART_DIR=$1 BASE_VERSION=$2 MAJOR=$(echo "$BASE_VERSION" | cut -d. -f1) MINOR=$(echo "$BASE_VERSION" | cut -d. -f2) PATCH=$(echo "$BASE_VERSION" | cut -d. -f3) if git show-ref --tags "$BASE_VERSION" --quiet; then # if there is tag $BASE_VERSION, then we count the number of commits since the tag PATCH=$(git log --oneline "${BASE_VERSION}.." "$CHART_DIR" | wc -l | xargs) fi COMMIT_SHA=$(git rev-parse --short HEAD) echo "${MAJOR}.${MINOR}.${PATCH}+${COMMIT_SHA}" ================================================ FILE: tools/debug_sleep.sh ================================================ #!/bin/bash sleep 86400 ================================================ FILE: tools/deployment/baremetal/005-setup-nodes.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: We only want to run ceph and control plane components on the primary node for LABEL in openstack-control-plane ceph-osd ceph-mon ceph-mds ceph-rgw ceph-mgr; do kubectl label nodes ${LABEL}- --all --overwrite PRIMARY_NODE="$(kubectl get nodes -l openstack-helm-node-class=primary -o name | awk -F '/' '{ print $NF; exit }')" kubectl label node "${PRIMARY_NODE}" ${LABEL}=enabled done #NOTE: Build charts make all #NOTE: Deploy libvirt with vbmc then define domains to use as baremetal nodes : "${OSH_PATH:="../openstack-helm"}" make -C ${OSH_PATH} libvirt helm install ${OSH_PATH}/libvirt \ --namespace=libvirt \ --name=libvirt \ --set network.backend=null \ --set conf.ceph.enabled=false \ --set images.tags.libvirt=docker.io/openstackhelm/vbmc:centos-0.1 #NOTE: Wait for deploy sleep 5 #NOTE(portdirect): work around k8s not immedately assigning pods to nodes helm osh wait-for-pods libvirt #NOTE: Create domains and start vbmc for ironic to manage as baremetal nodes LIBVIRT_PODS=$(kubectl get --namespace libvirt pods \ -l application=libvirt,component=libvirt \ --no-headers -o name | awk -F '/' '{ print $NF }') rm -f /tmp/bm-hosts.txt || true for LIBVIRT_POD in ${LIBVIRT_PODS}; do TEMPLATE_MAC_ADDR="00:01:DE:AD:BE:EF" MAC_ADDR=$(printf '00:01:DE:%02X:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256))) LIBVIRT_POD_NODE=$(kubectl get -n libvirt pod "${LIBVIRT_POD}" -o json | jq -r '.spec.nodeName') LIBVIRT_NODE_IP=$(kubectl get node "${LIBVIRT_POD_NODE}" -o json | jq -r '.status.addresses[] | select(.type=="InternalIP").address') kubectl exec -n libvirt "${LIBVIRT_POD}" -- mkdir -p /var/lib/libvirt/images kubectl exec -n libvirt "${LIBVIRT_POD}" -- rm -f /var/lib/libvirt/images/vm-1.qcow2 || true kubectl exec -n libvirt "${LIBVIRT_POD}" -- qemu-img create -f qcow2 /var/lib/libvirt/images/vm-1.qcow2 5G kubectl exec -n libvirt "${LIBVIRT_POD}" -- chown -R qemu: /var/lib/libvirt/images/vm-1.qcow2 VM_DEF="$(sed "s|${TEMPLATE_MAC_ADDR}|${MAC_ADDR}|g" ./tools/deployment/baremetal/fake-baremetal-1.xml | base64 -w0)" kubectl exec -n libvirt "${LIBVIRT_POD}" -- sh -c "echo ${VM_DEF} | base64 -d > /tmp/fake-baremetal-1.xml" kubectl exec -n libvirt "${LIBVIRT_POD}" -- sh -c "virsh undefine fake-baremetal-1 || true" kubectl exec -n libvirt "${LIBVIRT_POD}" -- virsh define /tmp/fake-baremetal-1.xml kubectl exec -n libvirt "${LIBVIRT_POD}" -- sh -c "vbmc delete fake-baremetal-1 || true" kubectl exec -n libvirt "${LIBVIRT_POD}" -- vbmc add fake-baremetal-1 --address "${LIBVIRT_NODE_IP}" kubectl exec -n libvirt "${LIBVIRT_POD}" -- sh -c "nohup vbmc start fake-baremetal-1 &>/dev/null &" kubectl exec -n libvirt "${LIBVIRT_POD}" -- virsh list --all kubectl exec -n libvirt "${LIBVIRT_POD}" -- vbmc show fake-baremetal-1 echo "${LIBVIRT_NODE_IP} ${MAC_ADDR}" >> /tmp/bm-hosts.txt done #NOTE: Deploy OvS to connect nodes to the deployment host : ${OSH_PATH:="../openstack-helm"} make -C ${OSH_PATH} openvswitch helm install ${OSH_PATH}/openvswitch \ --namespace=openstack \ --name=openvswitch #NOTE: Wait for deploy helm osh wait-for-pods openstack #NOTE: Setup GRE tunnels between deployment node and libvirt hosts OSH_IRONIC_PXE_DEV="${OSH_IRONIC_PXE_DEV:="ironic-pxe"}" OSH_IRONIC_PXE_ADDR="${OSH_IRONIC_PXE_ADDR:="172.24.6.1/24"}" MASTER_IP=$(kubectl get node "$(hostname -f)" -o json | jq -r '.status.addresses[] | select(.type=="InternalIP").address') NODE_IPS=$(kubectl get nodes -o json | jq -r '.items[].status.addresses[] | select(.type=="InternalIP").address' | sort -V) OVS_VSWITCHD_PODS=$(kubectl get --namespace openstack pods \ -l application=openvswitch,component=openvswitch-vswitchd \ --no-headers -o name | awk -F '/' '{ print $NF }') for OVS_VSWITCHD_POD in ${OVS_VSWITCHD_PODS}; do kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- ovs-vsctl add-br "${OSH_IRONIC_PXE_DEV}" if [ "x$(kubectl --namespace openstack get pod "${OVS_VSWITCHD_POD}" -o json | jq -r '.spec.nodeName')" == "x$(hostname -f)" ] ; then COUNTER=0 for NODE_IP in ${NODE_IPS}; do if ! [ "x${MASTER_IP}" == "x${NODE_IP}" ]; then kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- ovs-vsctl add-port "${OSH_IRONIC_PXE_DEV}" "gre${COUNTER}" \ -- set interface "gre${COUNTER}" type=gre options:remote_ip="${NODE_IP}" let COUNTER=COUNTER+1 fi done kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- ip addr add "${OSH_IRONIC_PXE_ADDR}" dev "${OSH_IRONIC_PXE_DEV}" #NOTE(portdirect): for simplity assume we are using the default dev # for tunnels, and a MTU overhead of 50 MASTER_NODE_DEV="$(kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- ip -4 route list 0/0 | awk '{ print $5; exit }')" MASTER_NODE_MTU="$(kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- cat "/sys/class/net/${MASTER_NODE_DEV}/mtu")" kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- ip link set dev ${OSH_IRONIC_PXE_DEV} mtu $((MASTER_NODE_MTU - 50)) kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- ip link set "${OSH_IRONIC_PXE_DEV}" up else kubectl exec --namespace openstack "${OVS_VSWITCHD_POD}" \ -- ovs-vsctl add-port "${OSH_IRONIC_PXE_DEV}" gre0 \ -- set interface gre0 type=gre options:remote_ip="${MASTER_IP}" fi done #NOTE: Set up the ${OSH_IRONIC_PXE_DEV} to forward traffic DEFAULT_ROUTE_DEV="$(sudo ip -4 route list 0/0 | awk '{ print $5; exit }')" sudo iptables -t nat -A POSTROUTING -o "${DEFAULT_ROUTE_DEV}" -j MASQUERADE sudo iptables -A FORWARD -i "${DEFAULT_ROUTE_DEV}" -o "${OSH_IRONIC_PXE_DEV}" -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i "${OSH_IRONIC_PXE_DEV}" -o "${DEFAULT_ROUTE_DEV}" -j ACCEPT ================================================ FILE: tools/deployment/baremetal/010-setup-client.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe sudo -H -E pip3 install \ -c${UPPER_CONSTRAINTS_FILE:=https://releases.openstack.org/constraints/upper/master} \ python-openstackclient python-heatclient python-ironicclient sudo -H mkdir -p /etc/openstack cat << EOF | sudo -H tee -a /etc/openstack/clouds.yaml clouds: openstack_helm: region_name: RegionOne identity_api_version: 3 auth: username: 'admin' password: 'password' project_name: 'admin' project_domain_name: 'default' user_domain_name: 'default' auth_url: 'http://keystone.openstack.svc.cluster.local/v3' EOF sudo -H chown -R $(id -un): /etc/openstack #NOTE: Build charts make all ================================================ FILE: tools/deployment/baremetal/110-compute-kit.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Lint and package chart make neutron make ironic make nova #NOTE: Deploy neutron #NOTE(portdirect): for simplicity we will assume the default route device # should be used for tunnels NETWORK_TUNNEL_DEV="$(sudo ip -4 route list 0/0 | awk '{ print $5; exit }')" OSH_IRONIC_PXE_DEV="ironic-pxe" OSH_IRONIC_PXE_PYSNET="ironic" tee /tmp/neutron.yaml << EOF network: interface: tunnel: "${NETWORK_TUNNEL_DEV}" labels: ovs: node_selector_key: openstack-helm-node-class node_selector_value: primary agent: dhcp: node_selector_key: openstack-helm-node-class node_selector_value: primary l3: node_selector_key: openstack-helm-node-class node_selector_value: primary metadata: node_selector_key: openstack-helm-node-class node_selector_value: primary pod: replicas: server: 1 conf: neutron: DEFAULT: l3_ha: False max_l3_agents_per_router: 1 l3_ha_network_type: vxlan dhcp_agents_per_network: 1 plugins: ml2_conf: ml2_type_flat: flat_networks: public,${OSH_IRONIC_PXE_PYSNET} openvswitch_agent: agent: tunnel_types: vxlan ovs: bridge_mappings: "external:br-ex,${OSH_IRONIC_PXE_PYSNET}:${OSH_IRONIC_PXE_DEV}" EOF helm upgrade --install neutron ./neutron \ --namespace=openstack \ --values=/tmp/neutron.yaml \ --set manifests.network_policy=true \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_NEUTRON} tee /tmp/ironic.yaml << EOF labels: node_selector_key: openstack-helm-node-class node_selector_value: primary network: pxe: device: "${OSH_IRONIC_PXE_DEV}" neutron_provider_network: "${OSH_IRONIC_PXE_PYSNET}" conf: ironic: DEFAULT: debug: true conductor: automated_clean: "false" deploy: shred_final_overwrite_with_zeros: "false" EOF helm upgrade --install ironic ./ironic \ --namespace=openstack \ --values=/tmp/ironic.yaml \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_IRONIC} tee /tmp/nova.yaml << EOF labels: agent: compute_ironic: node_selector_key: openstack-helm-node-class node_selector_value: primary conf: nova: DEFAULT: debug: true #force_config_drive: false scheduler_host_manager: ironic_host_manager compute_driver: ironic.IronicDriver firewall_driver: nova.virt.firewall.NoopFirewallDriver #ram_allocation_ratio: 1.0 reserved_host_memory_mb: 0 scheduler_use_baremetal_filters: true baremetal_scheduler_default_filters: "RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter" filter_scheduler: scheduler_tracks_instance_changes: false #scheduler_host_subset_size: 9999 scheduler: discover_hosts_in_cells_interval: 120 manifests: cron_job_cell_setup: true daemonset_compute: false daemonset_libvirt: false statefulset_compute_ironic: true job_cell_setup: true EOF # Deploy Nova helm upgrade --install nova ./nova \ --namespace=openstack \ --values=/tmp/nova.yaml \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_NOVA} #NOTE: Wait for deploy helm osh wait-for-pods openstack #NOTE: Validate Deployment info export OS_CLOUD=openstack_helm openstack service list sleep 30 openstack network agent list openstack baremetal driver list openstack compute service list ================================================ FILE: tools/deployment/baremetal/800-create-baremetal-host-aggregate.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe export OS_CLOUD=openstack_helm export OSH_IRONIC_NODE_ARCH=${OSH_IRONIC_NODE_ARCH:="x86_64"} #NOTE: setup a host aggregate for baremetal nodes to use openstack aggregate create \ --property baremetal=true \ --property cpu_arch=${OSH_IRONIC_NODE_ARCH} \ baremetal-hosts IRONIC_COMPUTES=$(openstack compute service list | grep compute | grep $(hostname) | grep -v down | awk '{print $6}') for COMPUTE in $IRONIC_COMPUTES; do openstack aggregate add host baremetal-hosts ${COMPUTE} done ================================================ FILE: tools/deployment/baremetal/810-register-baremetal-nodes.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe export OS_CLOUD=openstack_helm export OSH_IRONIC_NODE_DISC=${OSH_IRONIC_NODE_DISC:="5"} export OSH_IRONIC_NODE_RAM=${OSH_IRONIC_NODE_RAM:="4096"} export OSH_IRONIC_NODE_CPU=${OSH_IRONIC_NODE_CPU:="2"} export OSH_IRONIC_NODE_ARCH=${OSH_IRONIC_NODE_ARCH:="x86_64"} #NOTE: Register the baremetal nodes with ironic DEPLOY_VMLINUZ_UUID=$(openstack image show ironic-agent.kernel -f value -c id) DEPLOY_INITRD_UUID=$(openstack image show ironic-agent.initramfs -f value -c id) MASTER_IP=$(kubectl get node $(hostname -f) -o json | jq -r '.status.addresses[] | select(.type=="InternalIP").address') while read NODE_DETAIL_RAW; do NODE_DETAIL=($(echo ${NODE_DETAIL_RAW})) NODE_BMC_IP=${NODE_DETAIL[0]} NODE_MAC=${NODE_DETAIL[1]} if [ "$(kubectl get node -o name | wc -l)" -eq "1" ] || [ "x${MASTER_IP}" != "x${NODE_BMC_IP}" ]; then BM_NODE=$(openstack baremetal node create \ --driver agent_ipmitool \ --driver-info ipmi_username=admin \ --driver-info ipmi_password=password \ --driver-info ipmi_address="${NODE_BMC_IP}" \ --driver-info ipmi_port=623 \ --driver-info deploy_kernel=${DEPLOY_VMLINUZ_UUID} \ --driver-info deploy_ramdisk=${DEPLOY_INITRD_UUID} \ --property local_gb=${OSH_IRONIC_NODE_DISC} \ --property memory_mb=${OSH_IRONIC_NODE_RAM} \ --property cpus=${OSH_IRONIC_NODE_CPU} \ --property cpu_arch=${OSH_IRONIC_NODE_ARCH} \ -f value -c uuid) openstack baremetal node manage "${BM_NODE}" openstack baremetal port create --node ${BM_NODE} "${NODE_MAC}" openstack baremetal node validate "${BM_NODE}" openstack baremetal node provide "${BM_NODE}" openstack baremetal node show "${BM_NODE}" fi done < /tmp/bm-hosts.txt #NOTE: Wait for our baremetal nodes to become avalible for provisioning function wait_for_ironic_node { # Default wait timeout is 1200 seconds set +x end=$(date +%s) if ! [ -z $2 ]; then end=$((end + $2)) else end=$((end + 1200)) fi while true; do STATE=$(openstack baremetal node show $1 -f value -c provision_state) [ "x${STATE}" == "xavailable" ] && break sleep 1 now=$(date +%s) [ $now -gt $end ] && echo "Node did not come up in time" && openstack baremetal node show $1 && exit -1 done set -x } for NODE in $(openstack baremetal node list -f value -c UUID); do wait_for_ironic_node $NODE done openstack baremetal node list ================================================ FILE: tools/deployment/baremetal/820-create-baremetal-flavor.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe export OS_CLOUD=openstack_helm export OSH_IRONIC_NODE_DISC=${OSH_IRONIC_NODE_DISC:="5"} export OSH_IRONIC_NODE_RAM=${OSH_IRONIC_NODE_RAM:="4096"} export OSH_IRONIC_NODE_CPU=${OSH_IRONIC_NODE_CPU:="2"} export OSH_IRONIC_NODE_ARCH=${OSH_IRONIC_NODE_ARCH:="x86_64"} #NOTE: Create a flavor assocated with our baremetal nodes openstack flavor create \ --disk ${OSH_IRONIC_NODE_DISC} \ --ram ${OSH_IRONIC_NODE_RAM} \ --vcpus ${OSH_IRONIC_NODE_CPU} \ --property cpu_arch=${OSH_IRONIC_NODE_ARCH} \ --property baremetal=true \ baremetal ================================================ FILE: tools/deployment/baremetal/900-use-it.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Validate Deployment info export OS_CLOUD=openstack_helm export OSH_VM_KEY_STACK="heat-vm-key" # Setup SSH Keypair in Nova mkdir -p ${HOME}/.ssh openstack keypair create --private-key ${HOME}/.ssh/osh_key ${OSH_VM_KEY_STACK} chmod 600 ${HOME}/.ssh/osh_key # Deploy heat stack to provision node openstack stack create --wait --timeout 15 \ -t ./tools/deployment/baremetal/heat-basic-bm-deployment.yaml \ heat-basic-bm-deployment FLOATING_IP=$(openstack stack output show \ heat-basic-bm-deployment \ ip \ -f value -c output_value) # Wait for the nodes SSH port to come up function wait_for_ssh_port { # Default wait timeout is 300 seconds set +x end=$(date +%s) if ! [ -z $2 ]; then end=$((end + $2)) else end=$((end + 300)) fi while true; do # Use Nmap as its the same on Ubuntu and RHEL family distros nmap -Pn -p22 $1 | awk '$1 ~ /22/ {print $2}' | grep -q 'open' && \ break || true sleep 1 now=$(date +%s) [ $now -gt $end ] && echo "Could not connect to $1 port 22 in time" && exit -1 done set -x } wait_for_ssh_port $FLOATING_IP # SSH into the VM and check it can reach the outside world ssh-keyscan "$FLOATING_IP" >> ~/.ssh/known_hosts BM_GATEWAY="$(ssh -i ${HOME}/.ssh/osh_key cirros@${FLOATING_IP} ip -4 route list 0/0 | awk '{ print $3; exit }')" ssh -i ${HOME}/.ssh/osh_key cirros@${FLOATING_IP} ping -q -c 1 -W 2 ${BM_GATEWAY} # Check the VM can reach the metadata server ssh -i ${HOME}/.ssh/osh_key cirros@${FLOATING_IP} curl --verbose --connect-timeout 5 169.254.169.254 ================================================ FILE: tools/deployment/baremetal/fake-baremetal-1.xml ================================================ fake-baremetal-1 4096 4 /machine hvm destroy restart restart /usr/libexec/qemu-kvm
================================================ FILE: tools/deployment/baremetal/heat-basic-bm-deployment.yaml ================================================ --- heat_template_version: 2016-10-14 parameters: baremetal_net: type: string default: baremetal baremetal_subnet: type: string default: baremetal image: type: string default: Cirros 0.6.2 64-bit flavor: type: string default: baremetal ssh_key: type: string default: heat-vm-key resources: server: type: OS::Nova::Server properties: image: get_param: image flavor: get_param: flavor key_name: get_param: ssh_key networks: - port: get_resource: server_port user_data_format: RAW server_port: type: OS::Neutron::Port properties: network: get_param: baremetal_net fixed_ips: - subnet: get_param: baremetal_subnet port_security_enabled: false outputs: ip: value: get_attr: - server_port - fixed_ips - 0 - ip_address ... ================================================ FILE: tools/deployment/ceph/ceph-adapter-rook.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} helm upgrade --install ceph-adapter-rook ${OSH_HELM_REPO}/ceph-adapter-rook \ --namespace=openstack #NOTE: Wait for deploy helm osh wait-for-pods openstack ================================================ FILE: tools/deployment/ceph/ceph-ns-activate.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} #NOTE: Deploy command tee /tmp/ceph-openstack-config.yaml < /tmp/ceph-fs-uuid.txt CEPH_FS_ID="$(cat /tmp/ceph-fs-uuid.txt)" #NOTE(portdirect): to use RBD devices with Ubuntu kernels < 4.5 this # should be set to 'hammer' . /etc/os-release if [ "x${ID}" == "xcentos" ] || \ ([ "x${ID}" == "xubuntu" ] && \ dpkg --compare-versions "$(uname -r)" "lt" "4.5"); then CRUSH_TUNABLES=hammer else CRUSH_TUNABLES=null fi tee /tmp/rook.yaml < /dev/null 2>&1; then kubectl wait --namespace=ceph --for=condition=ready "pod/$MON_POD" --timeout=60s && \ { MON_PODS_READY=$(($MON_PODS_READY+1)); } || \ echo "Pod $MON_POD not ready, skipping..." else echo "Pod $MON_POD not found, skipping..." fi done if [[ ${MON_PODS_READY} == ${MON_PODS_NUM} ]]; then echo "Monitor pods are ready. Moving on." break; fi done echo "=========== CEPH K8S PODS LIST ============" kubectl get pods -n rook-ceph -o wide kubectl get pods -n ceph -o wide #NOTE: Wait for deploy RGW_POD=$(kubectl get pods \ --namespace=ceph \ --selector="app=rook-ceph-rgw" \ --no-headers | awk '{print $1; exit}') wait_start_time=$(date +%s) while [[ -z "${RGW_POD}" && $(($(date +%s) - $wait_start_time)) -lt 1800 ]] do sleep 30 date +'%Y-%m-%d %H:%M:%S' TOOLS_POD=$(kubectl get pods \ --namespace=ceph \ --selector="app=rook-ceph-tools" \ --no-headers | grep Running | awk '{ print $1; exit }') if [[ -z "${TOOLS_POD}" ]]; then echo "No running rook-ceph-tools pod found. Waiting..." continue fi echo "=========== CEPH STATUS ============" kubectl exec -n ceph ${TOOLS_POD} -- ceph -s || echo "Could not get cluster status. Might be a temporary network issue." echo "=========== CEPH OSD POOL LIST ============" kubectl exec -n ceph ${TOOLS_POD} -- ceph osd pool ls || echo "Could not get list of pools. Might be a temporary network issue." echo "=========== CEPH K8S PODS LIST ============" kubectl get pods -n ceph -o wide RGW_POD=$(kubectl get pods \ --namespace=ceph \ --selector="app=rook-ceph-rgw" \ --no-headers | awk '{print $1; exit}') done helm osh wait-for-pods ceph #NOTE: Validate deploy TOOLS_POD=$(kubectl get pods \ --namespace=ceph \ --selector="app=rook-ceph-tools" \ --no-headers | grep Running | awk '{ print $1; exit }') kubectl exec -n ceph ${TOOLS_POD} -- ceph -s ================================================ FILE: tools/deployment/ceph/ceph.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${CEPH_OSD_DATA_DEVICE:="/dev/loop100"} : ${POD_NETWORK_CIDR:="10.244.0.0/16"} : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} NUMBER_OF_OSDS="$(kubectl get nodes -l ceph-osd=enabled --no-headers | wc -l)" #NOTE: Deploy command [ -s /tmp/ceph-fs-uuid.txt ] || uuidgen > /tmp/ceph-fs-uuid.txt CEPH_FS_ID="$(cat /tmp/ceph-fs-uuid.txt)" #NOTE(portdirect): to use RBD devices with Ubuntu kernels < 4.5 this # should be set to 'hammer' . /etc/os-release if [ "x${ID}" == "xcentos" ] || \ ([ "x${ID}" == "xubuntu" ] && \ dpkg --compare-versions "$(uname -r)" "lt" "4.5"); then CRUSH_TUNABLES=hammer else CRUSH_TUNABLES=null fi tee /tmp/ceph.yaml < /tmp/ceph-fs-uuid.txt CEPH_FS_ID="$(cat /tmp/ceph-fs-uuid.txt)" #NOTE(portdirect): to use RBD devices with Ubuntu kernels < 4.5 this # should be set to 'hammer' . /etc/os-release if [ "x${ID}" == "xcentos" ] || \ ([ "x${ID}" == "xubuntu" ] && \ dpkg --compare-versions "$(uname -r)" "lt" "4.5"); then CRUSH_TUNABLES=hammer else CRUSH_TUNABLES=null fi # Most of PV fields are immutable and in case of CSI RBD plugin they refer # to secrets which were used for RBD provisioner and RBD attacher. These fields # can not be updated later. # So for testing purposes we assume legacy Ceph cluster is deployed with # the following secret names for the CSI plugin # - rook-csi-rbd-provisioner # - rook-csi-rbd-node # These exact secret names are used by Rook by default for CSI plugin and # and after migration PVs will be adopted by the new Rook Ceph cluster. # # Alternatively if we deploy legacy Ceph cluster with the default values # then we could later force Rook to use same CSI secret names as used for # legacy cluster. For example pvc-ceph-conf-combined-storageclass secret # name is used by default in legacy charts. # # Same is for CSI provisioner drivername option. For testing we deploy # legacy cluster with the drivername set to rook-ceph.rbd.csi.ceph.com # while default value is ceph.rbd.csi.ceph.com. # This is also for the sake of smooth adoption of PVs. tee /tmp/ceph.yaml < /tmp/mon-a.keyring export MON_HOST=$(kubectl -n ${CEPH_NAMESPACE} get pods -l app=rook-ceph-mon -o json | jq -r '.items[0].spec.nodeName') export MON_HOST_IP=$(kubectl get nodes -o json | jq -r '.items[] | select(.metadata.name == env.MON_HOST) | .status.addresses | .[] | select(.type == "InternalIP") | .address') # Shut down the Rook operator, delete the rook-ceph deployments, and get the new rook-ceph-mon IP address kubectl -n ${ROOK_CEPH_NAMESPACE} scale deploy rook-ceph-operator --replicas=0 kubectl -n ${CEPH_NAMESPACE} get deploy -o json | jq -r '.items[] | select(.metadata.name != "rook-ceph-tools") | .metadata.name' | xargs kubectl -n ${CEPH_NAMESPACE} delete deploy #MON_IP=$(kubectl -n ${CEPH_NAMESPACE} get service rook-ceph-mon-a -o json | jq -r '.spec.clusterIP') MON_IP=$(kubectl -n ${CEPH_NAMESPACE} get cm rook-ceph-mon-endpoints -o jsonpath='{.data.data}' | sed 's/.=//g' | awk -F: '{print $1}') wait_for_terminate # Download the old mon store and update its key to the new one ssh ${MON_HOST_IP} "sudo rm -rf /var/lib/rook/mon-a/data" ssh ${OLD_MON_HOST_IP} "sudo chmod -R a+rX /var/lib/openstack-helm/ceph/mon/mon/ceph-${OLD_MON_HOST}" scp -rp ${OLD_MON_HOST_IP}:/var/lib/openstack-helm/ceph/mon/mon/ceph-${OLD_MON_HOST} /tmp mv /tmp/ceph-${OLD_MON_HOST} /tmp/mon-a grep -A2 "\[mon\.\]" /tmp/mon-a.keyring > /tmp/mon-a/keyring # Generate a script to rewrite the monmap in the old mon store cat > /tmp/mon-a/fix-monmap.sh < /tmp/keyring" kubectl -n ${CEPH_NAMESPACE} exec ${TOOLS_POD} -- bash -c "echo -e \" key = ${CLIENT_KEY}\" >> /tmp/keyring" kubectl -n ${CEPH_NAMESPACE} exec ${TOOLS_POD} -- bash -c "echo -e ' caps mds = \"allow *\"' >> /tmp/keyring" kubectl -n ${CEPH_NAMESPACE} exec ${TOOLS_POD} -- bash -c "echo -e ' caps mon = \"allow *\"' >> /tmp/keyring" kubectl -n ${CEPH_NAMESPACE} exec ${TOOLS_POD} -- bash -c "echo -e ' caps osd = \"allow *\"' >> /tmp/keyring" kubectl -n ${CEPH_NAMESPACE} exec ${TOOLS_POD} -- bash -c "echo -e ' caps mgr = \"allow *\"' >> /tmp/keyring" kubectl -n ${CEPH_NAMESPACE} exec ${TOOLS_POD} -- ceph auth import -i /tmp/keyring kubectl -n ${CEPH_NAMESPACE} exec ${TOOLS_POD} -- rm /tmp/keyring # Remove the auth config options to re-enable authentication kubectl -n ${CEPH_NAMESPACE} get cm rook-config-override -o yaml | \ sed '/ auth_cluster_required = none/d' | \ sed '/ auth_service_required = none/d' | \ sed '/ auth_client_required = none/d' | \ sed '/ auth_supported = none/d' | \ kubectl apply -f - # Restart the Rook operator and Ceph cluster with the new config kubectl -n ${ROOK_CEPH_NAMESPACE} scale deploy rook-ceph-operator --replicas=0 kubectl -n ${CEPH_NAMESPACE} get deploy -o json | jq -r '.items[] | select(.metadata.name != "rook-ceph-tools") | .metadata.name' | xargs kubectl -n ${CEPH_NAMESPACE} delete deploy wait_for_terminate kubectl -n ${ROOK_CEPH_NAMESPACE} scale deploy rook-ceph-operator --replicas=1 wait_for_full_rook_deployment # Scale the mon and mgr deployments to original replica counts kubectl -n ${CEPH_NAMESPACE} get cephcluster ceph -o json | \ jq ".spec.mon.count = ${MON_COUNT} | .spec.mgr.count = ${MGR_COUNT}" | \ kubectl apply -f - wait_for_health_checks ${CEPH_NAMESPACE} ${TOOLS_POD} ================================================ FILE: tools/deployment/ceph/migrate-values.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe ROOK_RELEASE=v1.19.3 : ${CEPH_OSD_DATA_DEVICE:="/dev/loop100"} tee /tmp/rook-operator.yaml < ca-csr.json < cfssl.json < intermediate-ca.json < /tmp/ca-issuers.yaml <> ${HOME}/.bashrc </dev/null|| sudo docker pull $IMAGE done fi done ================================================ FILE: tools/deployment/common/rally-reports.yaml ================================================ --- apiVersion: batch/v1 kind: Job metadata: labels: version: v0.1.0 name: get-rally-data spec: template: spec: restartPolicy: OnFailure containers: - name: get-rally-data image: docker.io/alpine:latest imagePullPolicy: Always command: - /bin/sh - -ec - | cp -av /mnt/rally-pvc/* /mnt/rally-data volumeMounts: - name: pvc-rally mountPath: /mnt/rally-pvc - name: rally-data mountPath: /mnt/rally-data volumes: - name: pvc-rally persistentVolumeClaim: claimName: pvc-rally - name: rally-data hostPath: path: /tmp/rally-data ... ================================================ FILE: tools/deployment/common/run-helm-tests.sh ================================================ #!/bin/bash set -x APPLICATION=$1 RELEASE_GROUP=${2:-${APPLICATION}} NAMESPACE=${3:-openstack} : ${HELM_TESTS_TRIES:=2} timeout=${OSH_TEST_TIMEOUT:-900} run_tests() { # Delete the test pod if it still exists kubectl delete pods -l application=${APPLICATION},release_group=${RELEASE_GROUP},component=test --namespace=${NAMESPACE} --ignore-not-found helm test ${APPLICATION} --timeout ${timeout}s --namespace=${NAMESPACE} } for i in $(seq 1 ${HELM_TESTS_TRIES}); do echo "Run helm tests for ${APPLICATION}. Try #${i}" run_tests RC=$? [ ${RC} -eq "0" ] && break done exit ${RC} ================================================ FILE: tools/deployment/common/setup-certificates.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe CURRENT_DIR=$(pwd) CFSSLURL=https://pkg.cfssl.org/R1.2 TDIR=/tmp/certs rm -rf $TDIR mkdir -p $TDIR/bin cd $TDIR curl -sSL -o bin/cfssl $CFSSLURL/cfssl_linux-amd64 curl -sSL -o bin/cfssljson $CFSSLURL/cfssljson_linux-amd64 chmod +x bin/{cfssl,cfssljson} export PATH=$PATH:./bin OSH_CONFIG_ROOT="/etc/openstack-helm" OSH_CA_ROOT="${OSH_CONFIG_ROOT}/certs/ca" OSH_SERVER_TLS_ROOT="${OSH_CONFIG_ROOT}/certs/server" sudo mkdir -p ${OSH_CONFIG_ROOT} sudo chown $(whoami): -R ${OSH_CONFIG_ROOT} mkdir -p "${OSH_CA_ROOT}" tee ${OSH_CA_ROOT}/ca-config.json << EOF { "signing": { "default": { "expiry": "24h" }, "profiles": { "server": { "expiry": "24h", "usages": [ "signing", "key encipherment", "server auth" ] } } } } EOF tee ${OSH_CA_ROOT}/ca-csr.json << EOF { "CN": "ACME Company", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "SomeState", "ST": "SomeCity", "O": "SomeOrg", "OU": "SomeUnit" } ] } EOF cfssl gencert -initca ${OSH_CA_ROOT}/ca-csr.json | cfssljson -bare ${OSH_CA_ROOT}/ca - function check_cert_and_key () { TLS_CERT=$1 TLS_KEY=$2 openssl x509 -inform pem -in ${TLS_CERT} -noout -text CERT_MOD="$(openssl x509 -noout -modulus -in ${TLS_CERT})" KEY_MOD="$(openssl rsa -noout -modulus -in ${TLS_KEY})" if ! [ "${CERT_MOD}" = "${KEY_MOD}" ]; then echo "Failure: TLS private key does not match this certificate." exit 1 else CERT_MOD="" KEY_MOD="" echo "Pass: ${TLS_CERT} is valid with ${TLS_KEY}" fi } check_cert_and_key ${OSH_CA_ROOT}/ca.pem ${OSH_CA_ROOT}/ca-key.pem DOMAIN=openstackhelm.test for HOSTNAME in "swift" "keystone" "heat" "cloudformation" "horizon" "glance" "cinder" "nova" "placement" "novnc" "metadata" "neutron" "barbican"; do FQDN="${HOSTNAME}.${DOMAIN}" OSH_SERVER_CERTS="${OSH_SERVER_TLS_ROOT}/${HOSTNAME}" mkdir -p "${OSH_SERVER_CERTS}" tee ${OSH_SERVER_CERTS}/server-csr-${HOSTNAME}.json < ${DEVS_PRE_ATTACH} openstack stack show "heat-vm-volume-attach" || \ # Create and attach a block device to the instance openstack stack create --wait \ --parameter instance_uuid=${INSTANCE_ID} \ -t ${HEAT_DIR}/heat-vm-volume-attach.yaml \ heat-vm-volume-attach # Get the devices that are present on the instance DEVS_POST_ATTACH=$(mktemp) ssh -i ${SSH_DIR}/osh_key ${IMAGE_USER}@${FLOATING_IP} lsblk > ${DEVS_POST_ATTACH} # Check that we have the expected number of extra devices on the instance post attach if ! [ "$(comm -13 ${DEVS_PRE_ATTACH} ${DEVS_POST_ATTACH} | wc -l)" -eq "1" ]; then echo "Volume not successfully attached" exit 1 fi fi ================================================ FILE: tools/deployment/component/aodh/aodh.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_AODH:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c aodh ${FEATURES})"} #NOTE: Wait for deploy helm upgrade --install aodh ${OSH_HELM_REPO}/aodh \ --namespace=openstack \ --set pod.replicas.api=2 \ --set pod.replicas.evaluator=2 \ --set pod.replicas.listener=2 \ --set pod.replicas.notifier=2 \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_AODH} #NOTE: Wait for deploy helm osh wait-for-pods openstack #NOTE: Validate Deployment info export OS_CLOUD=openstack_helm openstack service list ================================================ FILE: tools/deployment/component/barbican/barbican.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_BARBICAN:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c barbican ${FEATURES})"} : ${RUN_HELM_TESTS:="yes"} #NOTE: Deploy command helm upgrade --install barbican ${OSH_HELM_REPO}/barbican \ --namespace=openstack \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_BARBICAN} #NOTE: Wait for deploy helm osh wait-for-pods openstack # Run helm test if [ "x${RUN_HELM_TESTS}" != "xno" ]; then ./tools/deployment/common/run-helm-tests.sh barbican fi ================================================ FILE: tools/deployment/component/blazar/blazar.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_BLAZAR:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c blazar ${FEATURES})"} : ${BLAZAR_RELEASE_NAME:="blazar"} : ${BLAZAR_NAMESPACE:="openstack"} #NOTE: Wait for deploy echo "Deploying OpenStack Blazar" helm upgrade --install ${BLAZAR_RELEASE_NAME} ${OSH_HELM_REPO}/blazar \ --namespace ${BLAZAR_NAMESPACE} \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_BLAZAR} #NOTE: Wait for deploy helm osh wait-for-pods ${BLAZAR_NAMESPACE} echo "OpenStack Blazar deployment complete." #NOTE: Validate Deployment info export OS_CLOUD=openstack_helm openstack service list # Run helm test if [ "x${RUN_HELM_TESTS}" != "xno" ]; then ./tools/deployment/common/run-helm-tests.sh blazar fi ================================================ FILE: tools/deployment/component/blazar/blazar_smoke_test.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -ex export OS_CLOUD=openstack_helm BLAZAR_DIR="$(readlink -f ./tools/deployment/component/blazar)" SSH_DIR="${HOME}/.ssh" OPENSTACK_CLIENT_CONTAINER_EXTRA_ARGS="${OPENSTACK_CLIENT_CONTAINER_EXTRA_ARGS} -v ${BLAZAR_DIR}:${BLAZAR_DIR} -v ${SSH_DIR}:${SSH_DIR}" export OPENSTACK_CLIENT_CONTAINER_EXTRA_ARGS echo "Test: Starting the process to delete all existing Blazar leases, if any" lease_ids=$(openstack reservation lease list -c id -f value) sleep 2 # Check if the list of leases is empty. if [ -z "$lease_ids" ]; then echo "Test: No leases found to delete" else echo "Test: The following lease IDs will be deleted:" echo "$lease_ids" echo "-------------------------------------" while IFS= read -r lease_id; do echo "Test: Deleting lease with ID: $lease_id" openstack reservation lease delete "$lease_id" sleep 2 echo "Test: Lease $lease_id deleted." done <<< "$lease_ids" echo "-------------------------------------" echo "Test: All Blazar leases have been successfully deleted" fi echo "Test: Starting the process to delete all existing Blazar hosts, if any" openstack host list sleep 2 openstack reservation host list sleep 2 host_ids=$(openstack reservation host list -c id -f value) sleep 2 # Check if the list of hosts is empty. if [ -z "$host_ids" ]; then echo "Test: No hosts found to delete" else echo "Test: The following host IDs will be deleted:" echo "$host_ids" echo "-------------------------------------" while IFS= read -r host_id; do # Get the list of servers on the specified host SERVER_LIST=$(openstack server list --host "$host_id" -f value -c id) sleep 2 # Check if any servers were found if [ -z "$SERVER_LIST" ]; then echo "No servers found on host '$host_id'" else # Delete all servers on the host echo "Deleting servers on host '$host_id'" for SERVER_ID in $SERVER_LIST; do echo "Deleting server $SERVER_ID" openstack server delete "$SERVER_ID" done echo "All servers on host '$host_id' have been deleted" fi echo "Test: Deleting host with ID: $host_id" openstack reservation host delete "$host_id" sleep 2 echo "Test: Host $host_id deleted" done <<< "$host_ids" echo "-------------------------------------" echo "Test: All Blazar hosts have been successfully deleted" fi echo "Test: list all the services" openstack service list sleep 2 echo "Test: list all the endpoints" openstack endpoint list sleep 2 echo "Test: list all the hypervisors" openstack hypervisor list sleep 2 echo "Extract the first available compute host name from the list of hosts" FIRST_COMPUTE_HOST=$(openstack host list | grep 'compute' | awk '{print $2}' | head -n 1) sleep 2 # A simple check to see if a host name was successfully found. if [ -z "$FIRST_COMPUTE_HOST" ]; then echo "Error: No compute host found in the list" exit 1 else echo "The first compute host found is: $FIRST_COMPUTE_HOST" fi sleep 2 # Set a variable for the aggregate name AGGREGATE_NAME="freepool" echo "Test: Checking if aggregate '${AGGREGATE_NAME}' already exists" AGGREGATE_FOUND=$(openstack aggregate list | grep " ${AGGREGATE_NAME} " | cut -d '|' -f 3 | tr -d ' ' 2>/dev/null || true) sleep 2 # Check if the AGGREGATE_FOUND variable is empty. if [ -z "$AGGREGATE_FOUND" ]; then echo "Test: Aggregate '${AGGREGATE_NAME}' not found, Creating it now" openstack aggregate create "${AGGREGATE_NAME}" sleep 5 # Check the exit status of the previous command. if [ $? -eq 0 ]; then echo "Test: Aggregate '${AGGREGATE_NAME}' created successfully" else echo "Test: Failed to create aggregate '${AGGREGATE_NAME}'" fi else echo "Test: Aggregate '${AGGREGATE_NAME}' already exists" fi sleep 2 echo "Test: list all the aggregates after creating/checking freepool aggregate" openstack aggregate list sleep 2 echo "Test: Add host into the Blazar freepool" openstack reservation host create $FIRST_COMPUTE_HOST sleep 5 echo "Test: Add extra capabilities to host to add other properties" openstack reservation host set --extra gpu=True $FIRST_COMPUTE_HOST sleep 2 echo "Test: list hosts in the blazar freepool after adding a host" openstack reservation host list sleep 2 # Get the current date in YYYY-MM-DD format, generate start and end dates current_date=$(date +%Y-%m-%d) start_date=$(date -d "$current_date + 1 day" +%Y-%m-%d\ 12:00) end_date=$(date -d "$current_date + 2 day" +%Y-%m-%d\ 12:00) echo "Test: Create a lease (compute host reservation)" openstack reservation lease create \ --reservation resource_type=physical:host,min=1,max=1,hypervisor_properties='[">=", "$vcpus", "2"]' \ --start-date "$start_date" \ --end-date "$end_date" \ lease-test-comp-host-res sleep 5 echo "Test: list leases after creating a lease" openstack reservation lease list sleep 2 echo "Test: list projects" openstack project list sleep 2 echo "Test: list flavors" openstack flavor list sleep 2 echo "Test: list images" openstack image list sleep 2 echo "Test: list networks" openstack network list sleep 2 # Get the flavor ID for m1.tiny FLAVOR_ID=$(openstack flavor show m1.tiny -f value -c id) sleep 2 # Get the image ID for Cirros 0.6.2 64-bit IMAGE_ID=$(openstack image show "Cirros 0.6.2 64-bit" -f value -c id) sleep 2 # --- Network --- # Check if a network named "net1" exists if ! openstack network show net1 &> /dev/null; then echo "Network 'net1' not found. Creating now" sleep 2 openstack network create net1 sleep 2 else echo "Network 'net1' already exists." fi NETWORK_ID=$(openstack network show net1 -f value -c id) sleep 2 # --- Subnet --- # Check if a subnet named "subnet1" exists if ! openstack subnet show subnet1 &> /dev/null; then echo "Subnet 'subnet1' not found. Creating now" sleep 2 openstack subnet create \ --network "$NETWORK_ID" \ --subnet-range 10.0.0.0/24 \ --allocation-pool start=10.0.0.2,end=10.0.0.254 \ --gateway 10.0.0.1 \ subnet1 sleep 2 else echo "Subnet 'subnet1' already exists." fi SUBNET_ID=$(openstack subnet show subnet1 -f value -c id) sleep 2 # --- Router --- # Check if a router named "router1" exists if ! openstack router show router1 &> /dev/null; then sleep 2 echo "Router 'router1' not found. Creating now" openstack router create router1 sleep 2 ROUTER_ID=$(openstack router show router1 -f value -c id) sleep 2 openstack router add subnet "$ROUTER_ID" "$SUBNET_ID" sleep 2 else echo "Router 'router1' already exists." fi echo "Test: get the lease ID" LEASE_ID=$(openstack reservation lease list | grep "lease-test-comp-host-res" | awk '{print $2}') sleep 2 echo "Test: get the reservation ID" # Check if the lease ID was found if [ -z "$LEASE_ID" ]; then echo "Error: Lease 'lease-test-comp-host-res' not found." else RESERVATION_ID=$(openstack reservation lease show "$LEASE_ID" | grep -A 100 'reservations' | sed -n 's/.*"id": "\([^"]*\)".*/\1/p') sleep 2 echo "Test: RESERVATION ID: $RESERVATION_ID" fi echo "Test: list servers" openstack server list sleep 2 if [ -n "$RESERVATION_ID" ]; then echo "Test: Create a server with the reservation hint" openstack server create \ --flavor "$FLAVOR_ID" \ --image "$IMAGE_ID" \ --network "$NETWORK_ID" \ --hint reservation="$RESERVATION_ID" \ server_test_blazar_with_reservation sleep 60 echo "Test: list servers after creating a server with reservation" openstack server list sleep 2 fi echo "Test: delete the created servers" # Get the list of servers and delete them SERVER_LIST=$(openstack server list -f value -c id) sleep 2 # Check if any servers were found if [ -z "$SERVER_LIST" ]; then echo "No servers found" else # Delete the servers for SERVER_ID in $SERVER_LIST; do echo "Deleting server: $SERVER_ID" openstack server delete "$SERVER_ID" sleep 5 done echo "All servers on host '$host_id' have been deleted" fi echo "Test: list servers after deleting" openstack server list sleep 2 echo "Test: Starting the process to delete all Blazar leases" lease_ids=$(openstack reservation lease list -c id -f value) sleep 2 # Check if the list of leases is empty. if [ -z "$lease_ids" ]; then echo "Test: No leases found to delete" else echo "Test: The following lease IDs will be deleted:" echo "$lease_ids" echo "-------------------------------------" while IFS= read -r lease_id; do echo "Test: Deleting lease with ID: $lease_id" openstack reservation lease delete "$lease_id" sleep 2 echo "Test: Lease $lease_id deleted." done <<< "$lease_ids" echo "-------------------------------------" echo "Test: All Blazar leases have been successfully deleted" fi echo "Test: Starting the process to delete all Blazar hosts" host_ids=$(openstack reservation host list -c id -f value) sleep 2 # Check if the list of hosts is empty. if [ -z "$host_ids" ]; then echo "Test: No hosts found to delete" else echo "Test: The following host IDs will be deleted:" echo "$host_ids" echo "-------------------------------------" while IFS= read -r host_id; do echo "Test: Deleting host with ID: $host_id" openstack reservation host delete "$host_id" sleep 2 echo "Test: Host $host_id deleted" done <<< "$host_ids" echo "-------------------------------------" echo "Test: All Blazar hosts have been successfully deleted" fi exit 0 ================================================ FILE: tools/deployment/component/ceilometer/ceilometer.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_CEILOMETER:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c ceilometer ${FEATURES})"} #NOTE: Wait for deploy helm upgrade --install ceilometer ${OSH_HELM_REPO}/ceilometer \ --namespace=openstack \ --set pod.replicas.api=2 \ --set pod.replicas.central=2 \ --set pod.replicas.notification=2 \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_CEILOMETER} #NOTE: Wait for deploy helm osh wait-for-pods openstack #NOTE: Validate Deployment info export OS_CLOUD=openstack_helm openstack service list ================================================ FILE: tools/deployment/component/cinder/cinder.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_CINDER:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c cinder ${FEATURES})"} : ${RUN_HELM_TESTS:="yes"} #NOTE: Deploy command tee /tmp/cinder.yaml < serial # Create the client CA private key openssl genpkey -algorithm RSA -out private/ca.key.pem -aes-128-cbc -pass pass:not-secure-passphrase chmod 400 private/ca.key.pem # Create the client CA root certificate openssl req -config ${OPENSSL_CONF} -key private/ca.key.pem -new -x509 -sha256 -extensions v3_ca -days 7300 -out certs/ca.cert.pem -subj "/C=US/ST=Oregon/L=Corvallis/O=OpenStack/OU=Octavia/CN=ClientRootCA" -passin pass:not-secure-passphrase ###### Client Intermediate CA mkdir intermediate_ca mkdir intermediate_ca/certs intermediate_ca/crl intermediate_ca/newcerts intermediate_ca/private chmod 700 intermediate_ca/private touch intermediate_ca/index.txt echo 1000 > intermediate_ca/serial # Create the client intermediate CA private key openssl genpkey -algorithm RSA -out intermediate_ca/private/intermediate.ca.key.pem -aes-128-cbc -pass pass:not-secure-passphrase chmod 400 intermediate_ca/private/intermediate.ca.key.pem # Create the client intermediate CA certificate signing request openssl req -config ${OPENSSL_CONF} -key intermediate_ca/private/intermediate.ca.key.pem -new -sha256 -out intermediate_ca/client_intermediate.csr -subj "/C=US/ST=Oregon/L=Corvallis/O=OpenStack/OU=Octavia/CN=ClientIntermediateCA" -passin pass:not-secure-passphrase # Create the client intermediate CA certificate openssl ca -config ${OPENSSL_CONF} -name CA_intermediate -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in intermediate_ca/client_intermediate.csr -out intermediate_ca/certs/intermediate.cert.pem -passin pass:not-secure-passphrase -batch # Create the client CA certificate chain cat intermediate_ca/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate_ca/ca-chain.cert.pem ###### Create the client key and certificate openssl genpkey -algorithm RSA -out intermediate_ca/private/controller.key.pem -aes-128-cbc -pass pass:not-secure-passphrase chmod 400 intermediate_ca/private/controller.key.pem # Create the client controller certificate signing request openssl req -config ${OPENSSL_CONF} -key intermediate_ca/private/controller.key.pem -new -sha256 -out intermediate_ca/controller.csr -subj "/C=US/ST=Oregon/L=Corvallis/O=OpenStack/OU=Octavia/CN=OctaviaController" -passin pass:not-secure-passphrase # Create the client controller certificate openssl ca -config ${OPENSSL_CONF} -name CA_intermediate -extensions usr_cert -days 1825 -notext -md sha256 -in intermediate_ca/controller.csr -out intermediate_ca/certs/controller.cert.pem -passin pass:not-secure-passphrase -batch # Build the cancatenated client cert and key openssl rsa -in intermediate_ca/private/controller.key.pem -out intermediate_ca/private/client.cert-and-key.pem -passin pass:not-secure-passphrase cat intermediate_ca/certs/controller.cert.pem >> intermediate_ca/private/client.cert-and-key.pem # We are done with the client CA cd .. ###### Stash the octavia default client CA cert files cp client_ca/intermediate_ca/ca-chain.cert.pem etc/octavia/certs/client_ca.cert.pem chmod 444 etc/octavia/certs/client_ca.cert.pem cp client_ca/intermediate_ca/private/client.cert-and-key.pem etc/octavia/certs/client.cert-and-key.pem chmod 600 etc/octavia/certs/client.cert-and-key.pem ###### Server Root CA mkdir server_ca cd server_ca mkdir certs crl newcerts private chmod 700 private touch index.txt echo 1000 > serial # Create the server CA private key openssl genpkey -algorithm RSA -out private/ca.key.pem -aes-128-cbc -pass pass:not-secure-passphrase chmod 400 private/ca.key.pem # Create the server CA root certificate openssl req -config ${OPENSSL_CONF} -key private/ca.key.pem -new -x509 -sha256 -extensions v3_ca -days 7300 -out certs/ca.cert.pem -subj "/C=US/ST=Oregon/L=Corvallis/O=OpenStack/OU=Octavia/CN=ServerRootCA" -passin pass:not-secure-passphrase ###### Server Intermediate CA mkdir intermediate_ca mkdir intermediate_ca/certs intermediate_ca/crl intermediate_ca/newcerts intermediate_ca/private chmod 700 intermediate_ca/private touch intermediate_ca/index.txt echo 1000 > intermediate_ca/serial # Create the server intermediate CA private key openssl genpkey -algorithm RSA -out intermediate_ca/private/intermediate.ca.key.pem -aes-128-cbc -pass pass:not-secure-passphrase chmod 400 intermediate_ca/private/intermediate.ca.key.pem # Create the server intermediate CA certificate signing request openssl req -config ${OPENSSL_CONF} -key intermediate_ca/private/intermediate.ca.key.pem -new -sha256 -out intermediate_ca/server_intermediate.csr -subj "/C=US/ST=Oregon/L=Corvallis/O=OpenStack/OU=Octavia/CN=ServerIntermediateCA" -passin pass:not-secure-passphrase # Create the server intermediate CA certificate openssl ca -config ${OPENSSL_CONF} -name CA_intermediate -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in intermediate_ca/server_intermediate.csr -out intermediate_ca/certs/intermediate.cert.pem -passin pass:not-secure-passphrase -batch # Create the server CA certificate chain cat intermediate_ca/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate_ca/ca-chain.cert.pem # We are done with the server CA cd .. ###### Stash the octavia default server CA cert files cp server_ca/intermediate_ca/ca-chain.cert.pem etc/octavia/certs/server_ca-chain.cert.pem chmod 444 etc/octavia/certs/server_ca-chain.cert.pem cp server_ca/intermediate_ca/certs/intermediate.cert.pem etc/octavia/certs/server_ca.cert.pem chmod 400 etc/octavia/certs/server_ca.cert.pem cp server_ca/intermediate_ca/private/intermediate.ca.key.pem etc/octavia/certs/server_ca.key.pem chmod 400 etc/octavia/certs/server_ca.key.pem ##### Validate the Octavia PKI files set +x echo "################# Verifying the Octavia files ###########################" openssl verify -CAfile etc/octavia/certs/client_ca.cert.pem etc/octavia/certs/client.cert-and-key.pem openssl verify -CAfile etc/octavia/certs/server_ca-chain.cert.pem etc/octavia/certs/server_ca.cert.pem # We are done, stop enforcing shell errexit set +e echo "!!!!!!!!!!!!!!!Do not use this script for deployments!!!!!!!!!!!!!" echo "Please use the Octavia Certificate Configuration guide:" echo "https://docs.openstack.org/octavia/latest/admin/guides/certificates.html" echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ================================================ FILE: tools/deployment/component/octavia/heat_octavia_env.yaml ================================================ --- heat_template_version: 2021-04-16 parameters: public_network_name: type: string default: public public_physical_network_name: type: string default: public public_subnet_name: type: string default: public public_subnet_cidr: type: string default: 172.24.4.0/24 public_subnet_gateway: type: string default: 172.24.4.1 public_allocation_pool_start: type: string default: 172.24.4.10 public_allocation_pool_end: type: string default: 172.24.4.254 private_subnet_cidr: type: string default: 192.168.128.0/24 dns_nameserver: type: string default: 172.24.4.1 image_name: type: string default: Ubuntu Jammy image_url: type: string default: "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img" ssh_key: type: string default: octavia-key compute_flavor_id: type: string az_1: type: string az_2: type: string resources: public_net: type: OS::Neutron::ProviderNet properties: name: get_param: public_network_name router_external: true physical_network: get_param: public_physical_network_name network_type: flat public_subnet: type: OS::Neutron::Subnet properties: name: get_param: public_subnet_name network: get_resource: public_net cidr: get_param: public_subnet_cidr gateway_ip: get_param: public_subnet_gateway enable_dhcp: false dns_nameservers: - get_param: public_subnet_gateway allocation_pools: - start: {get_param: public_allocation_pool_start} end: {get_param: public_allocation_pool_end} private_net: type: OS::Neutron::Net private_subnet: type: OS::Neutron::Subnet properties: network: get_resource: private_net cidr: get_param: private_subnet_cidr dns_nameservers: - get_param: dns_nameserver image: type: OS::Glance::WebImage properties: name: get_param: image_name location: get_param: image_url container_format: bare disk_format: qcow2 min_disk: 3 visibility: public flavor_vm: type: OS::Nova::Flavor properties: name: m1.test disk: 3 ram: 1024 vcpus: 2 wait_handle_1: type: OS::Heat::WaitConditionHandle wait_handle_2: type: OS::Heat::WaitConditionHandle server_1: type: OS::Nova::Server properties: image: get_resource: image flavor: get_resource: flavor_vm key_name: get_param: ssh_key networks: - port: get_resource: server_port_1 user_data_format: RAW user_data: str_replace: template: | #!/bin/bash echo "nameserver $nameserver" > /etc/resolv.conf echo "127.0.0.1 $(hostname)" >> /etc/hosts systemctl stop systemd-resolved systemctl disable systemd-resolved mkdir -p /var/www/html/ echo "Hello from server_1: $(hostname)" > /var/www/html/index.html nohup python3 -m http.server 8000 --directory /var/www/html > /dev/null 2>&1 & $wc_notify --data-binary '{ "status": "SUCCESS" }' params: $nameserver: {get_param: dns_nameserver} $wc_notify: {get_attr: ['wait_handle_1', 'curl_cli']} availability_zone: {get_param: az_1} wait_server_1: type: OS::Heat::WaitCondition properties: handle: {get_resource: wait_handle_1} timeout: 1200 server_2: type: OS::Nova::Server properties: image: get_resource: image flavor: get_resource: flavor_vm key_name: get_param: ssh_key networks: - port: get_resource: server_port_2 user_data_format: RAW user_data: str_replace: template: | #!/bin/bash echo "nameserver $nameserver" > /etc/resolv.conf echo "127.0.0.1 $(hostname)" >> /etc/hosts systemctl stop systemd-resolved systemctl disable systemd-resolved mkdir -p /var/www/html/ echo "Hello from server_2: $(hostname)" > /var/www/html/index.html nohup python3 -m http.server 8000 --directory /var/www/html > /dev/null 2>&1 & $wc_notify --data-binary '{ "status": "SUCCESS" }' params: $nameserver: {get_param: dns_nameserver} $wc_notify: {get_attr: ['wait_handle_2', 'curl_cli']} availability_zone: {get_param: az_2} wait_server_2: type: OS::Heat::WaitCondition properties: handle: {get_resource: wait_handle_2} timeout: 1200 security_group: type: OS::Neutron::SecurityGroup properties: name: default_port_security_group rules: - remote_ip_prefix: 0.0.0.0/0 protocol: tcp port_range_min: 22 port_range_max: 22 - remote_ip_prefix: 0.0.0.0/0 protocol: tcp port_range_min: 8000 port_range_max: 8000 - remote_ip_prefix: 0.0.0.0/0 protocol: icmp server_port_1: type: OS::Neutron::Port properties: network: get_resource: private_net fixed_ips: - subnet: get_resource: private_subnet security_groups: - get_resource: security_group server_floating_ip_1: type: OS::Neutron::FloatingIP properties: floating_network: get_resource: public_net port_id: get_resource: server_port_1 server_port_2: type: OS::Neutron::Port properties: network: get_resource: private_net fixed_ips: - subnet: get_resource: private_subnet security_groups: - get_resource: security_group server_floating_ip_2: type: OS::Neutron::FloatingIP properties: floating_network: get_resource: public_net port_id: get_resource: server_port_2 router: type: OS::Neutron::Router properties: external_gateway_info: network: get_resource: public_net router_interface: type: OS::Neutron::RouterInterface properties: router_id: get_resource: router subnet_id: get_resource: private_subnet flavor_profile: type: "OS::Octavia::FlavorProfile" properties: provider_name: amphora flavor_data: str_replace: template: | { "loadbalancer_topology": "SINGLE", "compute_flavor": "%compute_flavor%" } params: "%compute_flavor%": {get_param: compute_flavor_id} flavor: type: "OS::Octavia::Flavor" properties: flavor_profile: get_resource: flavor_profile loadbalancer: type: "OS::Octavia::LoadBalancer" properties: name: osh provider: amphora vip_subnet: get_resource: private_subnet flavor: get_resource: flavor floating_ip: type: OS::Neutron::FloatingIP properties: floating_network: {get_resource: public_net} port_id: {get_attr: [loadbalancer, vip_port_id]} listener: type: "OS::Octavia::Listener" properties: protocol_port: 80 protocol: "HTTP" loadbalancer: get_resource: loadbalancer pool: type: "OS::Octavia::Pool" properties: lb_algorithm: "ROUND_ROBIN" listener: get_resource: listener protocol: "HTTP" monitor: type: "OS::Octavia::HealthMonitor" properties: delay: 3 max_retries: 9 timeout: 3 type: "PING" pool: get_resource: pool pool_member_1: type: "OS::Octavia::PoolMember" properties: subnet: get_resource: private_subnet protocol_port: 8000 pool: get_resource: pool address: get_attr: - "server_1" - "first_address" pool_member_2: type: "OS::Octavia::PoolMember" properties: subnet: get_resource: private_subnet protocol_port: 8000 pool: get_resource: pool address: get_attr: - "server_2" - "first_address" ... ================================================ FILE: tools/deployment/component/octavia/octavia.sh ================================================ #!/bin/bash # Copyright 2019 Samsung Electronics Co., Ltd. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_OCTAVIA:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c octavia ${FEATURES})"} export OS_CLOUD=openstack_helm OSH_AMPHORA_IMAGE_NAME="amphora-x64-haproxy-ubuntu-jammy" OSH_AMPHORA_IMAGE_OWNER_ID=$(openstack image show "${OSH_AMPHORA_IMAGE_NAME}" -f value -c owner) OSH_AMPHORA_SECGROUP_LIST=$(openstack security group list -f value | grep lb-mgmt-sec-grp | awk '{print $1}') OSH_AMPHORA_FLAVOR_ID=$(openstack flavor show m1.amphora -f value -c id) OSH_AMPHORA_BOOT_NETWORK_LIST=$(openstack network list --name lb-mgmt-net -f value -c ID) # Test nodes are quite small (usually 8Gb RAM) and for testing Octavia # we need two worker VM instances and one amphora VM instance. # We are going to run them all on different K8s nodes. # The /tmp/inventory_k8s_nodes.txt file is created by the deploy-env role and contains the list # of all K8s nodes. Amphora instance is run on the first K8s node from the list. OSH_AMPHORA_TARGET_HOSTNAME=$(sed -n '1p' /tmp/inventory_k8s_nodes.txt) CONTROLLER_IP_PORT_LIST=$(cat /tmp/octavia_hm_controller_ip_port_list) #NOTE: Deploy command tee /tmp/octavia.yaml < /tmp/octavia_hm_controller_ip_port_list # Create a flavor for amphora instance openstack flavor show m1.amphora || \ openstack flavor create --ram 1024 --disk 3 --vcpus 1 m1.amphora # Create key pair to connect amphora instance via management network mkdir -p ${SSH_DIR} openstack keypair show octavia-key || \ openstack keypair create --private-key ${SSH_DIR}/octavia_key octavia-key sudo chown $(id -un) ${SSH_DIR}/octavia_key chmod 600 ${SSH_DIR}/octavia_key # accept diffie-hellman-group1-sha1 algo for SSH (for compatibility with older images) sudo tee -a /etc/ssh/ssh_config < /tmp/curl.txt curl http://${LB_FLOATING_IP} >> /tmp/curl.txt curl http://${LB_FLOATING_IP} >> /tmp/curl.txt grep "Hello from server_1" /tmp/curl.txt grep "Hello from server_2" /tmp/curl.txt ================================================ FILE: tools/deployment/component/octavia/openssl.cnf ================================================ # OpenSSL root CA configuration file. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # Directory and file locations. dir = ./ certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # The root key and root certificate. private_key = $dir/private/ca.key.pem certificate = $dir/certs/ca.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/ca.crl.pem crl_extensions = crl_ext default_crl_days = 30 # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 name_opt = ca_default cert_opt = ca_default # 10 years default_days = 7300 preserve = no policy = policy_strict [ CA_intermediate ] # Directory and file locations. dir = ./intermediate_ca certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # The root key and root certificate. private_key = ./private/ca.key.pem certificate = ./certs/ca.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/ca.crl.pem crl_extensions = crl_ext default_crl_days = 30 # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 name_opt = ca_default cert_opt = ca_default # 5 years default_days = 3650 preserve = no policy = policy_strict [ policy_strict ] # The root CA should only sign intermediate certificates that match. # See the POLICY FORMAT section of `man ca`. countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] # Options for the `req` tool (`man req`). default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # SHA-1 is deprecated, so use SHA-2 instead. default_md = sha256 # Extension to add when the -x509 option is used. x509_extensions = v3_ca [ req_distinguished_name ] # See . countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name localityName = Locality Name 0.organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name emailAddress = Email Address # Optionally, specify some defaults. countryName_default = US stateOrProvinceName_default = Oregon localityName_default = Corvallis 0.organizationName_default = OpenStack organizationalUnitName_default = Octavia emailAddress_default = commonName_default = example.org [ v3_ca ] # Extensions for a typical CA (`man x509v3_config`). subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ v3_intermediate_ca ] # Extensions for a typical intermediate CA (`man x509v3_config`). subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # Extensions for client certificates (`man x509v3_config`). basicConstraints = CA:FALSE nsCertType = client, email nsComment = "OpenSSL Generated Client Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, emailProtection [ server_cert ] # Extensions for server certificates (`man x509v3_config`). basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # Extension for CRLs (`man x509v3_config`). authorityKeyIdentifier=keyid:always ================================================ FILE: tools/deployment/component/ovn/ovn.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_OVN:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c ovn ${FEATURES})"} tee /tmp/ovn.yaml << EOF volume: ovn_ovsdb_nb: enabled: false ovn_ovsdb_sb: enabled: false network: interface: tunnel: null conf: ovn_bridge_mappings: public:br-ex auto_bridge_add: br-ex: provider1 EOF #NOTE: Deploy command : ${OSH_EXTRA_HELM_ARGS:=""} helm upgrade --install ovn ${OSH_HELM_REPO}/ovn \ --namespace=openstack \ --values=/tmp/ovn.yaml \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_OVN} #NOTE: Wait for deploy helm osh wait-for-pods openstack ================================================ FILE: tools/deployment/component/redis/redis.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe # NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_ZAQAR:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c redis ${FEATURES})"} helm upgrade --install redis ${OSH_HELM_REPO}/redis \ --namespace openstack \ --create-namespace \ --timeout 600s \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_ZAQAR} # NOTE: Wait for pods to be ready helm osh wait-for-pods openstack ================================================ FILE: tools/deployment/component/skyline/skyline.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_SKYLINE:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c skyline ${FEATURES})"} #NOTE: Deploy command helm upgrade --install skyline ${OSH_HELM_REPO}/skyline \ --namespace=openstack \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_SKYLINE} #NOTE: Wait for deploy helm osh wait-for-pods openstack 1200 ================================================ FILE: tools/deployment/component/swift/swift.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_SWIFT:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c swift ${FEATURES})"} tee /tmp/swift.yaml << EOF ring: replicas: 1 devices: - name: loop100 weight: 100 EOF #NOTE: Deploy command helm upgrade --install swift ${OSH_HELM_REPO}/swift \ --namespace=openstack \ --values=/tmp/swift.yaml \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_SWIFT} #NOTE: Wait for deploy helm osh wait-for-pods openstack 1200 openstack service list openstack endpoint list # Testing Swift openstack container list openstack container create test-container openstack container list echo "Hello World" > hello-world.txt export OPENSTACK_CLIENT_CONTAINER_EXTRA_ARGS="-v $(pwd):/mnt" openstack object create test-container /mnt/hello-world.txt openstack object list test-container openstack object delete test-container /mnt/hello-world.txt openstack container delete test-container openstack container list ================================================ FILE: tools/deployment/component/tacker/tacker.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_TACKER:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c tacker ${FEATURES})"} : ${RUN_HELM_TESTS:="no"} : ${STORAGE_CLASS:="nfs-provisioner"} #NOTE: Deploy command helm upgrade --install tacker ${OSH_HELM_REPO}/tacker \ --namespace=openstack \ --set storage.storageClass=${STORAGE_CLASS} \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_TACKER} #NOTE: Wait for deploy helm osh wait-for-pods openstack ================================================ FILE: tools/deployment/component/trove/trove.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe #NOTE: Define variables : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_TROVE:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c trove ${FEATURES})"} : ${RUN_HELM_TESTS:="yes"} #NOTE: Deploy command tee /tmp/trove.yaml <" repository: ceph-rgw config: indices: - "<*-{now/d}>" retention: expire_after: 30d ilm_policy: endpoint: _ilm/policy/cleanup body: policy: phases: delete: min_age: 5d actions: delete: {} test_empty: {} storage: s3: clients: # These values configure the s3 clients section of elasticsearch.yml, with access_key and secret_key being saved to the keystore default: # not needed when using Rook Ceph CRDs # auth: # username: elasticsearch # access_key: "elastic_access_key" # secret_key: "elastic_secret_key" settings: # endpoint: Defaults to the ceph-rgw endpoint # protocol: Defaults to http path_style_access: true # Required for ceph-rgw S3 API create_user: true # Attempt to create the user at the ceph_object_store endpoint, authenticating using the secret named at .Values.secrets.rgw.admin backup: # Change this as you'd like # not needed when using Rook Ceph CRDs # auth: # username: backup # access_key: "backup_access_key" # secret_key: "backup_secret_key" settings: # endpoint: rook-ceph-rgw-default.ceph.svc.cluster.local # Using the ingress here to test the endpoint override path_style_access: true create_user: true buckets: # List of buckets to create (if required). - name: elasticsearch-bucket client: default storage_class: ceph-bucket # this is valid when using Rook CRDs # not needed when using Rook Ceph CRDs # options: # list of extra options for s3cmd # - --region="default:osh-infra" - name: backup-bucket client: backup storage_class: ceph-bucket # this is valid when using Rook CRDs # not needed when using Rook Ceph CRDs # options: # list of extra options for s3cmd # - --region="default:backup" endpoints: ceph_object_store: name: radosgw namespace: ceph hosts: default: rook-ceph-rgw-default public: radosgw host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 8080 public: 80 network: elasticsearch: ingress: classes: namespace: ingress-osh-infra dependencies: static: elasticsearch_templates: services: - endpoint: internal service: elasticsearch jobs: null custom_resources: - apiVersion: objectbucket.io/v1alpha1 kind: ObjectBucket name: obc-osh-infra-elasticsearch-bucket fields: - key: "status.phase" value: "Bound" - apiVersion: objectbucket.io/v1alpha1 kind: ObjectBucket name: obc-osh-infra-backup-bucket fields: - key: "status.phase" value: "Bound" snapshot_repository: services: - endpoint: internal service: elasticsearch jobs: null custom_resources: - apiVersion: objectbucket.io/v1alpha1 kind: ObjectBucket name: obc-osh-infra-elasticsearch-bucket fields: - key: "status.phase" value: "Bound" - apiVersion: objectbucket.io/v1alpha1 kind: ObjectBucket name: obc-osh-infra-backup-bucket fields: - key: "status.phase" value: "Bound" manifests: job_s3_user: false job_s3_bucket: false object_bucket_claim: true images: tags: dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy EOF : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_ELASTICSEARCH:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c elasticsearch ${FEATURES})"} helm upgrade --install elasticsearch ${OSH_HELM_REPO}/elasticsearch \ --namespace=osh-infra \ --values=/tmp/elasticsearch.yaml\ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_ELASTICSEARCH} #NOTE: Wait for deploy helm osh wait-for-pods osh-infra # Delete the test pod if it still exists kubectl delete pods -l application=elasticsearch,release_group=elasticsearch,component=test --namespace=osh-infra --ignore-not-found helm test elasticsearch --namespace osh-infra ================================================ FILE: tools/deployment/logging/fluentbit.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_FLUENTBIT:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c fluentbit ${FEATURES})"} helm upgrade --install fluentbit ${OSH_HELM_REPO}/fluentbit \ --namespace=osh-infra \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_FLUENTBIT} #NOTE: Wait for deploy helm osh wait-for-pods osh-infra ================================================ FILE: tools/deployment/logging/fluentd.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_FLUENTD:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c fluentd ${FEATURES})"} tee /tmp/fluentd.yaml << EOF pod: env: fluentd: vars: MY_TEST_VAR: FOO secrets: MY_TEST_SECRET: BAR conf: fluentd: conf: # These fields are rendered as helm templates input: | @type prometheus port {{ tuple "fluentd" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} @type prometheus_monitor @type prometheus_output_monitor @type prometheus_tail_monitor bind 0.0.0.0 port "#{ENV['FLUENTD_PORT']}" @type forward @type tail @id in_tail_container_logs path "/var/log/containers/*.log" pos_file "/var/log/fluentd-containers.log.pos" tag kubernetes.* read_from_head true emit_unmatched_lines true @type "multi_format" format json time_key "time" time_type string time_format "%Y-%m-%dT%H:%M:%S.%NZ" keep_time_key false format regexp expression /^(? @type tail tag libvirt.* path /var/log/libvirt/**.log pos_file "/var/log/fluentd-libvirt.log.pos" read_from_head true @type none @type systemd tag auth path /var/log/journal matches [{ "SYSLOG_FACILITY":"10" }] read_from_head true @type local path /var/log/fluentd-systemd-auth.json fields_strip_underscores true fields_lowercase true @type systemd tag journal.* path /var/log/journal matches [{ "_SYSTEMD_UNIT": "docker.service" }] read_from_head true @type local path /var/log/fluentd-systemd-docker.json fields_strip_underscores true fields_lowercase true @type systemd tag journal.* path /var/log/journal matches [{ "_SYSTEMD_UNIT": "kubelet.service" }] read_from_head true @type local path /var/log/fluentd-systemd-kubelet.json fields_strip_underscores true fields_lowercase true @type systemd tag kernel path /var/log/journal matches [{ "_TRANSPORT": "kernel" }] read_from_head true @type local path /var/log/fluentd-systemd-kernel.json fields_strip_underscores true fields_lowercase true @type relabel @label @filter filter: | output: | EOF helm upgrade --install fluentd ${OSH_HELM_REPO}/fluentd \ --namespace=osh-infra \ --values=/tmp/fluentd.yaml \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_FLUENTD} #NOTE: Wait for deploy helm osh wait-for-pods osh-infra ================================================ FILE: tools/deployment/logging/kibana.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_KIBANA:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c kibana ${FEATURES})"} #NOTE: Deploy command helm upgrade --install kibana ${OSH_HELM_REPO}/kibana \ --namespace=osh-infra \ --set network.kibana.ingress.classes.namespace=ingress-osh-infra \ ${OSH_EXTRA_HELM_ARGS} \ ${OSH_EXTRA_HELM_ARGS_KIBANA} #NOTE: Wait for deploy helm osh wait-for-pods osh-infra ================================================ FILE: tools/deployment/monitoring/alertmanager.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} #NOTE: Deploy command helm upgrade --install prometheus-alertmanager ${OSH_HELM_REPO}/prometheus-alertmanager \ --namespace=osh-infra \ ${VOLUME_HELM_ARGS:="--set storage.alertmanager.enabled=false --set storage.alertmanager.use_local_path.enabled=true"} \ --set pod.replicas.alertmanager=1 #NOTE: Wait for deploy helm osh wait-for-pods osh-infra ================================================ FILE: tools/deployment/monitoring/blackbox-exporter.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} #NOTE: Deploy command helm upgrade --install prometheus-blackbox-exporter \ ${OSH_HELM_REPO}/prometheus-blackbox-exporter --namespace=osh-infra #NOTE: Wait for deploy helm osh wait-for-pods osh-infra ================================================ FILE: tools/deployment/monitoring/grafana.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} FEATURES="calico ceph containers coredns elasticsearch kubernetes nginx nodes openstack prometheus home_dashboard persistentvolume apparmor ${FEATURES}" : ${OSH_EXTRA_HELM_ARGS_GRAFANA:=$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c grafana ${FEATURES} 2>/dev/null)} #NOTE: Deploy command helm upgrade --install grafana ${OSH_HELM_REPO}/grafana \ --namespace=osh-infra \ --set network.grafana.ingress.classes.namespace="ingress-osh-infra" \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_GRAFANA} #NOTE: Wait for deploy helm osh wait-for-pods osh-infra # Delete the test pod if it still exists kubectl delete pods -l application=grafana,release_group=grafana,component=test --namespace=osh-infra --ignore-not-found helm test grafana --namespace osh-infra ================================================ FILE: tools/deployment/monitoring/kube-state-metrics.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_KUBE_STATE_METRICS:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c prometheus-kube-state-metrics ${FEATURES})"} #NOTE: Deploy command helm upgrade --install prometheus-kube-state-metrics \ ${OSH_HELM_REPO}/prometheus-kube-state-metrics --namespace=kube-system \ ${OSH_EXTRA_HELM_ARGS_KUBE_STATE_METRICS} #NOTE: Wait for deploy helm osh wait-for-pods kube-system ================================================ FILE: tools/deployment/monitoring/mysql-exporter.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_MARIADB_MYSQL_EXPORTER:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c prometheus-mysql-exporter ${FEATURES})"} #NOTE: Deploy command helm upgrade --install prometheus-mysql-exporter ${OSH_HELM_REPO}/prometheus-mysql-exporter \ --namespace=openstack \ --wait \ --timeout 900s \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_MARIADB_MYSQL_EXPORTER} #NOTE: Wait for deploy helm osh wait-for-pods openstack kubectl get pods --namespace=openstack -o wide ================================================ FILE: tools/deployment/monitoring/nagios.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_NAGIOS:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c nagios ${FEATURES})"} #NOTE: Deploy command helm upgrade --install nagios ${OSH_HELM_REPO}/nagios \ --namespace=osh-infra \ --set network.nagios.ingress.classes.namespace=ingress-osh-infra \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_NAGIOS} #NOTE: Wait for deploy helm osh wait-for-pods osh-infra # Delete the test pod if it still exists kubectl delete pods -l application=nagios,release_group=nagios,component=test --namespace=osh-infra --ignore-not-found helm test nagios --namespace osh-infra ================================================ FILE: tools/deployment/monitoring/node-exporter.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_NODE_EXPORTER:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c prometheus-node-exporter ${FEATURES})"} #NOTE: Deploy command helm upgrade --install prometheus-node-exporter \ ${OSH_HELM_REPO}/prometheus-node-exporter --namespace=kube-system \ ${OSH_EXTRA_HELM_ARGS_NODE_EXPORTER} #NOTE: Wait for deploy helm osh wait-for-pods kube-system ================================================ FILE: tools/deployment/monitoring/node-problem-detector.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} #NOTE: Deploy command tee /tmp/kubernetes-node-problem-detector.yaml << EOF monitoring: prometheus: pod: enabled: false service: enabled: true manifests: service: true EOF helm upgrade --install kubernetes-node-problem-detector \ ${OSH_HELM_REPO}/kubernetes-node-problem-detector --namespace=kube-system \ --values=/tmp/kubernetes-node-problem-detector.yaml #NOTE: Wait for deploy helm osh wait-for-pods kube-system ================================================ FILE: tools/deployment/monitoring/openstack-exporter.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe # Check if Keystone API DNS and HTTP endpoint are available; skip deployment if not KEYSTONE_HOST="keystone.openstack-helm.org" KEYSTONE_PORT=80 KEYSTONE_URL="http://$KEYSTONE_HOST:$KEYSTONE_PORT/v3" TIMEOUT=${TIMEOUT:-60} INTERVAL=2 start_time=$(date +%s) # DNS check while ! getent hosts "$KEYSTONE_HOST" >/dev/null; do now=$(date +%s) elapsed=$((now - start_time)) if [ $elapsed -ge $TIMEOUT ]; then echo "[INFO] Keystone API DNS not found after $TIMEOUT seconds, skipping prometheus-openstack-exporter deployment." exit 0 fi echo "[INFO] Waiting for Keystone DNS... ($elapsed/$TIMEOUT)" sleep $INTERVAL done # HTTP check while ! curl -sf "$KEYSTONE_URL" >/dev/null; do now=$(date +%s) elapsed=$((now - start_time)) if [ $elapsed -ge $TIMEOUT ]; then echo "[INFO] Keystone API not responding after $TIMEOUT seconds, skipping prometheus-openstack-exporter deployment." exit 0 fi echo "[INFO] Waiting for Keystone API... ($elapsed/$TIMEOUT)" sleep $INTERVAL done echo "[INFO] Keystone API is available. Proceeding with exporter deployment." : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_OS_EXPORTER:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c prometheus-openstack-exporter ${FEATURES})"} #NOTE: Deploy command helm upgrade --install prometheus-openstack-exporter \ ${OSH_HELM_REPO}/prometheus-openstack-exporter \ --namespace=openstack \ ${OSH_EXTRA_HELM_ARGS_OS_EXPORTER} #NOTE: Wait for deploy helm osh wait-for-pods openstack ================================================ FILE: tools/deployment/monitoring/process-exporter.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_PROCESS_EXPORTER:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c prometheus-process-exporter ${FEATURES})"} #NOTE: Deploy command helm upgrade --install prometheus-process-exporter \ ${OSH_HELM_REPO}/prometheus-process-exporter --namespace=kube-system \ ${OSH_EXTRA_HELM_ARGS_PROCESS_EXPORTER} #NOTE: Wait for deploy helm osh wait-for-pods kube-system ================================================ FILE: tools/deployment/monitoring/prometheus.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} FEATURES="alertmanager ceph elasticsearch kubernetes nodes openstack postgresql apparmor ${FEATURES}" : ${OSH_EXTRA_HELM_ARGS_PROMETHEUS:="$(helm osh get-values-overrides -p ${OSH_VALUES_OVERRIDES_PATH} -c prometheus ${FEATURES})"} #NOTE: Deploy command helm upgrade --install prometheus ${OSH_HELM_REPO}/prometheus \ --namespace=osh-infra \ --set network.prometheus.ingress.classes.namespace=ingress-osh-infra \ ${VOLUME_HELM_ARGS:="--set storage.enabled=false --set storage.use_local_path.enabled=true"} \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_PROMETHEUS} #NOTE: Wait for deploy helm osh wait-for-pods osh-infra # Delete the test pod if it still exists kubectl delete pods -l application=prometheus,release_group=prometheus,component=test --namespace=osh-infra --ignore-not-found helm test prometheus --namespace osh-infra ================================================ FILE: tools/deployment/openstack/keystone.sh ================================================ #!/bin/bash # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. set -xe : ${OSH_HELM_REPO:="../openstack-helm"} : ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} : ${OSH_EXTRA_HELM_ARGS_KEYSTONE:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c keystone ${FEATURES})"} # Install Keystone helm upgrade --install keystone ${OSH_HELM_REPO}/keystone \ --namespace=openstack \ ${OSH_EXTRA_HELM_ARGS:=} \ ${OSH_EXTRA_HELM_ARGS_KEYSTONE} helm osh wait-for-pods openstack # Testing basic functionality export OS_CLOUD=openstack_helm sleep 30 #NOTE(portdirect): Wait for ingress controller to update rules and restart Nginx openstack endpoint list ================================================ FILE: tools/gate/selenium/grafana-selenium.sh ================================================ #!/bin/bash set -xe export CHROMEDRIVER="${CHROMEDRIVER:="/etc/selenium/chromedriver"}" export ARTIFACTS_DIR="${ARTIFACTS_DIR:="/tmp/artifacts/"}" export GRAFANA_USER="admin" export GRAFANA_PASSWORD="password" export GRAFANA_URI="grafana.osh-infra.svc.cluster.local" python3 $(readlink -f $(dirname $0))/grafanaSelenium.py ================================================ FILE: tools/gate/selenium/grafanaSelenium.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import NoSuchElementException from seleniumtester import SeleniumTester st = SeleniumTester('Grafana') username = st.get_variable('GRAFANA_USER') password = st.get_variable('GRAFANA_PASSWORD') grafana_uri = st.get_variable('GRAFANA_URI') grafana_url = 'http://{0}'.format(grafana_uri) try: st.logger.info('Attempting to connect to Grafana') st.browser.get(grafana_url) el = WebDriverWait(st.browser, 15).until( EC.title_contains('Grafana') ) st.logger.info('Connected to Grafana') except TimeoutException: st.logger.critical('Timed out waiting to connect to Grafana') st.browser.quit() sys.exit(1) st.logger.info("Attempting to log into Grafana dashboard") try: st.browser.find_element(By.NAME, 'user').send_keys(username) st.browser.find_element(By.NAME, 'password').send_keys(password) st.browser.find_element(By.CLASS_NAME, 'css-1mhnkuh').click() st.logger.info("Successfully logged in to Grafana") except NoSuchElementException: st.logger.error("Failed to log in to Grafana") st.browser.quit() sys.exit(1) st.browser.quit() ================================================ FILE: tools/gate/selenium/kibana-selenium.sh ================================================ #!/bin/bash set -xe export CHROMEDRIVER="${CHROMEDRIVER:="/etc/selenium/chromedriver"}" export ARTIFACTS_DIR="${ARTIFACTS_DIR:="/tmp/artifacts/"}" export KIBANA_USER="admin" export KIBANA_PASSWORD="changeme" export KIBANA_URI="kibana.osh-infra.svc.cluster.local" export KERNEL_QUERY="discove?r_g=()&_a=(columns:!(_source),index:'kernel*',interval:auto,query:(language:kuery,query:''),sort:!('@timestamp',desc))" export JOURNAL_QUERY="discove?r_g=()&_a=(columns:!(_source),index:'journal*',interval:auto,query:(language:kuery,query:''),sort:!('@timestamp',desc))" export LOGSTASH_QUERY="discove?r_g=()&_a=(columns:!(_source),index:'logstash*',interval:auto,query:(language:kuery,query:''),sort:!('@timestamp',desc))" python3 $(readlink -f $(dirname $0))/kibanaSelenium.py ================================================ FILE: tools/gate/selenium/kibanaSelenium.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from seleniumtester import SeleniumTester st = SeleniumTester('Kibana') username = st.get_variable('KIBANA_USER') password = st.get_variable('KIBANA_PASSWORD') kibana_uri = st.get_variable('KIBANA_URI') kibana_url = 'http://{0}:{1}@{2}'.format(username, password, kibana_uri) try: st.logger.info('Attempting to connect to Kibana') st.browser.get(kibana_url) el = WebDriverWait(st.browser, 45).until( EC.title_contains('Kibana') ) st.logger.info('Connected to Kibana') except TimeoutException: st.logger.critical('Timed out waiting for Kibana') st.browser.quit() sys.exit(1) kernel_query = st.get_variable('KERNEL_QUERY') journal_query = st.get_variable('JOURNAL_QUERY') logstash_query = st.get_variable('LOGSTASH_QUERY') queries = [(kernel_query, 'Kernel'), (journal_query, 'Journal'), (logstash_query, 'Logstash')] for query, name in queries: retry = 3 while retry > 0: query_url = '{}/app/kibana#/{}'.format(kibana_url, query) try: st.logger.info('Attempting to query {} index'.format(name)) st.browser.get(query_url) WebDriverWait(st.browser, 60).until( EC.presence_of_element_located( (By.XPATH, '/html/body/div[2]/div/div/div/div[3]/' 'discover-app/main/div/div[2]/div/div[2]/section[2]/' 'doc-table/div/table/tbody/tr[1]/td[2]') ) ) st.logger.info('{} index loaded successfully'.format(name)) st.take_screenshot('Kibana {} Index'.format(name)) retry = 0 except TimeoutException: if retry > 1: st.logger.warning('Timed out loading {} index'.format(name)) else: st.logger.error('Could not load {} index'.format(name)) retry -= 1 if retry <= 0: # Reset test condition st.browser.get(kibana_url) st.browser.quit() ================================================ FILE: tools/gate/selenium/nagios-selenium.sh ================================================ #!/bin/bash set -xe export CHROMEDRIVER="${CHROMEDRIVER:="/etc/selenium/chromedriver"}" export ARTIFACTS_DIR="${ARTIFACTS_DIR:="/tmp/artifacts/"}" export NAGIOS_USER="nagiosadmin" export NAGIOS_PASSWORD="password" export NAGIOS_URI="nagios.osh-infra.svc.cluster.local" python3 $(readlink -f $(dirname $0))/nagiosSelenium.py ================================================ FILE: tools/gate/selenium/nagiosSelenium.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import NoSuchElementException from seleniumtester import SeleniumTester st = SeleniumTester('Nagios') username = st.get_variable('NAGIOS_USER') password = st.get_variable('NAGIOS_PASSWORD') nagios_uri = st.get_variable('NAGIOS_URI') nagios_url = 'http://{0}:{1}@{2}'.format(username, password, nagios_uri) try: st.logger.info('Attempting to connect to Nagios') st.browser.get(nagios_url) el = WebDriverWait(st.browser, 15).until( EC.title_contains('Nagios') ) st.logger.info('Connected to Nagios') except TimeoutException: st.logger.critical('Timed out waiting for Nagios') st.browser.quit() sys.exit(1) try: st.logger.info('Switching Focus to Navigation side frame') sideFrame = st.browser.switch_to.frame('side') except NoSuchElementException: st.logger.error('Failed selecting side frame') st.browser.quit() sys.exit(1) try: st.logger.info('Attempting to visit Services page') st.click_link_by_name('Services') st.take_screenshot('Nagios Services') except TimeoutException: st.logger.error('Failed to load Services page') st.browser.quit() sys.exit(1) try: st.logger.info('Attempting to visit Host Groups page') st.click_link_by_name('Host Groups') st.take_screenshot('Nagios Host Groups') except TimeoutException: st.logger.error('Failed to load Host Groups page') st.browser.quit() sys.exit(1) try: st.logger.info('Attempting to visit Hosts page') st.click_link_by_name('Hosts') st.take_screenshot('Nagios Hosts') except TimeoutException: st.logger.error('Failed to load Hosts page') st.browser.quit() sys.exit(1) st.browser.quit() ================================================ FILE: tools/gate/selenium/prometheus-selenium.sh ================================================ #!/bin/bash set -xe export CHROMEDRIVER="${CHROMEDRIVER:="/etc/selenium/chromedriver"}" export ARTIFACTS_DIR="${ARTIFACTS_DIR:="/tmp/artifacts/"}" export PROMETHEUS_USER="admin" export PROMETHEUS_PASSWORD="changeme" export PROMETHEUS_URI="prometheus.osh-infra.svc.cluster.local" python3 tools/gate/selenium/prometheusSelenium.py ================================================ FILE: tools/gate/selenium/prometheusSelenium.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from seleniumtester import SeleniumTester st = SeleniumTester('Prometheus') username = st.get_variable('PROMETHEUS_USER') password = st.get_variable('PROMETHEUS_PASSWORD') prometheus_uri = st.get_variable('PROMETHEUS_URI') prometheus_url = 'http://{}:{}@{}'.format(username, password, prometheus_uri) try: st.logger.info('Attempting to connect to Prometheus') st.browser.get(prometheus_url) el = WebDriverWait(st.browser, 15).until( EC.title_contains('Prometheus') ) st.logger.info('Connected to Prometheus') st.take_screenshot('Prometheus Dashboard') except TimeoutException: st.logger.critical('Timed out waiting for Prometheus') st.browser.quit() sys.exit(1) try: st.logger.info('Attempting to view Runtime Information') st.click_link_by_name('Status') st.click_link_by_name('Runtime & Build Information') el = WebDriverWait(st.browser, 15).until( EC.presence_of_element_located((By.XPATH, '/html/body/div/table[1]')) ) st.take_screenshot('Prometheus Runtime Info') except TimeoutException: st.logger.error('Failed to load Runtime Information page') st.browser.quit() sys.exit(1) try: st.logger.info('Attempting to view Runtime Information') st.click_link_by_name('Status') st.click_link_by_name('Command-Line Flags') el = WebDriverWait(st.browser, 15).until( EC.presence_of_element_located((By.XPATH, '/html/body/div/table')) ) st.take_screenshot('Prometheus Command Line Flags') except TimeoutException: st.logger.error('Failed to load Command Line Flags page') st.browser.quit() sys.exit(1) st.browser.quit() ================================================ FILE: tools/gate/selenium/seleniumtester.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import logging import sys from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import ScreenshotException class SeleniumTester(): def __init__(self, name): self.logger = self.get_logger(name) self.chrome_driver = self.get_variable('CHROMEDRIVER') self.artifacts_dir = self.get_variable('ARTIFACTS_DIR') self.initialize_artifiacts_dir() self.browser = self.get_browser() def get_logger(self, name): logger = logging.getLogger('{} Selenium Tests'.format(name)) logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # Set the formatter and add the handler ch.setFormatter(formatter) logger.addHandler(ch) return logger def get_variable(self, env_var): if env_var in os.environ: self.logger.info('Found "{}"'.format(env_var)) return os.environ[env_var] else: self.logger.critical( 'Variable "{}" is not defined!'.format(env_var) ) sys.exit(1) def get_browser(self): options = Options() options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--window-size=1920x1080') service = Service(executable_path=self.chrome_driver) browser = webdriver.Chrome(service=service, options=options) return browser def initialize_artifiacts_dir(self): if self.artifacts_dir and not os.path.exists(self.artifacts_dir): os.makedirs(self.artifacts_dir) self.logger.info( 'Created {} for test artifacts'.format(self.artifacts_dir) ) def click_link_by_name(self, link_name): try: el = WebDriverWait(self.browser, 15).until( EC.presence_of_element_located((By.LINK_TEXT, link_name)) ) self.logger.info("Clicking '{}' link".format(link_name)) link = self.browser.find_element(By.LINK_TEXT, link_name) link.click() except (TimeoutException, NoSuchElementException): self.logger.error("Failed clicking '{}' link".format(link_name)) self.browser.quit() sys.exit(1) def take_screenshot(self, page_name): file_name = page_name.replace(' ', '_') try: el = WebDriverWait(self.browser, 15) self.browser.save_screenshot( '{}{}.png'.format(self.artifacts_dir, file_name) ) self.logger.info( "Successfully captured {} screenshot".format(page_name) ) except ScreenshotException: self.logger.error( "Failed to capture {} screenshot".format(page_name) ) self.browser.quit() sys.exit(1) ================================================ FILE: tools/gate/selenium/skyline-selenium.sh ================================================ #!/bin/bash set -xe export CHROMEDRIVER="${CHROMEDRIVER:="/etc/selenium/chromedriver"}" export ARTIFACTS_DIR="${ARTIFACTS_DIR:="/tmp/artifacts/"}" export SKYLINE_USER="admin" export SKYLINE_PASSWORD="password" export SKYLINE_URI="skyline.openstack-helm.org" python3 $(readlink -f $(dirname $0))/skylineSelenium.py ================================================ FILE: tools/gate/selenium/skylineSelenium.py ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import sys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import NoSuchElementException from seleniumtester import SeleniumTester import time st = SeleniumTester('Skiline') username = st.get_variable('SKYLINE_USER') password = st.get_variable('SKYLINE_PASSWORD') skyline_uri = st.get_variable('SKYLINE_URI') login_url = 'http://{0}/auth/login'.format(skyline_uri) overview_url = 'http://{0}/base/overview'.format(skyline_uri) try: st.logger.info('Attempting to connect to Skyline') st.browser.get(login_url) el = WebDriverWait(st.browser, 15).until( EC.title_contains('Cloud') ) st.logger.info('Connected to Skyline') except TimeoutException: st.logger.critical('Timed out waiting to connect to Skyline') st.browser.quit() sys.exit(1) time.sleep(5) st.logger.info("Attempting to log into Skyline dashboard") try: print(f"Cookies before login: {st.browser.get_cookies()}") st.browser.find_element(By.ID, 'normal_login_domain').send_keys(username) st.browser.find_element(By.ID, 'normal_login_password').send_keys(password) st.browser.find_element(By.CLASS_NAME, 'login-form-button').click() st.logger.info("Submitted login form") time.sleep(5) st.logger.info(f"Current url: {st.browser.current_url}") for cookie in st.browser.get_cookies(): if cookie['name'] == 'session': st.logger.info(f"Session cookie: {cookie['name']} = {cookie['value']}") st.logger.info('Successfully logged in to Skyline') except NoSuchElementException: st.logger.error("Failed to log in to Skyline") st.browser.quit() sys.exit(1) st.browser.quit() ================================================ FILE: tox.ini ================================================ [tox] minversion = 3.1 envlist = docs skipsdist = True ignore_basepython_conflict = True [testenv] basepython = python3 setenv = VIRTUAL_ENV={envdir} deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} passenv = *_proxy,*_PROXY [testenv:venv] commands = {posargs} [testenv:linters] deps = pre-commit allowlist_externals = pre-commit commands = pre-commit run --all-files --show-diff-on-failure {posargs} [testenv:docs] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt commands = rm -rf doc/build make helm-docs sphinx-build -W --keep-going -b html -j auto doc/source doc/build/html allowlist_externals = make rm ; NOTE(kozhukalov): Temporarily disable the pdf generation because ; it is broken after merging the openstack-helm-infra. ; It is likely due to long lines. ; [testenv:pdf-docs] ; envdir = {toxworkdir}/docs ; deps = {[testenv:docs]deps} ; allowlist_externals = ; make ; rm ; commands = ; rm -rf doc/build/pdf ; make helm-docs ; sphinx-build -W --keep-going -b latex -j auto doc/source doc/build/pdf ; make -C doc/build/pdf [testenv:releasenotes] deps = -r{toxinidir}/releasenotes/requirements.txt commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html ================================================ FILE: trove/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Trove name: trove version: 2025.2.0 home: https://docs.openstack.org/trove/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Trove/OpenStack_Project_Trove_vertical.png sources: - https://opendev.org/openstack/trove - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: trove/templates/bin/_db-purge.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex # Purge deleted instances older than 30 days trove-manage --config-file /etc/trove/trove.conf db_purge --age_in_days 30 ================================================ FILE: trove/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex trove-manage --config-file /etc/trove/trove.conf db_sync ================================================ FILE: trove/templates/bin/_trove-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec trove-api \ --config-file /etc/trove/trove.conf ================================================ FILE: trove/templates/bin/_trove-conductor.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec trove-conductor \ --config-file /etc/trove/trove.conf ================================================ FILE: trove/templates/bin/_trove-taskmanager.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec trove-taskmanager \ --config-file /etc/trove/trove.conf ================================================ FILE: trove/templates/certificates.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.certificates }} {{- $envAll := . }} {{- $endpoint := "database" }} {{- range $key1, $cert := tuple "public" "internal" }} {{- $endpointScheme := tuple $endpoint "service" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" }} {{- if eq $endpointScheme "https" }} {{- $certName := index $envAll.Values.secrets.tls $endpoint "api" $cert }} {{- $endpointHost := index $envAll.Values.endpoints $endpoint "host_fqdn_override" $cert "host" }} {{- $endpointClusterHostname := tuple $endpoint $cert $envAll | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} {{- $endpointHostname := $endpointClusterHostname }} {{- if $endpointHost }} {{- $endpointHostname = $endpointHost }} {{- end }} --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: {{ $certName }} spec: secretName: {{ $certName }} issuerRef: name: {{ index $envAll.Values.endpoints $endpoint "host_fqdn_override" $cert "tls" "issuerRef" "name" }} kind: {{ index $envAll.Values.endpoints $endpoint "host_fqdn_override" $cert "tls" "issuerRef" "kind" }} commonName: {{ $endpointHostname }} dnsNames: - {{ $endpointHostname }} - {{ $endpointClusterHostname }} {{- end }} {{- end }} {{- end }} ================================================ FILE: trove/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: trove-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} db-purge.sh: | {{ tuple "bin/_db-purge.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} trove-api.sh: | {{ tuple "bin/_trove-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} trove-conductor.sh: | {{ tuple "bin/_trove-conductor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} trove-taskmanager.sh: | {{ tuple "bin/_trove-taskmanager.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: trove/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if and (not (kindIs "invalid" .Values.conf.trove.database.connection)) (empty .Values.conf.trove.database.connection) }} {{- $_ := tuple "oslo_db" "internal" "trove" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set .Values.conf.trove.database "connection" -}} {{- end -}} {{- if empty .Values.conf.trove.DEFAULT.transport_url }} {{- $_ := tuple "oslo_messaging" "internal" "trove" "amqp" . | include "helm-toolkit.endpoints.authenticated_transport_endpoint_uri_lookup" | set .Values.conf.trove.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.trove.DEFAULT.trove_auth_url }} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.trove.DEFAULT "trove_auth_url" -}} {{- end -}} {{- if empty .Values.conf.trove.DEFAULT.nova_compute_url }} {{- $_ := tuple "compute" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.trove.DEFAULT "nova_compute_url" -}} {{- end -}} {{- if empty .Values.conf.trove.DEFAULT.neutron_url }} {{- $_ := tuple "network" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.trove.DEFAULT "neutron_url" -}} {{- end -}} {{- if empty .Values.conf.trove.DEFAULT.cinder_url }} {{- $_ := tuple "volumev3" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.trove.DEFAULT "cinder_url" -}} {{- end -}} {{- if empty .Values.conf.trove.DEFAULT.glance_url }} {{- $_ := tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.trove.DEFAULT "glance_url" -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.auth_uri }} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.trove.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.auth_url }} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.trove.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.region_name }} {{- $_ := set .Values.conf.trove.keystone_authtoken "region_name" .Values.endpoints.identity.auth.trove.region_name -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.project_name }} {{- $_ := set .Values.conf.trove.keystone_authtoken "project_name" .Values.endpoints.identity.auth.trove.project_name -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.project_domain_name }} {{- $_ := set .Values.conf.trove.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.trove.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.user_domain_name }} {{- $_ := set .Values.conf.trove.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.trove.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.username }} {{- $_ := set .Values.conf.trove.keystone_authtoken "username" .Values.endpoints.identity.auth.trove.username -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.password }} {{- $_ := set .Values.conf.trove.keystone_authtoken "password" .Values.endpoints.identity.auth.trove.password -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.memcached_servers }} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.trove.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.trove.keystone_authtoken.memcache_secret_key }} {{- $_ := set .Values.conf.trove.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if empty .Values.conf.trove.service_credentials.auth_url }} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.trove.service_credentials "auth_url" -}} {{- end -}} {{- if empty .Values.conf.trove.service_credentials.region_name }} {{- $_ := set .Values.conf.trove.service_credentials "region_name" .Values.endpoints.identity.auth.trove.region_name -}} {{- end -}} {{- if empty .Values.conf.trove.service_credentials.project_name }} {{- $_ := set .Values.conf.trove.service_credentials "project_name" .Values.endpoints.identity.auth.trove.project_name -}} {{- end -}} {{- if empty .Values.conf.trove.service_credentials.project_domain_name }} {{- $_ := set .Values.conf.trove.service_credentials "project_domain_name" .Values.endpoints.identity.auth.trove.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.trove.service_credentials.user_domain_name }} {{- $_ := set .Values.conf.trove.service_credentials "user_domain_name" .Values.endpoints.identity.auth.trove.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.trove.service_credentials.username }} {{- $_ := set .Values.conf.trove.service_credentials "username" .Values.endpoints.identity.auth.trove.username -}} {{- end -}} {{- if empty .Values.conf.trove.service_credentials.password }} {{- $_ := set .Values.conf.trove.service_credentials "password" .Values.endpoints.identity.auth.trove.password -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: trove-etc type: Opaque data: trove.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.trove | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} {{- end }} ================================================ FILE: trove/templates/cron-job-trove-db-purge.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.cron_job_db_purge }} {{- $envAll := . }} {{- $mounts_trove_db_purge := .Values.pod.mounts.trove_db_purge.trove_db_purge }} {{- $mounts_trove_db_purge_init := .Values.pod.mounts.trove_db_purge.init_container }} {{- $serviceAccountName := "trove-db-purge" }} {{ tuple $envAll "db_purge" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: batch/v1 kind: CronJob metadata: name: trove-db-purge spec: schedule: {{ .Values.jobs.db_purge.cron | quote }} successfulJobsHistoryLimit: {{ .Values.jobs.db_purge.history.success }} failedJobsHistoryLimit: {{ .Values.jobs.db_purge.history.failed }} startingDeadlineSeconds: {{ .Values.jobs.db_purge.starting_deadline }} concurrencyPolicy: Forbid jobTemplate: metadata: labels: {{ tuple $envAll "trove" "db-purge" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} spec: template: metadata: labels: {{ tuple $envAll "trove" "db-purge" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} spec: {{ tuple "trove_db_purge" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 10 }} {{ tuple "trove_db_purge" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 10 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "db_purge" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 10 }} restartPolicy: OnFailure {{ if $envAll.Values.pod.tolerations.trove.enabled }} {{ tuple $envAll "trove" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 10 }} {{ end }} nodeSelector: {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} initContainers: {{ tuple $envAll "db_purge" $mounts_trove_db_purge_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 12 }} containers: - name: trove-db-purge {{ tuple $envAll "trove_db_purge" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.db_purge | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} {{ dict "envAll" $envAll "application" "db_purge" "container" "trove_db_purge" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 14 }} command: - /tmp/db-purge.sh env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.trove }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 16 }} {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: trove-bin mountPath: /tmp/db-purge.sh subPath: db-purge.sh readOnly: true - name: trove-etc mountPath: /etc/trove/trove.conf subPath: trove.conf readOnly: true - name: trove-etc mountPath: {{ .Values.conf.trove.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.trove.DEFAULT.log_config_append }} readOnly: true {{ if $mounts_trove_db_purge.volumeMounts }}{{ toYaml $mounts_trove_db_purge.volumeMounts | indent 16 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: trove-bin configMap: name: trove-bin defaultMode: 0555 - name: trove-etc secret: secretName: trove-etc defaultMode: 0444 {{ if $mounts_trove_db_purge.volumes }}{{ toYaml $mounts_trove_db_purge.volumes | indent 12 }}{{ end }} {{- end }} ================================================ FILE: trove/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "troveApiLivenessProbeTemplate" }} httpGet: scheme: {{ tuple "database" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "database" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "troveApiReadinessProbeTemplate" }} httpGet: scheme: {{ tuple "database" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "database" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_trove_api := .Values.pod.mounts.trove_api.trove_api }} {{- $mounts_trove_api_init := .Values.pod.mounts.trove_api.init_container }} {{- $serviceAccountName := "trove-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: trove-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "trove_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "trove-api" "containerNames" (list "trove-api" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "trove_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "trove_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "trove_api" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.trove.enabled }} {{ tuple $envAll "trove" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_trove_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: trove-api {{ tuple $envAll "trove_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "trove_api" "container" "trove_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.trove }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/trove-api.sh - start ports: - name: t-api containerPort: {{ tuple "database" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "api" "container" "trove-api" "type" "liveness" "probeTemplate" (include "troveApiLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "trove-api" "type" "readiness" "probeTemplate" (include "troveApiReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.trove.oslo_concurrency.lock_path }} - name: trove-bin mountPath: /tmp/trove-api.sh subPath: trove-api.sh readOnly: true - name: trove-etc mountPath: /etc/trove/trove.conf subPath: trove.conf readOnly: true - name: trove-etc mountPath: {{ .Values.conf.trove.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.trove.DEFAULT.log_config_append }} readOnly: true - name: trove-etc mountPath: /etc/trove/api-paste.ini subPath: api-paste.ini readOnly: true - name: trove-etc mountPath: /etc/trove/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_trove_api.volumeMounts }}{{ toYaml $mounts_trove_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: trove-bin configMap: name: trove-bin defaultMode: 0555 - name: trove-etc secret: secretName: trove-etc defaultMode: 0444 {{ if $mounts_trove_api.volumes }}{{ toYaml $mounts_trove_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: trove/templates/deployment-conductor.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_conductor }} {{- $envAll := . }} {{- $mounts_trove_conductor := .Values.pod.mounts.trove_conductor.trove_conductor }} {{- $mounts_trove_conductor_init := .Values.pod.mounts.trove_conductor.init_container }} {{- $serviceAccountName := "trove-conductor" }} {{ tuple $envAll "conductor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: trove-conductor annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "trove" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.conductor }} selector: matchLabels: {{ tuple $envAll "trove" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "trove" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "trove_conductor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "trove-conductor" "containerNames" (list "trove-conductor" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "trove_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "trove_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "trove_conductor" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "trove" "conductor" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.trove.enabled }} {{ tuple $envAll "trove" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.conductor.node_selector_key }}: {{ .Values.labels.conductor.node_selector_value }} initContainers: {{ tuple $envAll "conductor" $mounts_trove_conductor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: trove-conductor {{ tuple $envAll "trove_conductor" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.conductor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "trove_conductor" "container" "trove_conductor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.trove }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/trove-conductor.sh - start volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.trove.oslo_concurrency.lock_path }} - name: trove-bin mountPath: /tmp/trove-conductor.sh subPath: trove-conductor.sh readOnly: true - name: trove-etc mountPath: /etc/trove/trove.conf subPath: trove.conf readOnly: true - name: trove-etc mountPath: {{ .Values.conf.trove.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.trove.DEFAULT.log_config_append }} readOnly: true - name: trove-etc mountPath: /etc/trove/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_trove_conductor.volumeMounts }}{{ toYaml $mounts_trove_conductor.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: trove-bin configMap: name: trove-bin defaultMode: 0555 - name: trove-etc secret: secretName: trove-etc defaultMode: 0444 {{ if $mounts_trove_conductor.volumes }}{{ toYaml $mounts_trove_conductor.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: trove/templates/deployment-taskmanager.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_taskmanager }} {{- $envAll := . }} {{- $mounts_trove_taskmanager := .Values.pod.mounts.trove_taskmanager.trove_taskmanager }} {{- $mounts_trove_taskmanager_init := .Values.pod.mounts.trove_taskmanager.init_container }} {{- $serviceAccountName := "trove-taskmanager" }} {{ tuple $envAll "taskmanager" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: trove-taskmanager annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "trove" "taskmanager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.taskmanager }} selector: matchLabels: {{ tuple $envAll "trove" "taskmanager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "trove" "taskmanager" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "trove_taskmanager" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "trove-taskmanager" "containerNames" (list "trove-taskmanager" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "trove_taskmanager" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "trove_taskmanager" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "trove_taskmanager" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "trove" "taskmanager" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} {{ if $envAll.Values.pod.tolerations.trove.enabled }} {{ tuple $envAll "trove" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} nodeSelector: {{ .Values.labels.taskmanager.node_selector_key }}: {{ .Values.labels.taskmanager.node_selector_value }} initContainers: {{ tuple $envAll "taskmanager" $mounts_trove_taskmanager_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: trove-taskmanager {{ tuple $envAll "trove_taskmanager" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.taskmanager | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "trove_taskmanager" "container" "trove_taskmanager" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.trove }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: - /tmp/trove-taskmanager.sh - start volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.trove.oslo_concurrency.lock_path }} - name: trove-bin mountPath: /tmp/trove-taskmanager.sh subPath: trove-taskmanager.sh readOnly: true - name: trove-etc mountPath: /etc/trove/trove.conf subPath: trove.conf readOnly: true - name: trove-etc mountPath: {{ .Values.conf.trove.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.trove.DEFAULT.log_config_append }} readOnly: true - name: trove-etc mountPath: /etc/trove/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_trove_taskmanager.volumeMounts }}{{ toYaml $mounts_trove_taskmanager.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: trove-bin configMap: name: trove-bin defaultMode: 0555 - name: trove-etc secret: secretName: trove-etc defaultMode: 0444 {{ if $mounts_trove_taskmanager.volumes }}{{ toYaml $mounts_trove_taskmanager.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: trove/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: trove/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" . "backendService" "api" "backendServiceType" "database" "backendPort" "t-api" -}} {{- if .Values.network.api.ingress.classes -}} {{- $_ := set $ingressOpts "ingressClassName" ( index .Values.network.api.ingress.classes .Release.Namespace | default ( index .Values.network.api.ingress.classes "cluster" ) ) -}} {{- end -}} {{- $secretName := index $envAll.Values.secrets.tls.database.api ( $ingressOpts.backendService | replace "-" "_" ) -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.database.host_fqdn_override.public.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: trove/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "trove" -}} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: trove/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "trove" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: trove/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "trove" "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: trove/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "trove" -}} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: trove/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksEndpointsJob := dict "envAll" . "serviceName" "trove" "serviceTypes" ( tuple "database" ) -}} {{- $_ := set $ksEndpointsJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $ksEndpointsJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksEndpointsJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: trove/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "trove" "serviceTypes" ( tuple "database" ) -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: trove/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "trove" -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) }} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: trove/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.rabbit_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_rabbit_init }} {{- $rabbitInitJob := dict "envAll" . "serviceName" "trove" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $rabbitInitJob "tlsSecret" .Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $rabbitInitJob "jobAnnotations" (include "metadata.annotations.job.rabbit_init" . | fromYaml) }} {{- if .Values.pod.tolerations.trove.enabled -}} {{- $_ := set $rabbitInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $rabbitInitJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: trove/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $envAll := . }} --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: trove-default spec: podSelector: matchLabels: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 12 }} ports: {{ tuple "database" "service" "api" . | include "helm-toolkit.manifests.network_policy_list" | indent 8 }} egress: - to: - namespaceSelector: matchLabels: name: kube-system - to: - namespaceSelector: matchLabels: name: {{ .Release.Namespace }} ports: {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.manifests.network_policy_list" | indent 8 }} {{ tuple "oslo_messaging" "internal" "amqp" . | include "helm-toolkit.manifests.network_policy_list" | indent 8 }} {{ tuple "identity" "internal" "api" . | include "helm-toolkit.manifests.network_policy_list" | indent 8 }} {{- end }} ================================================ FILE: trove/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: trove-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: trove/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_trove_tests := .Values.pod.mounts.trove_tests.trove_tests }} {{- $mounts_trove_tests_init := .Values.pod.mounts.trove_tests.init_container }} {{- $serviceAccountName := "trove-tests" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "trove-tests" labels: {{ tuple $envAll "trove" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": "test" "helm.sh/hook-weight": "10" spec: {{ tuple "trove_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "trove_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} restartPolicy: Never serviceAccountName: {{ $serviceAccountName }} {{ if $envAll.Values.pod.tolerations.trove.enabled }} {{ tuple $envAll "trove" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} initContainers: {{ tuple $envAll "tests" $mounts_trove_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: trove-tests {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.Release.Name | quote }} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: trove-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally {{ if $mounts_trove_tests.volumeMounts }}{{ toYaml $mounts_trove_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: trove-bin configMap: name: trove-bin defaultMode: 0555 - name: rally-db emptyDir: {} {{ if $mounts_trove_tests.volumes }}{{ toYaml $mounts_trove_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: trove/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "trove" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- $userClassData := index $envAll.Values.endpoints.oslo_db.auth $userClass }} {{- if $userClassData.username }} DB_CONNECTION: {{ tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} {{- end }} ================================================ FILE: trove/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "database" ) }} {{- end }} ================================================ FILE: trove/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "trove" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- $identityClass := index $envAll.Values.endpoints.identity.auth $userClass }} {{- if $identityClass.username }} OS_AUTH_URL: {{ tuple "identity" "internal" "api" $envAll | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | b64enc }} OS_REGION_NAME: {{ $identityClass.region_name | b64enc }} OS_INTERFACE: {{ $identityClass.interface | default "internal" | b64enc }} OS_ENDPOINT_TYPE: {{ $identityClass.interface | default "internal" | b64enc }} OS_PROJECT_DOMAIN_NAME: {{ $identityClass.project_domain_name | b64enc }} OS_PROJECT_NAME: {{ $identityClass.project_name | b64enc }} OS_USER_DOMAIN_NAME: {{ $identityClass.user_domain_name | b64enc }} OS_USERNAME: {{ $identityClass.username | b64enc }} OS_PASSWORD: {{ $identityClass.password | b64enc }} OS_DEFAULT_DOMAIN: {{ $identityClass.default_domain_id | default "default" | b64enc }} {{- end }} {{- end }} {{- end }} ================================================ FILE: trove/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- $rabbitmqProtocol := "http" }} {{- if $envAll.Values.manifests.certificates }} {{- $rabbitmqProtocol = "https" }} {{- end }} {{- range $key1, $userClass := tuple "admin" "trove" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_messaging" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass $rabbitmqProtocol $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: trove/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_registry }} {{- $envAll := . }} {{- if .Values.endpoints.oci_image_registry.auth.enabled }} {{- $secretName := .Values.secrets.oci_image_registry.trove }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: {{ include "helm-toolkit.utils.imagePullSecret" ( dict "images" ( list .Values.endpoints.oci_image_registry ) "secret" ( dict "name" $secretName "namespace" $envAll.Release.Namespace ) ) }} {{- end }} {{- end }} ================================================ FILE: trove/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "database" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: t-api port: {{ tuple "database" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "trove" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{ end }} {{ end }} {{- end }} ================================================ FILE: trove/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_ingress_api }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "database" "backendPort" "t-api" -}} {{- $secretName := $envAll.Values.secrets.tls.database.api.internal -}} {{- if and .Values.manifests.certificates $secretName -}} {{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.database.host_fqdn_override.default.tls.issuerRef.name -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: trove/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for trove. # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled conductor: node_selector_key: openstack-control-plane node_selector_value: enabled taskmanager: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 db_init: quay.io/airshipit/heat:2025.1-ubuntu_noble trove_db_sync: quay.io/airshipit/trove:2025.1-ubuntu_noble db_drop: quay.io/airshipit/heat:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/heat:2025.1-ubuntu_noble ks_service: quay.io/airshipit/heat:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/heat:2025.1-ubuntu_noble trove_api: quay.io/airshipit/trove:2025.1-ubuntu_noble trove_conductor: quay.io/airshipit/trove:2025.1-ubuntu_noble trove_taskmanager: quay.io/airshipit/trove:2025.1-ubuntu_noble trove_db_purge: quay.io/airshipit/trove:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync jobs: db_purge: cron: "0 0 * * *" starting_deadline: 600 history: success: 3 failed: 1 pod: probes: api: trove-api: liveness: enabled: true params: initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds: 1 failureThreshold: 3 successThreshold: 1 readiness: enabled: true params: initialDelaySeconds: 30 security_context: db_purge: pod: runAsUser: 42424 container: trove_db_purge: readOnlyRootFilesystem: true allowPrivilegeEscalation: false trove_api: pod: runAsUser: 42424 container: trove_api: readOnlyRootFilesystem: true allowPrivilegeEscalation: false trove_conductor: pod: runAsUser: 42424 container: trove_conductor: readOnlyRootFilesystem: true allowPrivilegeEscalation: false trove_taskmanager: pod: runAsUser: 42424 container: trove_taskmanager: readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: trove: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: trove_api: init_container: null trove_api: volumeMounts: volumes: trove_conductor: init_container: null trove_conductor: volumeMounts: volumes: trove_taskmanager: init_container: null trove_taskmanager: volumeMounts: volumes: trove_db_purge: init_container: null trove_db_purge: volumeMounts: volumes: trove_tests: init_container: null trove_tests: volumeMounts: volumes: trove_db_sync: trove_db_sync: volumeMounts: volumes: replicas: api: 1 conductor: 1 taskmanager: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conductor: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" taskmanager: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_purge: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30878 conf: paste: composite:trove: use: call:trove.common.wsgi:versioned_urlmap /: versions /v1.0: troveapi app:versions: paste.app_factory: trove.versions:app_factory pipeline:troveapi: pipeline: http_proxy_to_wsgi faultwrapper authtoken authorization contextwrapper ratelimit extensions troveapp filter:extensions: paste.filter_factory: trove.common.extensions:factory filter:authtoken: paste.filter_factory: keystonemiddleware.auth_token:filter_factory filter:authorization: paste.filter_factory: trove.common.auth:AuthorizationMiddleware.factory filter:contextwrapper: paste.filter_factory: trove.common.wsgi:ContextMiddleware.factory filter:faultwrapper: paste.filter_factory: trove.common.wsgi:FaultWrapper.factory filter:ratelimit: paste.filter_factory: trove.common.limits:RateLimitingMiddleware.factory filter:http_proxy_to_wsgi: paste.filter_factory: oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory app:troveapp: paste.app_factory: trove.common.api:app_factory policy: {} trove: DEFAULT: log_config_append: /etc/trove/logging.conf trove_api_workers: 4 transport_url: null # control_exchange: trove # ip_regex: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ # black_list_regex: ^10\.0\.0\.[0-9]+$ default_datastore: mysql datastore_registry_ext: mysql:trove.guestagent.datastore.mysql.manager.Manager trove_conductor_workers: 1 notification_service_id: mysql:2f3ff068-2bfb-4f70-9a9d-a6bb65bc084b os_region_name: RegionOne # nova_compute_url: "" # neutron_url: "" # cinder_url: "" # swift_url: "" # glance_url: "" # heat_url: "" trove_volume_support: true network_isolation: false database: # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT service_credentials: auth_url: null region_name: RegionOne interface: internal auth_type: password oslo_messaging_notifications: driver: messagingv2 oslo_messaging_rabbit: rabbit_ha_queues: true oslo_concurrency: lock_path: /var/lock oslo_policy: policy_file: /etc/trove/policy.yaml logging: loggers: keys: - root - trove handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: DEBUG handlers: - stdout logger_trove: level: DEBUG handlers: - stdout qualname: trove logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" rally_tests: run_tempest: false tests: TroveInstances.create_and_delete_instance: - runner: type: constant times: 1 concurrency: 1 context: users: tenants: 1 users_per_tenant: 1 args: flavor_name: "m1.tiny" volume_size: 1 databases: - name: "testdb" users: - name: "testuser" password: "testpass" databases: - "testdb" dependencies: dynamic: common: local_image_registry: jobs: - trove-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - trove-db-sync - trove-ks-user - trove-ks-endpoints - trove-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging conductor: jobs: - trove-db-sync - trove-ks-user - trove-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging taskmanager: jobs: - trove-db-sync - trove-ks-user - trove-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity - endpoint: internal service: oslo_messaging db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - trove-db-init services: - endpoint: internal service: oslo_db ks_user: services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_endpoints: jobs: - trove-ks-service services: - endpoint: internal service: identity rabbit_init: services: - endpoint: internal service: oslo_messaging image_repo_sync: services: - endpoint: internal service: local_image_registry tests: services: - endpoint: internal service: identity - endpoint: internal service: database # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: trove-keystone-admin trove: trove-keystone-user oslo_db: admin: trove-db-admin trove: trove-db-user oslo_messaging: admin: trove-rabbitmq-admin trove: trove-rabbitmq-user tls: database: api: public: trove-tls-public internal: trove-tls-api oci_image_registry: trove: trove-oci-image-registry-key # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false trove: username: trove password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default trove: role: admin region_name: RegionOne username: trove password: password project_name: service user_domain_name: service project_domain_name: service nova: role: admin,service region_name: RegionOne username: nova password: password project_name: service user_domain_name: service project_domain_name: service neutron: role: admin,service region_name: RegionOne project_name: service user_domain_name: service project_domain_name: service username: neutron password: password cinder: role: admin,service region_name: RegionOne username: cinder password: password project_name: service user_domain_name: service project_domain_name: service glance: role: admin,service region_name: RegionOne username: glance password: password project_name: service user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 database: name: trove hosts: default: trove-api public: trove host_fqdn_override: default: null # NOTE: this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: /v1.0/%(tenant_id)s scheme: default: http port: api: default: 8779 public: 80 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct trove: username: trove password: password hosts: default: mariadb host_fqdn_override: default: null path: /trove scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password secret: tls: internal: rabbitmq-tls-direct trove: username: trove password: password statefulset: replicas: 2 name: rabbitmq-rabbitmq hosts: default: rabbitmq host_fqdn_override: default: null path: /trove scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE: this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 compute: name: nova hosts: default: nova-api public: nova host_fqdn_override: default: null # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public # endpoints using the following format: # public: # host: null # tls: # crt: null # key: null path: default: "/v2.1/" scheme: default: 'http' service: 'http' port: api: default: 8774 public: 80 service: 8774 novncproxy: default: 6080 network: name: neutron hosts: default: neutron-server public: neutron host_fqdn_override: default: null path: default: null scheme: default: 'http' port: api: default: 9696 public: 80 volumev3: name: cinderv3 hosts: default: cinder-api public: cinder host_fqdn_override: default: null path: default: '/v3' healthcheck: /healthcheck scheme: default: http port: api: default: 8776 public: 80 image: name: glance hosts: default: glance-api public: glance host_fqdn_override: default: null path: default: null scheme: default: http port: api: default: 9292 public: 80 manifests: certificates: false configmap_bin: true configmap_etc: true cron_job_db_purge: true deployment_api: true deployment_conductor: true deployment_taskmanager: true ingress_api: true job_bootstrap: false job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true network_policy: false pdb_api: true pod_rally_test: true secret_db: true secret_ingress_tls: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_api: true service_ingress_api: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: values_overrides/aodh/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble aodh_db_sync: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_api: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_evaluator: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_listener: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_notifier: quay.io/airshipit/aodh:2025.1-ubuntu_noble aodh_alarms_cleaner: quay.io/airshipit/aodh:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/aodh/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble aodh_db_sync: quay.io/airshipit/aodh:2025.2-ubuntu_noble aodh_api: quay.io/airshipit/aodh:2025.2-ubuntu_noble aodh_evaluator: quay.io/airshipit/aodh:2025.2-ubuntu_noble aodh_listener: quay.io/airshipit/aodh:2025.2-ubuntu_noble aodh_notifier: quay.io/airshipit/aodh:2025.2-ubuntu_noble aodh_alarms_cleaner: quay.io/airshipit/aodh:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/aodh/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" aodh_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: aodh: custom.tld/key: "value" tls: alarming_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/aodh/gateway.yaml ================================================ # Gateway API overrides for Aodh. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: alarming: host_fqdn_override: public: host: aodh.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: aodh-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.alarming.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: aodh-api port: 8042 ... ================================================ FILE: values_overrides/aodh/mariadb-operator.yaml ================================================ --- conf: aodh: database: connection: null manifests: job_db_init: false etcSources: aodh_api: - aodh-db-conn aodh_db_sync: - aodh-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: aodh namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: aodh namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: aodh-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: aodh-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "aodh" table: "*" username: aodh grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: aodh-db-conn spec: mariaDbRef: name: mariadb username: aodh passwordSecretKeyRef: name: aodh-db-password key: password database: aodh secretName: aodh-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/barbican/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" scripted_test: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" barbican_db_sync: "quay.io/airshipit/barbican:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" barbican_api: "quay.io/airshipit/barbican:2024.2-ubuntu_jammy" ... ================================================ FILE: values_overrides/barbican/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" scripted_test: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" barbican_db_sync: "quay.io/airshipit/barbican:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" barbican_api: "quay.io/airshipit/barbican:2025.1-ubuntu_jammy" ... ================================================ FILE: values_overrides/barbican/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" scripted_test: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" barbican_db_sync: "quay.io/airshipit/barbican:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" barbican_api: "quay.io/airshipit/barbican:2025.1-ubuntu_noble" ... ================================================ FILE: values_overrides/barbican/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" scripted_test: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" barbican_db_sync: "quay.io/airshipit/barbican:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" barbican_api: "quay.io/airshipit/barbican:2025.2-ubuntu_noble" ... ================================================ FILE: values_overrides/barbican/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" barbican_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: barbican: custom.tld/key: "value" tls: key_manager_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/barbican/apparmor.yaml ================================================ --- pod: security_context: barbican: container: barbican_api: appArmorProfile: type: RuntimeDefault test: container: barbican_test: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/barbican/gateway.yaml ================================================ # Gateway API overrides for Barbican. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: key_manager: host_fqdn_override: public: host: barbican.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: barbican-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.key_manager.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: barbican-api port: 9311 ... ================================================ FILE: values_overrides/barbican/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" scripted_test: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" barbican_db_sync: "quay.io/airshipit/barbican:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" barbican_api: "quay.io/airshipit/barbican:2025.1-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/barbican/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" scripted_test: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" barbican_db_sync: "quay.io/airshipit/barbican:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" barbican_api: "quay.io/airshipit/barbican:2025.2-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/barbican/mariadb-operator.yaml ================================================ --- conf: barbican: database: connection: null manifests: job_db_init: false etcSources: barbican_api: - barbican-db-conn barbican_db_sync: - barbican-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: barbican namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: barbican namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: barbican-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: barbican-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "barbican" table: "*" username: barbican grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: barbican-db-conn spec: mariaDbRef: name: mariadb username: barbican passwordSecretKeyRef: name: barbican-db-password key: password database: barbican secretName: barbican-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/barbican/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: barbican: ingress: - from: - podSelector: matchLabels: application: barbican - podSelector: matchLabels: application: ingress - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: magnum ports: - protocol: TCP port: 80 - protocol: TCP port: 9311 egress: - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/barbican/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt barbican: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/barbican/tls.yaml ================================================ --- manifests: certificates: true tls: identity: true oslo_messaging: true oslo_db: true ... ================================================ FILE: values_overrides/blazar/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy blazar_api: quay.io/airshipit/blazar:2025.1-ubuntu_jammy blazar_manager: quay.io/airshipit/blazar:2025.1-ubuntu_jammy blazar_db_sync: quay.io/airshipit/blazar:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/blazar/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble blazar_api: quay.io/airshipit/blazar:2025.1-ubuntu_noble blazar_manager: quay.io/airshipit/blazar:2025.1-ubuntu_noble blazar_db_sync: quay.io/airshipit/blazar:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/blazar/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble blazar_api: quay.io/airshipit/blazar:2025.2-ubuntu_noble blazar_manager: quay.io/airshipit/blazar:2025.2-ubuntu_noble blazar_db_sync: quay.io/airshipit/blazar:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/blazar/gateway.yaml ================================================ # Gateway API overrides for Blazar. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: reservation: host_fqdn_override: public: host: blazar.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: blazar-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.reservation.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: blazar-api port: 1234 ... ================================================ FILE: values_overrides/blazar/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci blazar_api: quay.io/airshipit/blazar:2025.1-ubuntu_noble_loci blazar_manager: quay.io/airshipit/blazar:2025.1-ubuntu_noble_loci blazar_db_sync: quay.io/airshipit/blazar:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/blazar/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci blazar_api: quay.io/airshipit/blazar:2025.2-ubuntu_noble_loci blazar_manager: quay.io/airshipit/blazar:2025.2-ubuntu_noble_loci blazar_db_sync: quay.io/airshipit/blazar:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/blazar/mariadb-operator.yaml ================================================ --- conf: blazar: database: connection: null manifests: job_db_init: false etcSources: blazar_api: - blazar-db-conn blazar_db_sync: - blazar-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: blazar namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: blazar namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: blazar-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: blazar-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "blazar" table: "*" username: blazar grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: blazar-db-conn spec: mariaDbRef: name: mariadb username: blazar passwordSecretKeyRef: name: blazar-db-password key: password database: blazar secretName: blazar-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/ceilometer/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ceilometer_central: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ceilometer_compute: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ceilometer_ipmi: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ceilometer_notification: quay.io/airshipit/ceilometer:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/ceilometer/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ceilometer_central: quay.io/airshipit/ceilometer:2025.2-ubuntu_noble ceilometer_compute: quay.io/airshipit/ceilometer:2025.2-ubuntu_noble ceilometer_ipmi: quay.io/airshipit/ceilometer:2025.2-ubuntu_noble ceilometer_notification: quay.io/airshipit/ceilometer:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/ceilometer/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" ceilometer_compute: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: ceilometer: custom.tld/key: "value" ... ================================================ FILE: values_overrides/ceph-client/apparmor.yaml ================================================ --- pod: security_context: checkdns: container: checkdns: appArmorProfile: type: RuntimeDefault mds: container: mds: appArmorProfile: type: RuntimeDefault init_dirs: appArmorProfile: type: RuntimeDefault rbd_pool: container: rbd_pool: appArmorProfile: type: RuntimeDefault bootstrap: container: bootstrap: appArmorProfile: type: RuntimeDefault test: container: test: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/ceph-mon/apparmor.yaml ================================================ --- pod: security_context: mon: container: ceph_mon: appArmorProfile: type: RuntimeDefault ceph_init_dirs: appArmorProfile: type: RuntimeDefault ceph_log_ownership: appArmorProfile: type: RuntimeDefault mgr: container: mgr: appArmorProfile: type: RuntimeDefault init_dirs: appArmorProfile: type: RuntimeDefault moncheck: container: ceph_mon: appArmorProfile: type: RuntimeDefault bootstrap: container: ceph_bootstrap: appArmorProfile: type: RuntimeDefault storage_keys_generator: container: ceph_storage_keys_generator: appArmorProfile: type: RuntimeDefault ceph: container: ceph_mon_keyring_generator: appArmorProfile: type: RuntimeDefault ceph_mgr_keyring_generator: appArmorProfile: type: RuntimeDefault ceph_mds_keyring_generator: appArmorProfile: type: RuntimeDefault ceph_osd_keyring_generator: appArmorProfile: type: RuntimeDefault post_apply: container: ceph_mon_post_apply: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/ceph-osd/apparmor.yaml ================================================ --- pod: security_context: osd: container: osd_pod: appArmorProfile: type: RuntimeDefault log_runner: appArmorProfile: type: RuntimeDefault ceph_init_dirs: appArmorProfile: type: RuntimeDefault ceph_log_ownership: appArmorProfile: type: RuntimeDefault osd_init: appArmorProfile: type: RuntimeDefault test: container: ceph_cluster_helm_test: appArmorProfile: type: RuntimeDefault post_apply: container: ceph_osd_post_apply: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/ceph-provisioners/apparmor.yaml ================================================ --- pod: security_context: cephfs_client_key_generator: container: ceph_storage_keys_generator: appArmorProfile: type: RuntimeDefault provisioner: container: ceph_rbd_provisioner: appArmorProfile: type: RuntimeDefault ceph_rbd_snapshotter: appArmorProfile: type: RuntimeDefault ceph_rbd_attacher: appArmorProfile: type: RuntimeDefault ceph_rbd_resizer: appArmorProfile: type: RuntimeDefault ceph_rbd_cephcsi: appArmorProfile: type: RuntimeDefault test: container: test: appArmorProfile: type: RuntimeDefault client_key_generator: container: ceph_storage_keys_generator: appArmorProfile: type: RuntimeDefault plugin: container: ceph_rbd_registrar: appArmorProfile: type: RuntimeDefault ceph_csi_rbd_plugin: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/ceph-rgw/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_endpoints: 'quay.io/airshipit/heat:2024.2-ubuntu_jammy' ks_service: 'quay.io/airshipit/heat:2024.2-ubuntu_jammy' ks_user: 'quay.io/airshipit/heat:2024.2-ubuntu_jammy' ... ================================================ FILE: values_overrides/ceph-rgw/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_endpoints: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy' ks_service: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy' ks_user: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy' ... ================================================ FILE: values_overrides/ceph-rgw/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_endpoints: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble' ks_service: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble' ks_user: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble' ... ================================================ FILE: values_overrides/ceph-rgw/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_endpoints: 'quay.io/airshipit/openstack-client:2025.2-ubuntu_noble' ks_service: 'quay.io/airshipit/openstack-client:2025.2-ubuntu_noble' ks_user: 'quay.io/airshipit/openstack-client:2025.2-ubuntu_noble' ... ================================================ FILE: values_overrides/ceph-rgw/apparmor.yaml ================================================ --- pod: security_context: rgw: container: rgw: appArmorProfile: type: RuntimeDefault init_dirs: appArmorProfile: type: RuntimeDefault rgw_init: appArmorProfile: type: RuntimeDefault bootstrap: container: bootstrap: appArmorProfile: type: RuntimeDefault keyring_placement: appArmorProfile: type: RuntimeDefault rgw_storage_init: container: rgw_storage_init: appArmorProfile: type: RuntimeDefault keyring_placement: appArmorProfile: type: RuntimeDefault rgw_s3_admin: container: create_s3_admin: appArmorProfile: type: RuntimeDefault keyring_placement: appArmorProfile: type: RuntimeDefault rgw_pool: container: rgw_pool: appArmorProfile: type: RuntimeDefault rgw_test: container: ceph_rgw_ks_validation: appArmorProfile: type: RuntimeDefault ceph_rgw_s3_validation: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/ceph-rgw/gateway.yaml ================================================ # Gateway API overrides for Ceph RGW. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: ceph_object_store: host_fqdn_override: public: host: ceph-rgw.openstack-helm.org manifests: ingress_rgw: false service_ingress_rgw: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: ceph-rgw-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.ceph_object_store.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: ceph-rgw port: 8088 ... ================================================ FILE: values_overrides/ceph-rgw/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_endpoints: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci' ks_service: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci' ks_user: 'quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci' ... ================================================ FILE: values_overrides/ceph-rgw/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_endpoints: 'quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci' ks_service: 'quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci' ks_user: 'quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci' ... ================================================ FILE: values_overrides/ceph-rgw/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: rgw: egress: - to: - ipBlock: cidr: 172.17.0.1/16 - to: ports: - protocol: TCP port: 80 - protocol: TCP port: 443 - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/ceph-rgw/tls.yaml ================================================ --- endpoints: object_store: scheme: default: https host_fqdn_override: default: tls: secretName: ceph-rgw-ks-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer ceph_object_store: scheme: default: https host_fqdn_override: default: tls: secretName: ceph-rgw-s3-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer network: api: ingress: public: true classes: namespace: "nginx" cluster: "nginx-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "0" nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" external_policy_local: false node_port: enabled: false port: 30004 public: 192.168.0.0/16 cluster: 192.168.0.0/16 manifests: certificates: true ... ================================================ FILE: values_overrides/cinder/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" cinder_db_sync: "quay.io/airshipit/cinder:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" cinder_api: "quay.io/airshipit/cinder:2024.2-ubuntu_jammy" bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" cinder_scheduler: "quay.io/airshipit/cinder:2024.2-ubuntu_jammy" cinder_volume: "quay.io/airshipit/cinder:2024.2-ubuntu_jammy" cinder_volume_usage_audit: "quay.io/airshipit/cinder:2024.2-ubuntu_jammy" cinder_db_purge: "quay.io/airshipit/cinder:2024.2-ubuntu_jammy" cinder_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" cinder_backup: "quay.io/airshipit/cinder:2024.2-ubuntu_jammy" cinder_backup_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/cinder/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" cinder_db_sync: "quay.io/airshipit/cinder:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" cinder_api: "quay.io/airshipit/cinder:2025.1-ubuntu_jammy" bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" cinder_scheduler: "quay.io/airshipit/cinder:2025.1-ubuntu_jammy" cinder_volume: "quay.io/airshipit/cinder:2025.1-ubuntu_jammy" cinder_volume_usage_audit: "quay.io/airshipit/cinder:2025.1-ubuntu_jammy" cinder_db_purge: "quay.io/airshipit/cinder:2025.1-ubuntu_jammy" cinder_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" cinder_backup: "quay.io/airshipit/cinder:2025.1-ubuntu_jammy" cinder_backup_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/cinder/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" cinder_db_sync: "quay.io/airshipit/cinder:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" cinder_api: "quay.io/airshipit/cinder:2025.1-ubuntu_noble" bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" cinder_scheduler: "quay.io/airshipit/cinder:2025.1-ubuntu_noble" cinder_volume: "quay.io/airshipit/cinder:2025.1-ubuntu_noble" cinder_volume_usage_audit: "quay.io/airshipit/cinder:2025.1-ubuntu_noble" cinder_db_purge: "quay.io/airshipit/cinder:2025.1-ubuntu_noble" cinder_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" cinder_backup: "quay.io/airshipit/cinder:2025.1-ubuntu_noble" cinder_backup_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/cinder/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" cinder_db_sync: "quay.io/airshipit/cinder:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" cinder_api: "quay.io/airshipit/cinder:2025.2-ubuntu_noble" bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" cinder_scheduler: "quay.io/airshipit/cinder:2025.2-ubuntu_noble" cinder_volume: "quay.io/airshipit/cinder:2025.2-ubuntu_noble" cinder_volume_usage_audit: "quay.io/airshipit/cinder:2025.2-ubuntu_noble" cinder_db_purge: "quay.io/airshipit/cinder:2025.2-ubuntu_noble" cinder_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" cinder_backup: "quay.io/airshipit/cinder:2025.2-ubuntu_noble" cinder_backup_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/cinder/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" cinder_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: cinder: custom.tld/key: "value" rbd: volume_external: custom.tld/key: "value" tls: volume_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/cinder/apparmor.yaml ================================================ --- pod: security_context: cinder_api: container: cinder_api: appArmorProfile: type: RuntimeDefault ceph_coordination_volume_perms: appArmorProfile: type: RuntimeDefault cinder_backup: container: cinder_backup: appArmorProfile: type: RuntimeDefault ceph_coordination_volume_perms: appArmorProfile: type: RuntimeDefault cinder_scheduler: container: cinder_scheduler: appArmorProfile: type: RuntimeDefault ceph_coordination_volume_perms: appArmorProfile: type: RuntimeDefault cinder_volume: container: cinder_volume: appArmorProfile: type: RuntimeDefault ceph_coordination_volume_perms: appArmorProfile: type: RuntimeDefault init_cinder_conf: appArmorProfile: type: RuntimeDefault storage_init: container: cinder_backup_storage_init: appArmorProfile: type: RuntimeDefault create_internal_tenant: container: create_internal_tenant: appArmorProfile: type: RuntimeDefault volume_usage_audit: container: cinder_volume_usage_audit: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/cinder/backend_pure.yaml ================================================ # NOTE: In order for below code to work, package "purestorage" # needs to be built into Cinder and Nova images. --- pod: useHostNetwork: volume: true backup: true security_context: cinder_volume: container: cinder_volume: readOnlyRootFilesystem: true privileged: true cinder_backup: container: cinder_backup: privileged: true bootstrap: volume_types: # volume type for PURE with multiattach on PURE-MULTIATTACH: multiattach: "\" True\"" volume_backend_name: "PURE_BE" access_type: "private" grant_access: default: - admin conf: cinder: DEFAULT: enabled_backends: "rbd1,PURE" backends: PURE: pure_eradicate_on_delete: true volume_backend_name: PURE_BE # NOTE: Replace below pure-api-token-value with the real token value pure_api_token: pure-api-token-value volume_driver: cinder.volume.drivers.pure.PureISCSIDriver use_multipath_for_image_xfer: true # NOTE: Replace below 1.1.1.1 with the real ip value san_ip: 1.1.1.1 enable_iscsi: true ... ================================================ FILE: values_overrides/cinder/external-ceph-backend.yaml ================================================ # Note: This yaml file serves as an example for overriding the manifest # to enable additional externally managed Ceph Cinder backend. # values_overrides/libvirt/cinder-external-ceph-backend.yaml in repo # openstack-helm is also needed for the attachment of ceph volumes. --- ceph_client: enable_external_ceph_backend: True external_ceph: rbd_user: cinder2 rbd_user_keyring: RBDUserKeyRing conf: global: auth client required: none auth cluster required: none auth service required: none cluster network: 172.31.0.128/25 fsid: 538fe375-1ee2-4719-a89e-1ff2cd851a1f log_to_syslog: False mon_host: "[v2:172.31.0.187:3300,v1:172.31.0.187:6789],[v2:172.31.0.188:3300,v1:172.31.0.188:6789],[v2:172.31.0.189:3300,v1:172.31.0.189:6789]" mon initial members: "host1,host2,host3" mon_allow_pool_delete: True mon_compact_on_trim: False mutex_perf_counter: False osd pool default crush rule: -1 public network: 172.31.0.128/25 osd: ms_dispatch_throttle_bytes: 1048576000 objecter_inflight_op_bytes: 1048576000 objecter_inflight_ops: 102400 osd memory target: 17599882854 osd_max_pg_log_entries: 10 osd_min_pg_log_entries: 10 osd_pg_log_dups_tracked: 10 osd_pg_log_trim_min: 10 conf: cinder: DEFAULT: enabled_backends: "rbd1,rbd2" backends: rbd2: volume_driver: cinder.volume.drivers.rbd.RBDDriver volume_backend_name: rbd2 rbd_pool: cinder2.volumes rbd_ceph_conf: "/etc/ceph/external-ceph.conf" rbd_flatten_volume_from_snapshot: False report_discard_supported: True rbd_max_clone_depth: 5 rbd_store_chunk_size: 4 rados_connect_timeout: -1 rbd_user: cinder2 rbd_secret_uuid: 3f0133e4-8384-4743-9473-fecacc095c74 image_volume_cache_enabled: True image_volume_cache_max_size_gb: 200 image_volume_cache_max_count: 50 ... ================================================ FILE: values_overrides/cinder/external-ceph-configmap.yaml ================================================ # Note: This yaml file serves as an example for overriding the manifest # to enable additional externally managed Ceph Cinder backend. # Configuration of external ceph cluster is provided by a pre-existing configmap. # For backup external ceph, backup-external-ceph configmap with ceph.conf data field. # For 2nd tier external ceph, external-ceph configmap with external-ceph.conf data field. --- backup: external_ceph_rbd: enabled: true configmap: backup-external-ceph ceph_client: enable_external_ceph_backend: True external_ceph: rbd_user: cinder2 rbd_user_keyring: RBDUserKeyRing configmap: external-ceph conf: cinder: DEFAULT: enabled_backends: "rbd1,rbd2" backends: rbd2: volume_driver: cinder.volume.drivers.rbd.RBDDriver volume_backend_name: rbd2 rbd_pool: cinder2.volumes rbd_ceph_conf: "/etc/ceph/external-ceph.conf" rbd_flatten_volume_from_snapshot: False report_discard_supported: True rbd_max_clone_depth: 5 rbd_store_chunk_size: 4 rados_connect_timeout: -1 rbd_user: cinder2 rbd_secret_uuid: 3f0133e4-8384-4743-9473-fecacc095c74 image_volume_cache_enabled: True image_volume_cache_max_size_gb: 200 image_volume_cache_max_count: 50 ... ================================================ FILE: values_overrides/cinder/gateway.yaml ================================================ # Gateway API overrides for Cinder. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: volumev3: host_fqdn_override: public: host: cinder.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: cinder-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.volumev3.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: cinder-api port: 8776 ... ================================================ FILE: values_overrides/cinder/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" cinder_db_sync: "quay.io/airshipit/cinder:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" cinder_api: "quay.io/airshipit/cinder:2025.1-ubuntu_noble_loci" bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" cinder_scheduler: "quay.io/airshipit/cinder:2025.1-ubuntu_noble_loci" cinder_volume: "quay.io/airshipit/cinder:2025.1-ubuntu_noble_loci" cinder_volume_usage_audit: "quay.io/airshipit/cinder:2025.1-ubuntu_noble_loci" cinder_db_purge: "quay.io/airshipit/cinder:2025.1-ubuntu_noble_loci" cinder_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" cinder_backup: "quay.io/airshipit/cinder:2025.1-ubuntu_noble_loci" cinder_backup_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/cinder/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" cinder_db_sync: "quay.io/airshipit/cinder:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" cinder_api: "quay.io/airshipit/cinder:2025.2-ubuntu_noble_loci" bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" cinder_scheduler: "quay.io/airshipit/cinder:2025.2-ubuntu_noble_loci" cinder_volume: "quay.io/airshipit/cinder:2025.2-ubuntu_noble_loci" cinder_volume_usage_audit: "quay.io/airshipit/cinder:2025.2-ubuntu_noble_loci" cinder_db_purge: "quay.io/airshipit/cinder:2025.2-ubuntu_noble_loci" cinder_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" cinder_backup: "quay.io/airshipit/cinder:2025.2-ubuntu_noble_loci" cinder_backup_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/cinder/mariadb-operator.yaml ================================================ --- conf: cinder: database: connection: null manifests: job_db_init: false etcSources: cinder_api: - cinder-db-conn cinder_db_sync: - cinder-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: cinder namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: cinder namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: cinder-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: cinder-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "cinder" table: "*" username: cinder grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: cinder-db-conn spec: mariaDbRef: name: mariadb username: cinder passwordSecretKeyRef: name: cinder-db-password key: password database: cinder secretName: cinder-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/cinder/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: cinder: egress: - to: - ipBlock: cidr: 172.17.0.1/16 - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/16 - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/cinder/nfs-cinder-backup.yaml ================================================ --- conf: cinder: DEFAULT: backup_driver: cinder.backup.drivers.nfs.NFSBackupDriver backup_mount_point_base: /backup/openstack/cinder backup_share: 10.30.1.3:/ pod: mounts: cinder_backup: cinder_backup: volumeMounts: - mountPath: /backup name: nfs-backup volumes: - emptyDir: {} name: nfs-backup security_context: cinder_backup: container: cinder_backup: readOnlyRootFilesystem: false runAsGroup: 42424 runAsUser: 42424 ... ================================================ FILE: values_overrides/cinder/qos.yaml ================================================ # NOTE: In this yaml file, an example qos is created # and associated with volume type rbd1 --- bootstrap: high-iops: consumer: front-end properties: read_iops_sec: 20000 write_iops_sec: 10000 associates: - rbd1 ... ================================================ FILE: values_overrides/cinder/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: cinder: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # cinder: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/cinder/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/cinder/tls.yaml ================================================ --- pod: security_context: cinder_api: container: cinder_api: runAsUser: 0 readOnlyRootFilesystem: false network: api: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" conf: software: apache2: binary: apache2 start_parameters: -DFOREGROUND site_dir: /etc/apache2/sites-enabled conf_dir: /etc/apache2/conf-enabled mods_dir: /etc/apache2/mods-available a2enmod: - ssl a2dismod: null mpm_event: | ServerLimit 1024 StartServers 32 MinSpareThreads 32 MaxSpareThreads 256 ThreadsPerChild 25 MaxRequestsPerChild 128 ThreadLimit 720 wsgi_cinder: | {{- $portInt := tuple "volume" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen {{ $portInt }} Require all granted ServerName {{ printf "%s.%s.svc.%s" "cinder-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} WSGIDaemonProcess cinder-api processes=1 threads=1 user=cinder display-name=%{GROUP} WSGIProcessGroup cinder-api WSGIScriptAlias / /var/lib/openstack/bin/cinder-wsgi WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On AllowEncodedSlashes On SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded SSLEngine on SSLCertificateFile /etc/cinder/certs/tls.crt SSLCertificateKeyFile /etc/cinder/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on cinder: DEFAULT: glance_ca_certificates_file: /etc/cinder/certs/ca.crt keystone_authtoken: cafile: /etc/cinder/certs/ca.crt oslo_messaging_rabbit: ssl: true ssl_ca_file: /etc/rabbitmq/certs/ca.crt ssl_cert_file: /etc/rabbitmq/certs/tls.crt ssl_key_file: /etc/rabbitmq/certs/tls.key endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt cinder: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt scheme: default: https port: api: default: 443 image: scheme: default: https port: api: public: 443 image_registry: scheme: default: https port: api: public: 443 volume: host_fqdn_override: default: tls: secretName: cinder-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https internal: https port: api: public: 443 volumev2: host_fqdn_override: default: tls: secretName: cinder-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https internal: https port: api: public: 443 volumev3: host_fqdn_override: default: tls: secretName: cinder-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https internal: https port: api: public: 443 ingress: port: ingress: default: 443 oslo_messaging: port: https: default: 15680 manifests: certificates: true ... ================================================ FILE: values_overrides/cloudkitty/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy cloudkitty_api: quay.io/airshipit/cloudkitty:2024.2-ubuntu_jammy cloudkitty_db_sync: quay.io/airshipit/cloudkitty:2024.2-ubuntu_jammy cloudkitty_processor: quay.io/airshipit/cloudkitty:2024.2-ubuntu_jammy cloudkitty_storage_init: quay.io/airshipit/cloudkitty:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/cloudkitty/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy cloudkitty_api: quay.io/airshipit/cloudkitty:2025.1-ubuntu_jammy cloudkitty_db_sync: quay.io/airshipit/cloudkitty:2025.1-ubuntu_jammy cloudkitty_processor: quay.io/airshipit/cloudkitty:2025.1-ubuntu_jammy cloudkitty_storage_init: quay.io/airshipit/cloudkitty:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/cloudkitty/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble cloudkitty_api: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble cloudkitty_db_sync: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble cloudkitty_processor: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble cloudkitty_storage_init: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/cloudkitty/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble cloudkitty_api: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble cloudkitty_db_sync: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble cloudkitty_processor: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble cloudkitty_storage_init: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/cloudkitty/gateway.yaml ================================================ # Gateway API overrides for CloudKitty. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: rating: host_fqdn_override: public: host: cloudkitty.openstack-helm.org manifests: ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: cloudkitty-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.rating.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: cloudkitty-api port: 8089 ... ================================================ FILE: values_overrides/cloudkitty/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci cloudkitty_api: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble_loci cloudkitty_db_sync: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble_loci cloudkitty_processor: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble_loci cloudkitty_storage_init: quay.io/airshipit/cloudkitty:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/cloudkitty/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci cloudkitty_api: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble_loci cloudkitty_db_sync: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble_loci cloudkitty_processor: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble_loci cloudkitty_storage_init: quay.io/airshipit/cloudkitty:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/cloudkitty/mariadb-operator.yaml ================================================ --- conf: cloudkitty: database: connection: null manifests: job_db_init: false etcSources: cloudkitty_api: - cloudkitty-db-conn cloudkitty_db_sync: - cloudkitty-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: cloudkitty namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: cloudkitty namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: cloudkitty-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: cloudkitty-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "cloudkitty" table: "*" username: cloudkitty grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: cloudkitty-db-conn spec: mariaDbRef: name: mariadb username: cloudkitty passwordSecretKeyRef: name: cloudkitty-db-password key: password database: cloudkitty secretName: cloudkitty-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/cyborg/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" cyborg_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: cyborg: custom.tld/key: "value" ... ================================================ FILE: values_overrides/cyborg/gateway.yaml ================================================ # Gateway API overrides for Cyborg. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: accelerator: host_fqdn_override: public: host: cyborg.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: cyborg-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.accelerator.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: cyborg-api port: 6666 ... ================================================ FILE: values_overrides/cyborg/mariadb-operator.yaml ================================================ --- conf: cyborg: database: connection: null manifests: job_db_init: false etcSources: cyborg_api: - cyborg-db-conn cyborg_db_sync: - cyborg-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: cyborg namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: cyborg namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: cyborg-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: cyborg-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "cyborg" table: "*" username: cyborg grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: cyborg-db-conn spec: mariaDbRef: name: mariadb username: cyborg passwordSecretKeyRef: name: cyborg-db-password key: password database: cyborg secretName: cyborg-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/cyborg/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: cyborg: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # cyborg: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/designate/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" designate_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: designate: custom.tld/key: "value" tls: dns_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/designate/gateway.yaml ================================================ # Gateway API overrides for Designate. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: dns: host_fqdn_override: public: host: designate.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: designate-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.dns.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: designate-api port: 9001 ... ================================================ FILE: values_overrides/designate/mariadb-operator.yaml ================================================ --- conf: designate: database: connection: null storage:sqlalchemy: connection: null manifests: job_db_init: false etcSources: designate_api: - designate-db-conn designate_db_sync: - designate-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: designate namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: designate namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: designate-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: designate-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "designate" table: "*" username: designate grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: designate-db-conn spec: mariaDbRef: name: mariadb username: designate passwordSecretKeyRef: name: designate-db-password key: password database: designate secretName: designate-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/elastic-apm-server/apparmor.yaml ================================================ --- pod: security_context: elastic_apm_server: container: elastic_apm_server: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/elastic-filebeat/apparmor.yaml ================================================ --- pod: security_context: filebeat: container: filebeat: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/elasticsearch/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: memory_init: quay.io/airshipit/heat:2024.2-ubuntu_jammy helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/elasticsearch/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: memory_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/elasticsearch/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: memory_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/elasticsearch/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: memory_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/elasticsearch/apparmor.yaml ================================================ --- pod: security_context: master: container: elasticsearch_master: appArmorProfile: type: RuntimeDefault elasticsearch_perms: appArmorProfile: type: RuntimeDefault memory_map_increase: appArmorProfile: type: RuntimeDefault data: container: elasticsearch_data: appArmorProfile: type: RuntimeDefault elasticsearch_perms: appArmorProfile: type: RuntimeDefault memory_map_increase: appArmorProfile: type: RuntimeDefault client: container: elasticsearch_client: appArmorProfile: type: RuntimeDefault memory_map_increase: appArmorProfile: type: RuntimeDefault apache_proxy: appArmorProfile: type: RuntimeDefault exporter: container: elasticsearch_exporter: appArmorProfile: type: RuntimeDefault test: container: helm_tests: appArmorProfile: type: RuntimeDefault create_template: container: create_elasticsearch_template: appArmorProfile: type: RuntimeDefault verify_repositories: container: elasticsearch_verify_repositories: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/elasticsearch/gateway.yaml ================================================ # Gateway API overrides for Elasticsearch. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: elasticsearch: host_fqdn_override: public: host: elasticsearch.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: elasticsearch-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.elasticsearch.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: elasticsearch-logging port: 9200 ... ================================================ FILE: values_overrides/elasticsearch/local-storage.yaml ================================================ --- pod: replicas: data: 1 storage: data: requests: storage: 1Gi storage_class: local-storage master: requests: storage: 1Gi storage_class: local-storage manifests: cron_curator: false cron_verify_repositories: false job_snapshot_repository: false job_elasticsearch_templates: false job_s3_user: false job_s3_bucket: false helm_tests: false ... ================================================ FILE: values_overrides/elasticsearch/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: memory_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/elasticsearch/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: memory_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/elasticsearch/remote-cluster.yaml ================================================ # Can't use these settings at startup yet becuse of # https://github.com/elastic/elasticsearch/issues/27006 # conf: # elasticsearch: # config: # cluster: # remote: # remote_elasticsearch: # seeds: # - elasticsearch-gateway-1.remote_host:9301 # - elasticsearch-gateway-2.remote_host:9301 # - elasticsearch-gateway-3.remote_host:9301 # skip_unavailale: true --- network: remote_clustering: enabled: true manifests: cron_curator: false cron_verify_repositories: false job_snapshot_repository: false pod: replicas: master: 2 data: 1 client: 1 gateway: 1 ... ================================================ FILE: values_overrides/elasticsearch/tls.yaml ================================================ --- endpoints: elasticsearch: host_fqdn_override: default: tls: secretName: elasticsearch-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: "https" port: http: default: 443 network: elasticsearch: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: https conf: httpd: | ServerRoot "/usr/local/apache2" Listen 443 LoadModule allowmethods_module modules/mod_allowmethods.so LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule slotmem_shm_module modules/mod_slotmem_shm.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule ssl_module modules/mod_ssl.so User daemon Group daemon AllowOverride none Require all denied Require all denied ErrorLog /dev/stderr LogLevel warn LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout common CustomLog /dev/stdout combined CustomLog /dev/stdout proxy env=forwarded AllowOverride None Options None Require all granted RequestHeader unset Proxy early Include conf/extra/proxy-html.conf ProxyPass http://localhost:{{ tuple "elasticsearch" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ ProxyPassReverse http://localhost:{{ tuple "elasticsearch" "internal" "client" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ AuthName "Elasticsearch" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user # Restrict access to the Elasticsearch Update By Query API Endpoint to prevent modification of indexed documents Require all denied # Restrict access to the Elasticsearch Delete By Query API Endpoint to prevent deletion of indexed documents Require all denied SSLEngine On SSLProxyEngine on SSLCertificateFile /etc/elasticsearch/certs/tls.crt SSLCertificateKeyFile /etc/elasticsearch/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on elasticsearch: config: xpack: security: enabled: true transport: ssl: enabled: true verification_mode: certificate key: /usr/share/elasticsearch/config/tls.key certificate: /usr/share/elasticsearch/config/tls.crt certificate_authorities: ["/usr/share/elasticsearch/config/ca.crt"] curator: config: client: use_ssl: True ssl_no_validate: False certificate: '/etc/elasticsearch/certs/ca.crt' manifests: certificates: true ... ================================================ FILE: values_overrides/fluentd/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/fluentd/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/fluentd/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/fluentd/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/fluentd/apparmor.yaml ================================================ --- pod: security_context: fluentd: container: fluentd: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/fluentd/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/fluentd/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/fluentd/tls.yaml ================================================ --- conf: fluentd: conf: output: | endpoints: elasticsearch: scheme: default: "https" port: http: default: 443 manifests: certificates: true ... ================================================ FILE: values_overrides/freezer/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy freezer_db_sync: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy freezer_api: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/freezer/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble freezer_db_sync: quay.io/airshipit/freezer-api:2025.1-ubuntu_noble freezer_api: quay.io/airshipit/freezer-api:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/freezer/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble freezer_db_sync: quay.io/airshipit/freezer-api:2025.2-ubuntu_noble freezer_api: quay.io/airshipit/freezer-api:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/freezer/gateway.yaml ================================================ # Gateway API overrides for Freezer. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: backup: host_fqdn_override: public: host: freezer.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: freezer-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.backup.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: freezer-api port: 9090 ... ================================================ FILE: values_overrides/freezer/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci freezer_db_sync: quay.io/airshipit/freezer-api:2025.1-ubuntu_noble_loci freezer_api: quay.io/airshipit/freezer-api:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/freezer/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci freezer_db_sync: quay.io/airshipit/freezer-api:2025.2-ubuntu_noble_loci freezer_api: quay.io/airshipit/freezer-api:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/freezer/mariadb-operator.yaml ================================================ --- conf: freezer: database: connection: null manifests: job_db_init: false etcSources: freezer_api: - freezer-db-conn freezer_db_sync: - freezer-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: freezer namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: freezer namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: freezer-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: freezer-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "freezer" table: "*" username: freezer grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: freezer-db-conn spec: mariaDbRef: name: mariadb username: freezer passwordSecretKeyRef: name: freezer-db-password key: password database: freezer secretName: freezer-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/glance/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" glance_db_sync: "quay.io/airshipit/glance:2024.2-ubuntu_jammy" glance_api: "quay.io/airshipit/glance:2024.2-ubuntu_jammy" glance_metadefs_load: "quay.io/airshipit/glance:2024.2-ubuntu_jammy" glance_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/glance/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" glance_db_sync: "quay.io/airshipit/glance:2025.1-ubuntu_jammy" glance_api: "quay.io/airshipit/glance:2025.1-ubuntu_jammy" glance_metadefs_load: "quay.io/airshipit/glance:2025.1-ubuntu_jammy" glance_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/glance/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" glance_db_sync: "quay.io/airshipit/glance:2025.1-ubuntu_noble" glance_api: "quay.io/airshipit/glance:2025.1-ubuntu_noble" glance_metadefs_load: "quay.io/airshipit/glance:2025.1-ubuntu_noble" glance_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/glance/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" glance_db_sync: "quay.io/airshipit/glance:2025.2-ubuntu_noble" glance_api: "quay.io/airshipit/glance:2025.2-ubuntu_noble" glance_metadefs_load: "quay.io/airshipit/glance:2025.2-ubuntu_noble" glance_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/glance/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" glance_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: glance: custom.tld/key: "value" tls: image_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/glance/apparmor.yaml ================================================ --- pod: security_context: glance: container: glance_api: appArmorProfile: type: RuntimeDefault glance_perms: appArmorProfile: type: RuntimeDefault nginx: appArmorProfile: type: RuntimeDefault metadefs_load: container: glance_metadefs_load: appArmorProfile: type: RuntimeDefault storage_init: container: glance_storage_init: appArmorProfile: type: RuntimeDefault test: container: glance_test_ks_user: appArmorProfile: type: RuntimeDefault glance_test: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/glance/bootstrap-ubuntu-image.yaml ================================================ --- bootstrap: structured: images: ubuntu_miniaml: name: "Ubuntu Jammy Minimal" source_url: "https://cloud-images.ubuntu.com/minimal/releases/jammy/release/" image_file: "ubuntu-22.04-minimal-cloudimg-amd64.img" id: null min_disk: 3 image_type: qcow2 container_format: bare ... ================================================ FILE: values_overrides/glance/gateway.yaml ================================================ # Gateway API overrides for Glance. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: image: host_fqdn_override: public: host: glance.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: glance-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.image.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: glance-api port: 9292 ... ================================================ FILE: values_overrides/glance/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" glance_db_sync: "quay.io/airshipit/glance:2025.1-ubuntu_noble_loci" glance_api: "quay.io/airshipit/glance:2025.1-ubuntu_noble_loci" glance_metadefs_load: "quay.io/airshipit/glance:2025.1-ubuntu_noble_loci" glance_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/glance/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" glance_db_sync: "quay.io/airshipit/glance:2025.2-ubuntu_noble_loci" glance_api: "quay.io/airshipit/glance:2025.2-ubuntu_noble_loci" glance_metadefs_load: "quay.io/airshipit/glance:2025.2-ubuntu_noble_loci" glance_storage_init: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/glance/mariadb-operator.yaml ================================================ --- conf: glance: database: connection: null manifests: job_db_init: false etcSources: glance_api: - glance-db-conn glance_db_sync: - glance-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: glance namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: glance namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: glance-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: glance-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "glance" table: "*" username: glance grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: glance-db-conn spec: mariaDbRef: name: mariadb username: glance passwordSecretKeyRef: name: glance-db-password key: password database: glance secretName: glance-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/glance/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: glance: ingress: - from: - podSelector: matchLabels: application: glance - podSelector: matchLabels: application: nova - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: ingress - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: ironic - podSelector: matchLabels: application: cinder ports: - protocol: TCP port: 9292 egress: - to: ports: - protocol: TCP port: 80 - protocol: TCP port: 443 - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/glance/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: glance: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # glance: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/glance/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/glance/tls.yaml ================================================ --- images: tags: nginx: docker.io/nginx:1.18.0 conf: glance: keystone_authtoken: cafile: /etc/glance/certs/ca.crt glance_store: # This option has been removed in 2024.1 https_ca_certificates_file: /etc/glance/certs/ca.crt swift_store_cacert: /etc/glance/certs/ca.crt oslo_messaging_rabbit: ssl: true ssl_ca_file: /etc/rabbitmq/certs/ca.crt ssl_cert_file: /etc/rabbitmq/certs/tls.crt ssl_key_file: /etc/rabbitmq/certs/tls.key glance_api_uwsgi: uwsgi: http-socket: 127.0.0.1:9292 nginx: | worker_processes 1; daemon off; user nginx; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65s; tcp_nodelay on; log_format main '[nginx] method=$request_method path=$request_uri ' 'status=$status upstream_status=$upstream_status duration=$request_time size=$body_bytes_sent ' '"$remote_user" "$http_referer" "$http_user_agent"'; access_log /dev/stdout main; upstream websocket { server 127.0.0.1:$PORT; } server { server_name {{ printf "%s.%s.svc.%s" "${SHORTNAME}" .Release.Namespace .Values.endpoints.cluster_domain_suffix }}; listen $POD_IP:$PORT ssl; client_max_body_size 0; ssl_certificate /etc/nginx/certs/tls.crt; ssl_certificate_key /etc/nginx/certs/tls.key; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; location / { proxy_pass_request_headers on; proxy_http_version 1.1; proxy_pass http://websocket; proxy_read_timeout 90; } } } network: api: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" endpoints: identity: name: keystone auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt glance: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt scheme: default: https port: api: default: 443 image: host_fqdn_override: default: tls: secretName: glance-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https public: https port: api: public: 443 dashboard: scheme: default: https public: https port: web: default: 80 public: 443 oslo_messaging: port: https: default: 15680 pod: security_context: glance: pod: runAsUser: 0 resources: nginx: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" manifests: certificates: true ... ================================================ FILE: values_overrides/gnocchi/gateway.yaml ================================================ # Gateway API overrides for Gnocchi. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: metric: host_fqdn_override: public: host: gnocchi.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: gnocchi-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.metric.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: gnocchi-api port: 8041 ... ================================================ FILE: values_overrides/gnocchi/mariadb-operator.yaml ================================================ --- conf: gnocchi: database: connection: null indexer: url: null manifests: job_db_init: false job_db_init_indexer: false secret_db_indexer: false etcSources: gnocchi_api: - gnocchi-db-conn gnocchi_db_sync: - gnocchi-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: gnocchi namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: gnocchi namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: gnocchi-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: gnocchi-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "gnocchi" table: "*" username: gnocchi grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: gnocchi-db-conn spec: mariaDbRef: name: mariadb username: gnocchi passwordSecretKeyRef: name: gnocchi-db-password key: password database: gnocchi secretName: gnocchi-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/grafana/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/heat:2024.2-ubuntu_jammy grafana_db_session_sync: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/grafana/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy grafana_db_session_sync: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/grafana/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble grafana_db_session_sync: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/grafana/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble grafana_db_session_sync: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/grafana/apparmor.yaml ================================================ --- pod: security_context: dashboard: container: grafana: appArmorProfile: type: RuntimeDefault db_init: container: grafana_db_init_session: appArmorProfile: type: RuntimeDefault grafana_db_init: appArmorProfile: type: RuntimeDefault db_session_sync: container: grafana_db_session_sync: appArmorProfile: type: RuntimeDefault set_admin_user: container: grafana_set_admin_password: appArmorProfile: type: RuntimeDefault run_migrator: container: grafana_run_migrator: appArmorProfile: type: RuntimeDefault prepare_grafana_migrator: appArmorProfile: type: RuntimeDefault test: container: helm_tests: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/grafana/calico.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for a dashboard for # the Calico CNI --- conf: dashboards: network: calico: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "5.0.0" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "Calico cluster monitoring dashboard", "overwrite": true, "editable": false, "gnetId": 3244, "graphTooltip": 0, "id": 38, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "true": 0, "w": 24, "x": 0, "y": 0 }, "id": 15, "panels": [], "repeat": null, "title": "Felix", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 1, "w": 12, "x": 0, "y": 1 }, "id": 1, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_active_local_endpoints", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Active Local Endpoints", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 1, "w": 12, "x": 12, "y": 1 }, "id": 3, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_active_local_policies", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Active Local Policies", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 8, "w": 12, "x": 0, "y": 8 }, "id": 2, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_active_local_selectors", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Active Local Selectors", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 8, "w": 12, "x": 12, "y": 8 }, "id": 4, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_active_local_tags", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Active Local Tags", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 15, "w": 12, "x": 0, "y": 15 }, "id": 5, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_cluster_num_host_endpoints", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Cluster Host Endpoints", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 15, "w": 12, "x": 12, "y": 15 }, "id": 6, "legend": { "alignAsTable": true, "avg": false, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_cluster_num_workload_endpoints", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Cluster Workload Endpoints", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 22, "w": 12, "x": 0, "y": 22 }, "id": 7, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_cluster_num_hosts", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Clusters Hosts", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 22, "w": 12, "x": 12, "y": 22 }, "id": 8, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_ipsets_calico", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Active IP Sets", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 29, "w": 12, "x": 0, "y": 29 }, "id": 9, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_iptables_chains", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Active IP Tables Chains", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 29, "w": 12, "x": 12, "y": 29 }, "id": 10, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_ipset_errors", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "IP Set Command Failures", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 36, "w": 12, "x": 0, "y": 36 }, "id": 11, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_iptables_save_errors", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "IP Tables Save Errors", "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_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 36, "w": 12, "x": 12, "y": 36 }, "id": 12, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_iptables_restore_errors", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "IP Tables Restore Errors", "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_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 43, "w": 12, "x": 0, "y": 43 }, "id": 13, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_resyncs_started", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Felix Resyncing Datastore", "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_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "true": 43, "w": 12, "x": 12, "y": 43 }, "id": 14, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "felix_int_dataplane_failures", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{instance}}", "refId": "A", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Dataplane failed updates", "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 } ] } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [ "calico" ], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Kubernetes Calico", "version": 1 } ... ================================================ FILE: values_overrides/grafana/ceph.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for dashboards for # the overall state of ceph clusters, ceph osds in those clusters, and the # status of ceph pools for those clusters --- conf: dashboards: ceph: ceph_cluster: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "Prometheus.IO", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "3.1.1" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "Ceph Cluster overview.\r\n", "overwrite": true, "editable": false, "gnetId": 917, "graphTooltip": 0, "id": 14, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 35, "panels": [], "title": "New row", "type": "row" }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 4, "x": 0, "y": 1 }, "id": 21, "interval": "1m", "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "ceph_health_status{application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "refId": "A", "step": 60 } ], "thresholds": "1,1", "title": "Status", "type": "singlestat", "valueFontSize": "100%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" }, { "op": "=", "text": "HEALTHY", "value": "0" }, { "op": "=", "text": "WARNING", "value": "1" }, { "op": "=", "text": "CRITICAL", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 4, "x": 4, "y": 1 }, "id": 22, "interval": "1m", "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "count(ceph_pool_max_avail{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "", "title": "Pools", "type": "singlestat", "valueFontSize": "100%", "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_PROMETHEUS}", "editable": true, "error": false, "format": "bytes", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 4, "x": 8, "y": 1 }, "id": 33, "interval": "1m", "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "ceph_cluster_total_bytes{application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "0.025,0.1", "title": "Cluster Capacity", "type": "singlestat", "valueFontSize": "100%", "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_PROMETHEUS}", "editable": true, "error": false, "format": "bytes", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 4, "x": 12, "y": 1 }, "id": 34, "interval": "1m", "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "ceph_cluster_total_used_bytes{application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "0.025,0.1", "title": "Used Capacity", "type": "singlestat", "valueFontSize": "100%", "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_PROMETHEUS}", "editable": true, "error": false, "format": "percentunit", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 4, "x": 16, "y": 1 }, "id": 23, "interval": "1m", "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "ceph_cluster_total_used_bytes/ceph_cluster_total_bytes{application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "70,80", "title": "Current Utilization", "type": "singlestat", "valueFontSize": "100%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, "id": 36, "panels": [], "title": "New row", "type": "row" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 2, "x": 0, "y": 6 }, "id": 26, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(ceph_osd_in{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "", "title": "OSDs IN", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(50, 172, 45, 0.97)", "rgba(237, 40, 40, 0.89)", "rgba(245, 54, 54, 0.9)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 2, "x": 2, "y": 6 }, "id": 27, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(ceph_osd_metadata{application=\"ceph\",release_group=\"$ceph_cluster\"}) - sum(ceph_osd_in{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "1,1", "title": "OSDs OUT", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 2, "x": 4, "y": 6 }, "id": 28, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(ceph_osd_up{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "", "title": "OSDs UP", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(50, 172, 45, 0.97)", "rgba(237, 40, 40, 0.89)", "rgba(245, 54, 54, 0.9)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 2, "x": 6, "y": 6 }, "id": 29, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(ceph_osd_metadata{application=\"ceph\",release_group=\"$ceph_cluster\"}) - sum(ceph_osd_up{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "1,1", "title": "OSDs DOWN", "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_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 8, "y": 6 }, "id": 30, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "avg(ceph_osd_numpg{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "250,300", "title": "Average PGs per OSD", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 9 }, "id": 37, "panels": [], "repeat": null, "title": "CLUSTER", "type": "row" }, { "aliasColors": { "Available": "#EAB839", "Total Capacity": "#447EBC", "Used": "#BF1B00", "total_avail": "#6ED0E0", "total_space": "#7EB26D", "total_used": "#890F02" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 4, "grid": {}, "gridPos": { "h": 8, "w": 8, "x": 0, "y": 10 }, "height": "300", "id": 1, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 0, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "Total Capacity", "fill": 0, "linewidth": 3, "stack": false } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "ceph_cluster_total_bytes{application=\"ceph\",release_group=\"$ceph_cluster\"} - ceph_cluster_total_used_bytes{application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Available", "refId": "A", "step": 60 }, { "expr": "ceph_cluster_total_used_bytes", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Used", "refId": "B", "step": 60 }, { "expr": "ceph_cluster_total_bytes", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Total Capacity", "refId": "C", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Capacity", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "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": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Total Capacity": "#7EB26D", "Used": "#BF1B00", "total_avail": "#6ED0E0", "total_space": "#7EB26D", "total_used": "#890F02" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 8, "w": 8, "x": 8, "y": 10 }, "height": "300", "id": 3, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "sum(ceph_osd_op_w{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Write", "refId": "A", "step": 60 }, { "expr": "sum(ceph_osd_op_r{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Read", "refId": "B", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "IOPS", "tooltip": { "msResolution": true, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "none", "label": "", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 8, "w": 8, "x": 16, "y": 10 }, "height": "300", "id": 7, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "sum(ceph_osd_op_in_bytes{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Write", "refId": "A", "step": 60 }, { "expr": "sum(ceph_osd_op_out_bytes{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Read", "refId": "B", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Throughput", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "Bps", "label": null, "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 18 }, "id": 38, "panels": [], "title": "New row", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 19 }, "id": 18, "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": false, "min": false, "rightSide": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/^Total.*$/", "stack": false } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "ceph_cluster_total_objects{application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Total", "refId": "A", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Objects in the Cluster", "tooltip": { "msResolution": false, "shared": true, "sort": 1, "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 26 }, "id": 19, "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": false, "min": false, "rightSide": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/^Total.*$/", "stack": false } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "sum(ceph_osd_numpg{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Total", "refId": "A", "step": 60 }, { "expr": "sum(ceph_pg_active{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Active", "refId": "B", "step": 60 }, { "expr": "sum(ceph_pg_inconsistent{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Inconsistent", "refId": "C", "step": 60 }, { "expr": "sum(ceph_pg_creating{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Creating", "refId": "D", "step": 60 }, { "expr": "sum(ceph_pg_recovering{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Recovering", "refId": "E", "step": 60 }, { "expr": "sum(ceph_pg_down{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Down", "refId": "F", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "PGs", "tooltip": { "msResolution": false, "shared": true, "sort": 1, "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": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 26 }, "id": 20, "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": false, "min": false, "rightSide": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/^Total.*$/", "stack": false } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "sum(ceph_pg_degraded{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Degraded", "refId": "A", "step": 60 }, { "expr": "sum(ceph_pg_stale{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Stale", "refId": "B", "step": 60 }, { "expr": "sum(ceph_pg_undersized{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Undersized", "refId": "C", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Stuck PGs", "tooltip": { "msResolution": false, "shared": true, "sort": 1, "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": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [ "ceph", "cluster" ], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": null, "current": {}, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Cluster", "multi": false, "name": "ceph_cluster", "options": [], "query": "label_values(ceph_health_status, release_group)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 2, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "auto": true, "auto_count": 10, "auto_min": "1m", "current": { "text": "1m", "value": "1m" }, "datasource": null, "hide": 0, "includeAll": false, "label": "Interval", "multi": false, "name": "interval", "options": [ { "selected": false, "text": "auto", "value": "$__auto_interval_interval" }, { "selected": true, "text": "1m", "value": "1m" }, { "selected": false, "text": "10m", "value": "10m" }, { "selected": false, "text": "30m", "value": "30m" }, { "selected": false, "text": "1h", "value": "1h" }, { "selected": false, "text": "6h", "value": "6h" }, { "selected": false, "text": "12h", "value": "12h" }, { "selected": false, "text": "1d", "value": "1d" }, { "selected": false, "text": "7d", "value": "7d" }, { "selected": false, "text": "14d", "value": "14d" }, { "selected": false, "text": "30d", "value": "30d" } ], "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", "refresh": 2, "skipUrlSync": false, "type": "interval" } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Ceph - Cluster", "version": 1 } ceph_osd: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "Prometheus.IO", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "3.1.1" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "CEPH OSD Status.", "overwrite": true, "editable": true, "gnetId": 923, "graphTooltip": 0, "id": 17, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 11, "panels": [], "title": "New row", "type": "row" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 40, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 2, "x": 0, "y": 1 }, "id": 6, "interval": null, "isNew": true, "links": [], "mappingType": 2, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" }, { "from": "0", "text": "DOWN", "to": "0.99" }, { "from": "0.99", "text": "UP", "to": "1" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "ceph_osd_up{ceph_daemon=\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "refId": "A", "step": 60 } ], "thresholds": "0,1", "timeFrom": null, "title": "Status", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "DOWN", "value": "0" }, { "op": "=", "text": "UP", "value": "1" }, { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 40, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 2, "x": 2, "y": 1 }, "id": 8, "interval": null, "isNew": true, "links": [], "mappingType": 2, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" }, { "from": "0", "text": "OUT", "to": "0.99" }, { "from": "0.99", "text": "IN", "to": "1" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "ceph_osd_in{ceph_daemon=\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "refId": "A", "step": 60 } ], "thresholds": "0,1", "timeFrom": null, "title": "Available", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "DOWN", "value": "0" }, { "op": "=", "text": "UP", "value": "1" }, { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 2, "x": 4, "y": 1 }, "id": 10, "interval": null, "isNew": true, "links": [], "mappingType": 2, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "count(ceph_osd_metadata{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "refId": "A", "step": 60 } ], "thresholds": "0,1", "timeFrom": null, "title": "Total OSDs", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "DOWN", "value": "0" }, { "op": "=", "text": "UP", "value": "1" }, { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 4 }, "id": 12, "panels": [], "title": "OSD: $osd", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 20, "x": 0, "y": 5 }, "id": 5, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/^Average.*/", "fill": 0, "stack": false } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "ceph_osd_numpg{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Number of PGs - {{ $osd }}", "refId": "A", "step": 60 }, { "expr": "avg(ceph_osd_numpg{application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Average Number of PGs in the Cluster", "refId": "B", "step": 60 } ], "thresholds": [ { "colorMode": "custom", "line": true, "lineColor": "rgba(216, 200, 27, 0.27)", "op": "gt", "value": 250 }, { "colorMode": "custom", "line": true, "lineColor": "rgba(234, 112, 112, 0.22)", "op": "gt", "value": 300 } ], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "PGs", "tooltip": { "msResolution": false, "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": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 4, "x": 20, "y": 5 }, "id": 7, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "(ceph_osd_stat_bytes_used{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"}/ceph_osd_stat_bytes{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"})*100", "interval": "$interval", "intervalFactor": 1, "legendFormat": "", "refId": "A", "step": 60 } ], "thresholds": "60,80", "timeFrom": null, "title": "Utilization", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 12 }, "id": 13, "panels": [], "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 13 }, "id": 2, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "ceph_osd_stat_bytes_used{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Used - {{ osd.$osd }}", "metric": "ceph_osd_used_bytes", "refId": "A", "step": 60 }, { "expr": "ceph_osd_stat_bytes{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"} - ceph_osd_stat_bytes_used{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "hide": false, "interval": "$interval", "intervalFactor": 1, "legendFormat": "Available - {{ $osd }}", "metric": "ceph_osd_avail_bytes", "refId": "B", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "OSD Storage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 5, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 13 }, "id": 9, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": false, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 2, "points": true, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "(ceph_osd_stat_bytes_used{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"}/ceph_osd_stat_bytes{ceph_daemon=~\"$osd\",application=\"ceph\",release_group=\"$ceph_cluster\"})", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Available - {{ $osd }}", "metric": "ceph_osd_avail_bytes", "refId": "A", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Utilization Variance", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "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": "none", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "refresh": "15m", "schemaVersion": 18, "style": "dark", "tags": [ "ceph", "osd" ], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": null, "current": { "text": "clcp-ucp-ceph-client", "value": "clcp-ucp-ceph-client" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Cluster", "multi": false, "name": "ceph_cluster", "options": [], "query": "label_values(ceph_health_status, release_group)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 2, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "auto": true, "auto_count": 10, "auto_min": "1m", "current": { "text": "1m", "value": "1m" }, "datasource": null, "hide": 0, "includeAll": false, "label": "Interval", "multi": false, "name": "interval", "options": [ { "selected": false, "text": "auto", "value": "$__auto_interval_interval" }, { "selected": true, "text": "1m", "value": "1m" }, { "selected": false, "text": "10m", "value": "10m" }, { "selected": false, "text": "30m", "value": "30m" }, { "selected": false, "text": "1h", "value": "1h" }, { "selected": false, "text": "6h", "value": "6h" }, { "selected": false, "text": "12h", "value": "12h" }, { "selected": false, "text": "1d", "value": "1d" }, { "selected": false, "text": "7d", "value": "7d" }, { "selected": false, "text": "14d", "value": "14d" }, { "selected": false, "text": "30d", "value": "30d" } ], "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", "refresh": 2, "skipUrlSync": false, "type": "interval" }, { "allValue": null, "current": { "text": "osd.0", "value": "osd.0" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "OSD", "multi": false, "name": "osd", "options": [], "query": "label_values(ceph_osd_metadata{release_group=\"$ceph_cluster\"}, ceph_daemon)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Ceph - OSD", "version": 1 } ceph_pool: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "Prometheus.IO", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "3.1.1" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "Ceph Pools dashboard.", "overwrite": true, "editable": false, "gnetId": 926, "graphTooltip": 0, "id": 2, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 11, "panels": [], "title": "Pool: $pool", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 4, "grid": {}, "gridPos": { "h": 7, "w": 20, "x": 0, "y": 1 }, "height": "", "id": 2, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "rightSide": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 0, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/^Total.*$/", "fill": 0, "linewidth": 4, "stack": false }, { "alias": "/^Raw.*$/", "color": "#BF1B00", "fill": 0, "linewidth": 4 } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "ceph_pool_max_avail{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Total - {{ $pool }}", "refId": "A", "step": 60 }, { "expr": "ceph_pool_stored{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Used - {{ $pool }}", "refId": "B", "step": 60 }, { "expr": "ceph_pool_max_avail{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"} - ceph_pool_stored{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Available - {{ $pool }}", "refId": "C", "step": 60 }, { "expr": "ceph_pool_raw_bytes_used{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Raw - {{ $pool }}", "refId": "D", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "[[pool_name]] Pool Storage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "cacheTimeout": null, "colorBackground": false, "colorValue": true, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "percentunit", "gauge": { "maxValue": 1, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 4, "x": 20, "y": 1 }, "id": 10, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(ceph_pool_stored{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"} / ceph_pool_max_avail{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"})", "format": "time_series", "interval": "$interval", "intervalFactor": 1, "refId": "A", "step": 60 } ], "thresholds": "", "title": "[[pool_name]] Pool Usage", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 8 }, "id": 12, "panels": [], "title": "New row", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 9 }, "height": "", "id": 7, "isNew": true, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "ceph_pool_objects{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Objects - {{ $pool_name }}", "refId": "A", "step": 60 }, { "expr": "ceph_pool_dirty{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Dirty Objects - {{ $pool_name }}", "refId": "B", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Objects in Pool [[pool_name]]", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": null, "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 9 }, "id": 4, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "irate(ceph_pool_rd{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}[3m])", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Read - {{ $pool_name }}", "refId": "B", "step": 60 }, { "expr": "irate(ceph_pool_wr{pool_id=~\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}[3m])", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Write - {{ $pool_name }}", "refId": "A", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "[[pool_name]] Pool IOPS", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "none", "label": "IOPS", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": "IOPS", "logBase": 1, "max": null, "min": 0, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 16 }, "id": 5, "interval": "$interval", "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "irate(ceph_pool_rd_bytes{pool_id=\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}[3m])", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Read Bytes - {{ $pool_name }}", "refId": "A", "step": 60 }, { "expr": "irate(ceph_pool_wr_bytes{pool_id=\"$pool\",application=\"ceph\",release_group=\"$ceph_cluster\"}[3m])", "interval": "$interval", "intervalFactor": 1, "legendFormat": "Written Bytes - {{ $pool_name }}", "refId": "B", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "[[pool_name]] Pool Throughput", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "Bps", "label": null, "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "Bps", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [ "ceph", "pools" ], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": null, "current": { "text": "clcp-ucp-ceph-client", "value": "clcp-ucp-ceph-client" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Cluster", "multi": false, "name": "ceph_cluster", "options": [], "query": "label_values(ceph_health_status, release_group)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 2, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "auto": true, "auto_count": 10, "auto_min": "1m", "current": { "text": "1m", "value": "1m" }, "datasource": null, "hide": 0, "includeAll": false, "label": "Interval", "multi": false, "name": "interval", "options": [ { "selected": false, "text": "auto", "value": "$__auto_interval_interval" }, { "selected": true, "text": "1m", "value": "1m" }, { "selected": false, "text": "10m", "value": "10m" }, { "selected": false, "text": "30m", "value": "30m" }, { "selected": false, "text": "1h", "value": "1h" }, { "selected": false, "text": "6h", "value": "6h" }, { "selected": false, "text": "12h", "value": "12h" }, { "selected": false, "text": "1d", "value": "1d" }, { "selected": false, "text": "7d", "value": "7d" }, { "selected": false, "text": "14d", "value": "14d" }, { "selected": false, "text": "30d", "value": "30d" } ], "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", "refresh": 2, "skipUrlSync": false, "type": "interval" }, { "allValue": null, "current": { "text": "1", "value": "1" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Pool", "multi": false, "name": "pool", "options": [], "query": "label_values(ceph_pool_objects{release_group=\"$ceph_cluster\"}, pool_id)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": null, "current": { "text": "rbd", "value": "rbd" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Pool", "multi": false, "name": "pool_name", "options": [], "query": "label_values(ceph_pool_metadata{release_group=\"$ceph_cluster\",pool_id=\"[[pool]]\" }, name)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Ceph - Pools", "version": 1 } ... ================================================ FILE: values_overrides/grafana/containers.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for a dashboard for # container metrics, specific to each host --- conf: dashboards: kubernetes: containers: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "3.1.1" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.3.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "Monitors Kubernetes cluster using Prometheus. Shows overall cluster CPU / Memory / Filesystem usage as well as individual pod, containers, systemd services statistics. Uses cAdvisor metrics only.", "overwrite": true, "editable": false, "gnetId": 315, "graphTooltip": 0, "id": 32, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 33, "panels": [], "title": "Network I/O pressure", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 5, "w": 24, "x": 0, "y": 1 }, "height": "200px", "id": 32, "isNew": true, "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", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum (rate (container_network_receive_bytes_total{kubernetes_io_hostname=~\"^$Node$\"}[5m]))", "interval": "10s", "intervalFactor": 1, "legendFormat": "Received", "metric": "network", "refId": "A", "step": 10 }, { "expr": "- sum (rate (container_network_transmit_bytes_total{kubernetes_io_hostname=~\"^$Node$\"}[5m]))", "interval": "10s", "intervalFactor": 1, "legendFormat": "Sent", "metric": "network", "refId": "B", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Network I/O pressure", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "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": "Bps", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 6 }, "id": 34, "panels": [], "title": "Total usage", "type": "row" }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 8, "x": 0, "y": 7 }, "height": "180px", "id": 4, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "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", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "thresholds": "65, 90", "title": "Cluster memory 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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 8, "x": 8, "y": 7 }, "height": "180px", "id": 6, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum (rate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) / sum (machine_cpu_cores{kubernetes_io_hostname=~\"^$Node$\"}) * 100", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "thresholds": "65, 90", "title": "Cluster CPU usage (5m avg)", "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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 8, "x": 16, "y": 7 }, "height": "180px", "id": 7, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "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/[sv]da[0-9]$\",id=~\"/.+\",kubernetes_io_hostname=~\"^$Node$\"}) / sum (container_fs_limit_bytes{device=~\"^/dev/[sv]da[0-9]$\",id=~\"/.+\",kubernetes_io_hostname=~\"^$Node$\"}) * 100", "interval": "10s", "intervalFactor": 1, "legendFormat": "", "metric": "", "refId": "A", "step": 10 } ], "thresholds": "65, 90", "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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "bytes", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 0, "y": 12 }, "height": "1px", "id": 9, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "20%", "prefix": "", "prefixFontSize": "20%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "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$\"})", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "bytes", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 4, "y": 12 }, "height": "1px", "id": 10, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "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$\"})", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 8, "y": 12 }, "height": "1px", "id": 11, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": " cores", "postfixFontSize": "30%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum (rate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[5m]))", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 12, "y": 12 }, "height": "1px", "id": 12, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": " cores", "postfixFontSize": "30%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "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$\"})", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "bytes", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 16, "y": 12 }, "height": "1px", "id": 13, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "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/[sv]da[0-9]$\",id=~\"/.+\",kubernetes_io_hostname=~\"^$Node$\"})", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "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_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "format": "bytes", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 20, "y": 12 }, "height": "1px", "id": 14, "interval": null, "isNew": true, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "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/[sv]da[0-9]$\",id=~\"/.+\",kubernetes_io_hostname=~\"^$Node$\"})", "interval": "10s", "intervalFactor": 1, "refId": "A", "step": 10 } ], "thresholds": "", "title": "Total", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 15 }, "id": 35, "panels": [], "title": "Pods CPU usage", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 3, "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 16 }, "height": "", "id": 17, "isNew": true, "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", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": true, "targets": [ { "expr": "sum (rate (container_cpu_usage_seconds_total{image!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (pod)", "interval": "10s", "intervalFactor": 1, "legendFormat": "{{ pod }}", "metric": "container_cpu", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Pods CPU usage (5m avg)", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 23 }, "id": 36, "panels": [ { "aliasColors": {}, "bars": false, "datasource": "${DS_PROMETHEUS}", "decimals": 3, "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 23 }, "height": "", "id": 24, "isNew": true, "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": [], "stack": false, "steppedLine": true, "targets": [ { "expr": "sum (rate (container_cpu_usage_seconds_total{image!=\"\",name=~\"^k8s_.*\",container!=\"POD\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (container, pod)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "pod: {{ pod }} | {{ container }}", "metric": "container_cpu", "refId": "A", "step": 10 }, { "expr": "sum (rate (container_cpu_usage_seconds_total{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (kubernetes_io_hostname, name, image)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})", "metric": "container_cpu", "refId": "B", "step": 10 }, { "expr": "sum (rate (container_cpu_usage_seconds_total{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (kubernetes_io_hostname, rkt_container_name)", "interval": "10s", "intervalFactor": 1, "legendFormat": "rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}", "metric": "container_cpu", "refId": "C", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Containers CPU usage (5m avg)", "tooltip": { "msResolution": true, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "show": true }, "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 } ] } ], "title": "Containers CPU usage", "type": "row" }, { "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 24 }, "id": 37, "panels": [ { "aliasColors": {}, "bars": false, "datasource": "${DS_PROMETHEUS}", "decimals": 3, "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 13, "w": 24, "x": 0, "y": 24 }, "id": 20, "isNew": true, "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": [], "stack": false, "steppedLine": true, "targets": [ { "expr": "sum (rate (container_cpu_usage_seconds_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (id)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "{{ id }}", "metric": "container_cpu", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "All processes CPU usage (5m avg)", "tooltip": { "msResolution": true, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "show": true }, "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, "title": "All processes CPU usage", "type": "row" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 25 }, "id": 38, "panels": [], "title": "Pods memory usage", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 26 }, "id": 25, "isNew": true, "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", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": true, "targets": [ { "expr": "sum (container_memory_working_set_bytes{image!=\"\",kubernetes_io_hostname=~\"^$Node$\"}) by (pod)", "interval": "10s", "intervalFactor": 1, "legendFormat": "{{ pod }}", "metric": "container_memory_usage:sort_desc", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 33 }, "id": 39, "panels": [ { "aliasColors": {}, "bars": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 33 }, "id": 27, "isNew": true, "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": [], "stack": false, "steppedLine": true, "targets": [ { "expr": "sum (container_memory_working_set_bytes{image!=\"\",name=~\"^k8s_.*\",container!=\"POD\",kubernetes_io_hostname=~\"^$Node$\"}) by (container, pod)", "interval": "10s", "intervalFactor": 1, "legendFormat": "pod: {{ pod }} | {{ container }}", "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)", "interval": "10s", "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)", "interval": "10s", "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": { "show": true }, "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 } ] } ], "title": "Containers memory usage", "type": "row" }, { "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 34 }, "id": 40, "panels": [ { "aliasColors": {}, "bars": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 13, "w": 24, "x": 0, "y": 34 }, "id": 28, "isNew": true, "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": [], "stack": false, "steppedLine": true, "targets": [ { "expr": "sum (container_memory_working_set_bytes{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) by (id)", "interval": "10s", "intervalFactor": 1, "legendFormat": "{{ id }}", "metric": "container_memory_usage:sort_desc", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "All processes memory usage", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "show": true }, "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 } ] } ], "title": "All processes memory usage", "type": "row" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 35 }, "id": 41, "panels": [], "title": "Pods network I/O", "type": "row" }, { "aliasColors": {}, "bars": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 36 }, "id": 16, "isNew": true, "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", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "stack": false, "steppedLine": false, "targets": [ { "expr": "sum (rate (container_network_receive_bytes_total{image!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (pod)", "interval": "10s", "intervalFactor": 1, "legendFormat": "-> {{ pod }}", "metric": "network", "refId": "A", "step": 10 }, { "expr": "- sum (rate (container_network_transmit_bytes_total{image!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (pod)", "interval": "10s", "intervalFactor": 1, "legendFormat": "<- {{ pod }}", "metric": "network", "refId": "B", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Pods network I/O (5m avg)", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "show": true }, "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 } ] }, { "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 43 }, "id": 42, "panels": [ { "aliasColors": {}, "bars": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 43 }, "id": 30, "isNew": true, "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": [], "stack": false, "steppedLine": false, "targets": [ { "expr": "sum (rate (container_network_receive_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (container, pod)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "-> pod: {{ pod }} | {{ container }}", "metric": "network", "refId": "B", "step": 10 }, { "expr": "- sum (rate (container_network_transmit_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (container, pod)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "<- pod: {{ pod }} | {{ container }}", "metric": "network", "refId": "D", "step": 10 }, { "expr": "sum (rate (container_network_receive_bytes_total{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (kubernetes_io_hostname, name, image)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "-> docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})", "metric": "network", "refId": "A", "step": 10 }, { "expr": "- sum (rate (container_network_transmit_bytes_total{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (kubernetes_io_hostname, name, image)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "<- docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})", "metric": "network", "refId": "C", "step": 10 }, { "expr": "sum (rate (container_network_transmit_bytes_total{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (kubernetes_io_hostname, rkt_container_name)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "-> rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}", "metric": "network", "refId": "E", "step": 10 }, { "expr": "- sum (rate (container_network_transmit_bytes_total{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (kubernetes_io_hostname, rkt_container_name)", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "<- rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}", "metric": "network", "refId": "F", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Containers network I/O (5m avg)", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "show": true }, "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 } ] } ], "title": "Containers network I/O", "type": "row" }, { "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 44 }, "id": 43, "panels": [ { "aliasColors": {}, "bars": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 13, "w": 24, "x": 0, "y": 44 }, "id": 29, "isNew": true, "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": [], "stack": false, "steppedLine": false, "targets": [ { "expr": "sum (rate (container_network_receive_bytes_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (id)", "interval": "10s", "intervalFactor": 1, "legendFormat": "-> {{ id }}", "metric": "network", "refId": "A", "step": 10 }, { "expr": "- sum (rate (container_network_transmit_bytes_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[5m])) by (id)", "interval": "10s", "intervalFactor": 1, "legendFormat": "<- {{ id }}", "metric": "network", "refId": "B", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "All processes network I/O (5m avg)", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "show": true }, "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 } ] } ], "title": "All processes network I/O", "type": "row" } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [ "kubernetes" ], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": ".*", "current": { "text": "All", "value": "$__all" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": true, "label": null, "multi": false, "name": "Node", "options": [], "query": "label_values(kubernetes_io_hostname)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-5m", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Container Metrics (cAdvisor)", "version": 1 } ... ================================================ FILE: values_overrides/grafana/coredns.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for a dashboard for # CoreDNS --- conf: dashboards: kubernetes: coredns: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.4.3" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "A dashboard for the CoreDNS DNS server.", "overwrite": true, "editable": true, "gnetId": 5926, "graphTooltip": 0, "id": 20, "links": [], "panels": [ { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 0 }, "id": 1, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "total", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(coredns_dns_request_count_total{instance=~\"$instance\"}[5m])) by (proto)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{proto}}", "refId": "A", "step": 60 }, { "expr": "sum(rate(coredns_dns_request_count_total{instance=~\"$instance\"}[5m]))", "format": "time_series", "intervalFactor": 2, "legendFormat": "total", "refId": "B", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Requests (total)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 8, "x": 8, "y": 0 }, "id": 12, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "total", "yaxis": 2 }, { "alias": "other", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(coredns_dns_request_type_count_total{instance=~\"$instance\"}[5m])) by (type)", "intervalFactor": 2, "legendFormat": "{{type}}", "refId": "A", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Requests (by qtype)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 8, "x": 16, "y": 0 }, "id": 2, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "total", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(coredns_dns_request_count_total{instance=~\"$instance\"}[5m])) by (zone)", "intervalFactor": 2, "legendFormat": "{{zone}}", "refId": "A", "step": 60 }, { "expr": "sum(rate(coredns_dns_request_count_total{instance=~\"$instance\"}[5m]))", "intervalFactor": 2, "legendFormat": "total", "refId": "B", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Requests (by zone)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 7 }, "id": 10, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "total", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(coredns_dns_request_do_count_total{instance=~\"$instance\"}[5m]))", "intervalFactor": 2, "legendFormat": "DO", "refId": "A", "step": 40 }, { "expr": "sum(rate(coredns_dns_request_count_total{instance=~\"$instance\"}[5m]))", "intervalFactor": 2, "legendFormat": "total", "refId": "B", "step": 40 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Requests (DO bit)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "pps", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 6, "x": 12, "y": 7 }, "id": 9, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "tcp:90", "yaxis": 2 }, { "alias": "tcp:99 ", "yaxis": 2 }, { "alias": "tcp:50", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_size_bytes_bucket{instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", "intervalFactor": 2, "legendFormat": "{{proto}}:99 ", "refId": "A", "step": 60 }, { "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_size_bytes_bucket{instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", "intervalFactor": 2, "legendFormat": "{{proto}}:90", "refId": "B", "step": 60 }, { "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_size_bytes_bucket{instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto))", "intervalFactor": 2, "legendFormat": "{{proto}}:50", "refId": "C", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Requests (size, udp)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 7 }, "id": 14, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "tcp:90", "yaxis": 1 }, { "alias": "tcp:99 ", "yaxis": 1 }, { "alias": "tcp:50", "yaxis": 1 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_size_bytes_bucket{instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", "intervalFactor": 2, "legendFormat": "{{proto}}:99 ", "refId": "A", "step": 60 }, { "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_size_bytes_bucket{instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", "intervalFactor": 2, "legendFormat": "{{proto}}:90", "refId": "B", "step": 60 }, { "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_size_bytes_bucket{instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto))", "intervalFactor": 2, "legendFormat": "{{proto}}:50", "refId": "C", "step": 60 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Requests (size,tcp)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 14 }, "id": 5, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(coredns_dns_response_rcode_count_total{instance=~\"$instance\"}[5m])) by (rcode)", "intervalFactor": 2, "legendFormat": "{{rcode}}", "refId": "A", "step": 40 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Responses (by rcode)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 14 }, "id": 3, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_request_duration_seconds_bucket{instance=~\"$instance\"}[5m])) by (le, job))", "intervalFactor": 2, "legendFormat": "99%", "refId": "A", "step": 40 }, { "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_request_duration_seconds_bucket{instance=~\"$instance\"}[5m])) by (le))", "intervalFactor": 2, "legendFormat": "90%", "refId": "B", "step": 40 }, { "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_request_duration_seconds_bucket{instance=~\"$instance\"}[5m])) by (le))", "intervalFactor": 2, "legendFormat": "50%", "refId": "C", "step": 40 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Responses (duration)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "s", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 21 }, "id": 8, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "udp:50%", "yaxis": 1 }, { "alias": "tcp:50%", "yaxis": 2 }, { "alias": "tcp:90%", "yaxis": 2 }, { "alias": "tcp:99%", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_response_size_bytes_bucket{instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", "intervalFactor": 2, "legendFormat": "{{proto}}:99%", "refId": "A", "step": 40 }, { "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_response_size_bytes_bucket{instance=\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", "intervalFactor": 2, "legendFormat": "{{proto}}:90%", "refId": "B", "step": 40 }, { "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_response_size_bytes_bucket{instance=~\"$instance\",proto=\"udp\"}[5m])) by (le,proto)) ", "intervalFactor": 2, "legendFormat": "{{proto}}:50%", "metric": "", "refId": "C", "step": 40 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Responses (size, udp)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 21 }, "id": 13, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "udp:50%", "yaxis": 1 }, { "alias": "tcp:50%", "yaxis": 1 }, { "alias": "tcp:90%", "yaxis": 1 }, { "alias": "tcp:99%", "yaxis": 1 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "histogram_quantile(0.99, sum(rate(coredns_dns_response_size_bytes_bucket{instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto)) ", "intervalFactor": 2, "legendFormat": "{{proto}}:99%", "refId": "A", "step": 40 }, { "expr": "histogram_quantile(0.90, sum(rate(coredns_dns_response_size_bytes_bucket{instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le,proto)) ", "intervalFactor": 2, "legendFormat": "{{proto}}:90%", "refId": "B", "step": 40 }, { "expr": "histogram_quantile(0.50, sum(rate(coredns_dns_response_size_bytes_bucket{instance=~\"$instance\",proto=\"tcp\"}[5m])) by (le, proto)) ", "intervalFactor": 2, "legendFormat": "{{proto}}:50%", "metric": "", "refId": "C", "step": 40 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Responses (size, tcp)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 28 }, "id": 15, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(coredns_cache_size{instance=~\"$instance\"}) by (type)", "intervalFactor": 2, "legendFormat": "{{type}}", "refId": "A", "step": 40 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Cache (size)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 28 }, "id": 16, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "misses", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(coredns_cache_hits_total{instance=~\"$instance\"}[5m])) by (type)", "intervalFactor": 2, "legendFormat": "hits:{{type}}", "refId": "A", "step": 40 }, { "expr": "sum(rate(coredns_cache_misses_total{instance=~\"$instance\"}[5m])) by (type)", "intervalFactor": 2, "legendFormat": "misses", "refId": "B", "step": 40 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Cache (hitrate)", "tooltip": { "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "pps", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "schemaVersion": 18, "style": "dark", "tags": [ "dns", "coredns" ], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": ".*", "current": { "text": "All", "value": "$__all" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": true, "label": "Instance", "multi": false, "name": "instance", "options": [], "query": "up{job=\"coredns\"}", "refresh": 1, "regex": ".*instance=\"(.*?)\".*", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "now": true, "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "CoreDNS", "version": 1 } ... ================================================ FILE: values_overrides/grafana/elasticsearch.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for a dashboard for # an Elasticsearch cluster --- conf: dashboards: lma: elasticsearch: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.6.3" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "Elasticsearch detailed dashboard", "overwrite": true, "editable": true, "gnetId": 4358, "graphTooltip": 1, "id": 23, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 50, "panels": [], "repeat": null, "title": "Cluster", "type": "row" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(178, 49, 13, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 10, "x": 0, "y": 1 }, "height": "50", "id": 8, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "(sum(elasticsearch_cluster_health_status{cluster=~\"$cluster\",color=\"green\"})*2)+sum(elasticsearch_cluster_health_status{cluster=~\"$cluster\",color=\"yellow\"})", "format": "time_series", "intervalFactor": 3, "legendFormat": "", "metric": "", "refId": "A", "step": 40 } ], "thresholds": "0,1,2", "title": "Cluster health status", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "GREEN", "value": "2" }, { "op": "=", "text": "YELLOW", "value": "1" }, { "op": "=", "text": "RED", "value": "0" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 10, "y": 1 }, "height": "50", "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(elasticsearch_cluster_health_number_of_nodes{cluster=~\"$cluster\"})", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "", "metric": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "Nodes", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 14, "y": 1 }, "height": "50", "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "elasticsearch_cluster_health_number_of_data_nodes{cluster=\"$cluster\"}", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "", "metric": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "Data nodes", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 6, "x": 18, "y": 1 }, "height": "50", "hideTimeOverride": true, "id": 16, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "elasticsearch_cluster_health_number_of_pending_tasks{cluster=\"$cluster\"}", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "", "metric": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "Pending tasks", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 4 }, "id": 51, "panels": [], "repeat": null, "title": "Shards", "type": "row" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 0, "y": 5 }, "height": "50", "id": 11, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "maxPerRow": 6, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "repeat": "shard_type", "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "elasticsearch_cluster_health_active_primary_shards{cluster=\"$cluster\"}", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "active primary shards", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 4, "y": 5 }, "height": "50", "id": 39, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "maxPerRow": 6, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "elasticsearch_cluster_health_active_shards{cluster=\"$cluster\"}", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "active shards", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 8, "y": 5 }, "height": "50", "id": 40, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "maxPerRow": 6, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "elasticsearch_cluster_health_initializing_shards{cluster=\"$cluster\"}", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "initializing shards", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 12, "y": 5 }, "height": "50", "id": 41, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "maxPerRow": 6, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "elasticsearch_cluster_health_relocating_shards{cluster=\"$cluster\"}", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "relocating shards", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 4, "x": 16, "y": 5 }, "height": "50", "id": 42, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "maxPerRow": 6, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "elasticsearch_cluster_health_unassigned_shards{cluster=\"$cluster\"}", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 40 } ], "thresholds": "", "title": "unassigned shards", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 8 }, "id": 52, "panels": [], "repeat": null, "title": "System", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 0, "y": 9 }, "height": "400", "id": 30, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "elasticsearch_process_cpu_percent{cluster=\"$cluster\",es_master_node=\"true\",name=~\"$node\"}", "format": "time_series", "instant": false, "interval": "", "intervalFactor": 2, "legendFormat": "{{ name }} - master", "metric": "", "refId": "A", "step": 10 }, { "expr": "elasticsearch_process_cpu_percent{cluster=\"$cluster\",es_data_node=\"true\",name=~\"$node\"}", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{ name }} - data", "metric": "", "refId": "B", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "CPU usage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "percent", "label": "CPU usage", "logBase": 1, "max": 100, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 6, "y": 9 }, "height": "400", "id": 31, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "elasticsearch_jvm_memory_used_bytes{cluster=\"$cluster\",name=~\"$node\",name=~\"$node\"}", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{ name }} - used: {{area}}", "metric": "", "refId": "A", "step": 10 }, { "expr": "elasticsearch_jvm_memory_committed_bytes{cluster=\"$cluster\",name=~\"$node\",name=~\"$node\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - committed: {{area}}", "refId": "B", "step": 10 }, { "expr": "elasticsearch_jvm_memory_max_bytes{cluster=\"$cluster\",name=~\"$node\",name=~\"$node\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - max: {{area}}", "refId": "C", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "JVM memory usage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": "Memory", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 12, "y": 9 }, "height": "400", "id": 32, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "1-(elasticsearch_filesystem_data_available_bytes{cluster=\"$cluster\"}/elasticsearch_filesystem_data_size_bytes{cluster=\"$cluster\",name=~\"$node\"})", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{ name }} - {{path}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [ { "colorMode": "custom", "fill": true, "fillColor": "rgba(216, 200, 27, 0.27)", "op": "gt", "value": 0.8 }, { "colorMode": "custom", "fill": true, "fillColor": "rgba(234, 112, 112, 0.22)", "op": "gt", "value": 0.9 } ], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Disk usage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "percentunit", "label": "Disk Usage %", "logBase": 1, "max": 1, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 18, "y": 9 }, "height": "400", "id": 47, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "sort": "max", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "sent", "transform": "negative-Y" } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "irate(elasticsearch_transport_tx_size_bytes_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} -sent", "refId": "D", "step": 10 }, { "expr": "irate(elasticsearch_transport_rx_size_bytes_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} -received", "refId": "C", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Network usage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "Bps", "label": "Bytes/sec", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "pps", "label": "", "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 19 }, "id": 53, "panels": [], "repeat": null, "title": "Documents", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 0, "y": 20 }, "height": "400", "id": 1, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "elasticsearch_indices_docs{cluster=\"$cluster\",name=~\"$node\"}", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{ name }}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Documents count", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "Documents", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 6, "y": 20 }, "height": "400", "id": 24, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "irate(elasticsearch_indices_indexing_index_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Documents indexed rate", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "index calls/s", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 12, "y": 20 }, "height": "400", "id": 25, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_indices_docs_deleted{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Documents deleted rate", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "Documents/s", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 18, "y": 20 }, "height": "400", "id": 26, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_indices_merges_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Documents merged rate", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "Documents/s", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 30 }, "id": 54, "panels": [], "repeat": null, "title": "Total Operations stats", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 12, "x": 0, "y": 31 }, "height": "400", "id": 48, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "sort": "avg", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "irate(elasticsearch_indices_indexing_index_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{ name }} - indexing", "metric": "", "refId": "A", "step": 4 }, { "expr": "irate(elasticsearch_indices_search_query_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - query", "refId": "B", "step": 4 }, { "expr": "irate(elasticsearch_indices_search_fetch_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - fetch", "refId": "C", "step": 4 }, { "expr": "irate(elasticsearch_indices_merges_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - merges", "refId": "D", "step": 4 }, { "expr": "irate(elasticsearch_indices_refresh_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - refresh", "refId": "E", "step": 4 }, { "expr": "irate(elasticsearch_indices_flush_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - flush", "refId": "F", "step": 4 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Total Operations rate", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "Operations/s", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 12, "x": 12, "y": 31 }, "height": "400", "id": 49, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "sort": "avg", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "irate(elasticsearch_indices_indexing_index_time_seconds_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{ name }} - indexing", "metric": "", "refId": "A", "step": 4 }, { "expr": "irate(elasticsearch_indices_search_query_time_ms_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - query", "refId": "B", "step": 4 }, { "expr": "irate(elasticsearch_indices_search_fetch_time_ms_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - fetch", "refId": "C", "step": 4 }, { "expr": "irate(elasticsearch_indices_merges_total_time_ms_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - merges", "refId": "D", "step": 4 }, { "expr": "irate(elasticsearch_indices_refresh_total_time_ms_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - refresh", "refId": "E", "step": 4 }, { "expr": "irate(elasticsearch_indices_flush_time_ms_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ name }} - flush", "refId": "F", "step": 4 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Total Operations time", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "ms", "label": "Time", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 41 }, "id": 55, "panels": [], "repeat": null, "title": "Times", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 8, "x": 0, "y": 42 }, "height": "400", "id": 33, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_indices_search_query_time_seconds{cluster=\"$cluster\",name=~\"$node\"}[$interval]) ", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 4 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Query time", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "ms", "label": "Time", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 8, "x": 8, "y": 42 }, "height": "400", "id": 5, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_indices_indexing_index_time_seconds_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 4 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Indexing time", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "ms", "label": "Time", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 8, "x": 16, "y": 42 }, "height": "400", "id": 3, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_indices_merges_total_time_seconds_total{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 4 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Merging time", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "s", "label": "Time", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 52 }, "id": 56, "panels": [], "repeat": null, "title": "Caches", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 0, "y": 53 }, "height": "400", "id": 4, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "elasticsearch_indices_fielddata_memory_size_bytes{cluster=\"$cluster\",name=~\"$node\"}", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Field data memory size", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": "Memory", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 6, "y": 53 }, "height": "400", "id": 34, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_indices_fielddata_evictions{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Field data evictions", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "Evictions/s", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 12, "y": 53 }, "height": "400", "id": 35, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "elasticsearch_indices_query_cache_memory_size_bytes{cluster=\"$cluster\",name=~\"$node\"}", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Query cache size", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": "Size", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 6, "x": 18, "y": 53 }, "height": "400", "id": 36, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_indices_query_cache_evictions{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}}", "metric": "", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Query cache evictions", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "Evictions/s", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 63 }, "id": 57, "panels": [], "repeat": null, "title": "Thread Pool", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 19, "w": 6, "x": 0, "y": 64 }, "id": 45, "legend": { "alignAsTable": true, "avg": true, "current": false, "max": true, "min": true, "show": true, "sort": "avg", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": " irate(elasticsearch_thread_pool_rejected_count{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{name}} - {{ type }}", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Thread Pool operations rejected", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 19, "w": 6, "x": 6, "y": 64 }, "id": 46, "legend": { "alignAsTable": true, "avg": true, "current": false, "max": true, "min": true, "show": true, "sort": "avg", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "elasticsearch_thread_pool_active_count{cluster=\"$cluster\",name=~\"$node\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{name}} - {{ type }}", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Thread Pool operations queued", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 19, "w": 6, "x": 12, "y": 64 }, "height": "", "id": 43, "legend": { "alignAsTable": true, "avg": true, "current": false, "max": true, "min": true, "show": true, "sort": "avg", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "elasticsearch_thread_pool_active_count{cluster=\"$cluster\",name=~\"$node\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{name}} - {{ type }}", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Thread Pool threads active", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 19, "w": 6, "x": 18, "y": 64 }, "id": 44, "legend": { "alignAsTable": true, "avg": true, "current": false, "max": true, "min": true, "show": true, "sort": "avg", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "irate(elasticsearch_thread_pool_completed_count{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{name}} - {{ type }}", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Thread Pool operations completed", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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 } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 83 }, "id": 58, "panels": [], "repeat": null, "title": "JVM Garbage Collection", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 12, "x": 0, "y": 84 }, "height": "400", "id": 7, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_jvm_gc_collection_seconds_count{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}} - {{gc}}", "metric": "", "refId": "A", "step": 4 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "GC count", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "GCs", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 10, "w": 12, "x": 12, "y": 84 }, "height": "400", "id": 27, "legend": { "alignAsTable": true, "avg": true, "current": true, "hideEmpty": false, "hideZero": false, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(elasticsearch_jvm_gc_collection_seconds_count{cluster=\"$cluster\",name=~\"$node\"}[$interval])", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "{{name}} - {{gc}}", "metric": "", "refId": "A", "step": 4 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "GC time", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "s", "label": "Time", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ] } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [ "elasticsearch", "App" ], "templating": { "list": [ { "auto": true, "auto_count": 30, "auto_min": "10s", "current": { "text": "auto", "value": "$__auto_interval_interval" }, "hide": 0, "label": "Interval", "name": "interval", "options": [ { "selected": true, "text": "auto", "value": "$__auto_interval_interval" }, { "selected": false, "text": "1m", "value": "1m" }, { "selected": false, "text": "10m", "value": "10m" }, { "selected": false, "text": "30m", "value": "30m" }, { "selected": false, "text": "1h", "value": "1h" }, { "selected": false, "text": "6h", "value": "6h" }, { "selected": false, "text": "12h", "value": "12h" }, { "selected": false, "text": "1d", "value": "1d" }, { "selected": false, "text": "7d", "value": "7d" }, { "selected": false, "text": "14d", "value": "14d" }, { "selected": false, "text": "30d", "value": "30d" } ], "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", "refresh": 2, "skipUrlSync": false, "type": "interval" }, { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": null, "current": {}, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Instance", "multi": false, "name": "cluster", "options": [], "query": "label_values(elasticsearch_cluster_health_status,cluster)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 1, "tagValuesQuery": null, "tags": [], "tagsQuery": null, "type": "query", "useTags": false }, { "allValue": null, "current": { "text": "All", "value": "$__all" }, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": true, "label": "node", "multi": true, "name": "node", "options": [], "query": "label_values(elasticsearch_process_cpu_percent,name)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 1, "tagValuesQuery": null, "tags": [], "tagsQuery": null, "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Elasticsearch", "version": 1 } ... ================================================ FILE: values_overrides/grafana/gateway.yaml ================================================ # Gateway API overrides for Grafana. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: grafana: host_fqdn_override: public: host: grafana.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: grafana-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.grafana.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: grafana-dashboard port: 3000 ... ================================================ FILE: values_overrides/grafana/home_dashboard.yaml ================================================ # This override file provides a reference for dashboards for # customized OSH Welcome Page --- conf: dashboards: home: home_dashboard: |- { "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": true, "gnetId": null, "graphTooltip": 0, "id": 66, "links": [], "panels": [ { "content": "
\n OSH Home Dashboard\n
", "editable": true, "gridPos": { "h": 3, "w": 24, "x": 0, "y": 0 }, "id": 1, "links": [], "mode": "html", "options": {}, "style": {}, "title": "", "transparent": true, "type": "text" }, { "folderId": 0, "gridPos": { "h": 10, "w": 13, "x": 6, "y": 3 }, "headings": true, "id": 3, "limit": 30, "links": [], "options": {}, "query": "", "recent": true, "search": false, "starred": true, "tags": [], "title": "", "type": "dashlist" } ], "schemaVersion": 18, "style": "dark", "tags": [], "templating": { "list": [] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "hidden": true, "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ], "type": "timepicker" }, "timezone": "browser", "title": "OSH Home", "version": 1 } ... ================================================ FILE: values_overrides/grafana/kubernetes.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for dashboards that # reflect the overall state of a Kubernetes deployment --- conf: dashboards: kubernetes: kubernetes_capacity_planning: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.4.1" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "", "overwrite": true, "editable": false, "gnetId": 22, "graphTooltip": 0, "id": 35, "links": [], "panels": [ { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 0 }, "id": 3, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(node_cpu{mode=\"idle\"}[2m])) * 100", "hide": false, "intervalFactor": 10, "legendFormat": "", "refId": "A", "step": 50 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Idle cpu", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "percent", "label": "cpu usage", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 0 }, "id": 9, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(node_load1)", "intervalFactor": 4, "legendFormat": "load 1m", "refId": "A", "step": 20, "target": "" }, { "expr": "sum(node_load5)", "intervalFactor": 4, "legendFormat": "load 5m", "refId": "B", "step": 20, "target": "" }, { "expr": "sum(node_load15)", "intervalFactor": 4, "legendFormat": "load 15m", "refId": "C", "step": 20, "target": "" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "System load", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "percentunit", "label": null, "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 18, "x": 0, "y": 7 }, "id": 4, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "node_memory_SwapFree{instance=\"172.17.0.1:9100\",job=\"prometheus\"}", "yaxis": 2 } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "sum(node_memory_MemTotal) - sum(node_memory_MemFree) - sum(node_memory_Buffers) - sum(node_memory_Cached)", "intervalFactor": 2, "legendFormat": "memory usage", "metric": "memo", "refId": "A", "step": 10, "target": "" }, { "expr": "sum(node_memory_Buffers)", "interval": "", "intervalFactor": 2, "legendFormat": "memory buffers", "metric": "memo", "refId": "B", "step": 10, "target": "" }, { "expr": "sum(node_memory_Cached)", "interval": "", "intervalFactor": 2, "legendFormat": "memory cached", "metric": "memo", "refId": "C", "step": 10, "target": "" }, { "expr": "sum(node_memory_MemFree)", "interval": "", "intervalFactor": 2, "legendFormat": "memory free", "metric": "memo", "refId": "D", "step": 10, "target": "" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Memory usage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 7 }, "id": 5, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "((sum(node_memory_MemTotal) - sum(node_memory_MemFree) - sum(node_memory_Buffers) - sum(node_memory_Cached)) / sum(node_memory_MemTotal)) * 100", "intervalFactor": 2, "metric": "", "refId": "A", "step": 60, "target": "" } ], "thresholds": "80, 90", "title": "Memory usage", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 18, "x": 0, "y": 14 }, "id": 6, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "read", "yaxis": 1 }, { "alias": "{instance=\"172.17.0.1:9100\"}", "yaxis": 2 }, { "alias": "io time", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(node_disk_bytes_read[5m]))", "hide": false, "intervalFactor": 4, "legendFormat": "read", "refId": "A", "step": 20, "target": "" }, { "expr": "sum(rate(node_disk_bytes_written[5m]))", "intervalFactor": 4, "legendFormat": "written", "refId": "B", "step": 20 }, { "expr": "sum(rate(node_disk_io_time_ms[5m]))", "intervalFactor": 4, "legendFormat": "io time", "refId": "C", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Disk I/O", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "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": "ms", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "percentunit", "gauge": { "maxValue": 1, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 14 }, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(sum(node_filesystem_size{device!=\"rootfs\"}) - sum(node_filesystem_free{device!=\"rootfs\"})) / sum(node_filesystem_size{device!=\"rootfs\"})", "intervalFactor": 2, "refId": "A", "step": 60, "target": "" } ], "thresholds": "0.75, 0.9", "title": "Disk space usage", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 21 }, "id": 8, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "transmitted ", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(node_network_receive_bytes{device!~\"lo\"}[5m]))", "hide": false, "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 10, "target": "" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Network received", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "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": "bytes", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 21 }, "id": 10, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "transmitted ", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(node_network_transmit_bytes{device!~\"lo\"}[5m]))", "hide": false, "intervalFactor": 2, "legendFormat": "", "refId": "B", "step": 10, "target": "" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Network transmitted", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "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": "bytes", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 18, "x": 0, "y": 28 }, "id": 11, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(kube_pod_info)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Current number of Pods", "refId": "A", "step": 10 }, { "expr": "sum(kube_node_status_capacity_pods)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Maximum capacity of pods", "refId": "B", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Cluster Pod Utilization", "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 28 }, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "100 - (sum(kube_node_status_capacity_pods) - sum(kube_pod_info)) / sum(kube_node_status_capacity_pods) * 100", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 60, "target": "" } ], "thresholds": "80,90", "title": "Pod Utilization", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" } ], "refresh": false, "schemaVersion": 18, "style": "dark", "tags": [], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Kubernetes Capacity Planning", "version": 1 } kubernetes_cluster_status: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.4.1" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": false, "overwrite": true, "gnetId": null, "graphTooltip": 0, "id": 5, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 11, "panels": [], "repeat": null, "title": "Cluster Health", "type": "row" }, { "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_PROMETHEUS}", "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 12, "x": 0, "y": 1 }, "id": 5, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(up{job=~\"apiserver|kube-scheduler|kube-controller-manager\"} == 0)", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "1,3", "title": "Control Plane UP", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "UP", "value": "null" } ], "valueName": "total" }, { "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_PROMETHEUS}", "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 12, "x": 12, "y": 1 }, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(ALERTS{alertstate=\"firing\",alertname!=\"DeadMansSwitch\"})", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "3,5", "title": "Alerts Firing", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "0", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, "id": 12, "panels": [], "repeat": null, "title": "Control Plane Status", "type": "row" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "decimals": null, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 6, "x": 0, "y": 6 }, "id": 1, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(sum(up{job=\"apiserver\"} == 1) / count(up{job=\"apiserver\"})) * 100", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "50,80", "title": "API Servers UP", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "decimals": null, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 6, "x": 6, "y": 6 }, "id": 2, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(sum(up{job=\"kube-controller-manager-discovery\"} == 1) / count(up{job=\"kube-controller-manager-discovery\"})) * 100", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "50,80", "title": "Controller Managers UP", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "decimals": null, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 6, "x": 12, "y": 6 }, "id": 3, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(sum(up{job=\"kube-scheduler-discovery\"} == 1) / count(up{job=\"kube-scheduler-discovery\"})) * 100", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "50,80", "title": "Schedulers UP", "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_PROMETHEUS}", "decimals": null, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 6, "x": 18, "y": 6 }, "hideTimeOverride": false, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "count(increase(kube_pod_container_status_restarts{namespace=~\"kube-system|tectonic-system\"}[1h]) > 5)", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "1,3", "title": "Crashlooping Control Plane Pods", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "0", "value": "null" } ], "valueName": "current" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 11 }, "id": 13, "panels": [], "repeat": null, "title": "Capacity Planing", "type": "row" }, { "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_PROMETHEUS}", "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 6, "x": 0, "y": 12 }, "id": 8, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "sum(100 - (avg by (instance) (rate(node_cpu{job=\"node-exporter\",mode=\"idle\"}[5m])) * 100)) / count(node_cpu{job=\"node-exporter\",mode=\"idle\"})", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "80,90", "title": "CPU Utilization", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "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_PROMETHEUS}", "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 6, "x": 6, "y": 12 }, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "((sum(node_memory_MemTotal) - sum(node_memory_MemFree) - sum(node_memory_Buffers) - sum(node_memory_Cached)) / sum(node_memory_MemTotal)) * 100", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "80,90", "title": "Memory Utilization", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "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_PROMETHEUS}", "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 6, "x": 12, "y": 12 }, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(sum(node_filesystem_size{device!=\"rootfs\"}) - sum(node_filesystem_free{device!=\"rootfs\"})) / sum(node_filesystem_size{device!=\"rootfs\"})", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "80,90", "title": "Filesystem Utilization", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "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_PROMETHEUS}", "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 4, "w": 6, "x": 18, "y": 12 }, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "100 - (sum(kube_node_status_capacity_pods) - sum(kube_pod_info)) / sum(kube_node_status_capacity_pods) * 100", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A", "step": 600 } ], "thresholds": "80,90", "title": "Pod Utilization", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" } ], "schemaVersion": 18, "style": "dark", "tags": [], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Kubernetes Cluster Status", "version": 1 } ... ================================================ FILE: values_overrides/grafana/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci grafana_db_session_sync: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/grafana/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci grafana_db_session_sync: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/grafana/mariadb-operator.yaml ================================================ --- conf: grafana: database: url: null manifests: job_db_init: false job_db_init_session: false secret_db_session: false etcSources: grafana_api: - grafana-db-conn grafana_db_sync: - grafana-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: grafana namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: grafana namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: grafana-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: grafana-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "grafana" table: "*" username: grafana grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: grafana-db-conn spec: mariaDbRef: name: mariadb username: grafana passwordSecretKeyRef: name: grafana-db-password key: password database: grafana secretName: grafana-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/grafana/nginx.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for a dashboard for # nginx --- conf: dashboards: kubernetes: nginx_stats: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "Prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "5.0.0" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "5.0.0" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" }, { "datasource": "${DS_PROMETHEUS}", "enable": true, "expr": "sum(changes(nginx_ingress_controller_config_last_reload_successful_timestamp_seconds{instance!=\"unknown\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[30s])) by (controller_class)", "hide": false, "iconColor": "rgba(255, 96, 96, 1)", "limit": 100, "name": "Config Reloads", "showIn": 0, "step": "30s", "tagKeys": "controller_class", "tags": [], "titleFormat": "Config Reloaded", "type": "tags" } ] }, "editable": true, "overwrite": true, "gnetId": null, "graphTooltip": 0, "links": [], "panels": [ { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "format": "ops", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 6, "x": 0, "y": 0 }, "id": 20, "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" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "round(sum(irate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[2m])), 0.001)", "format": "time_series", "intervalFactor": 1, "refId": "A", "step": 4 } ], "thresholds": "", "title": "Controller Request Volume", "transparent": false, "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 6, "x": 6, "y": 0 }, "id": 82, "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" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "sum(avg_over_time(nginx_ingress_controller_nginx_process_connections{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m]))", "format": "time_series", "instant": false, "intervalFactor": 1, "refId": "A", "step": 4 } ], "thresholds": "", "title": "Controller Connections", "transparent": false, "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "format": "percentunit", "gauge": { "maxValue": 100, "minValue": 80, "show": false, "thresholdLabels": false, "thresholdMarkers": false }, "gridPos": { "h": 3, "w": 6, "x": 12, "y": 0 }, "id": 21, "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" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",status!~\"[4-5].*\"}[2m])) / sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\"}[2m]))", "format": "time_series", "intervalFactor": 1, "refId": "A", "step": 4 } ], "thresholds": "95, 99, 99.5", "title": "Controller Success Rate (non-4|5xx responses)", "transparent": false, "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "decimals": 0, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 3, "x": 18, "y": 0 }, "id": 81, "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" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "avg(nginx_ingress_controller_success{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"})", "format": "time_series", "instant": true, "intervalFactor": 1, "refId": "A", "step": 4 } ], "thresholds": "", "title": "Config Reloads", "transparent": false, "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "datasource": "${DS_PROMETHEUS}", "decimals": 0, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 3, "w": 3, "x": 21, "y": 0 }, "id": 83, "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" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": true, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "count(nginx_ingress_controller_config_last_reload_successful{controller_pod=~\"$controller\",controller_namespace=~\"$namespace\"} == 0)", "format": "time_series", "instant": true, "intervalFactor": 1, "refId": "A", "step": 4 } ], "thresholds": "", "title": "Last Config Failed", "transparent": false, "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "None", "value": "null" } ], "valueName": "avg" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 3 }, "height": "200px", "id": 86, "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": false, "hideEmpty": false, "hideZero": true, "max": false, "min": false, "rightSide": true, "show": true, "sideWidth": 300, "sort": "current", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "repeat": null, "repeatDirection": "h", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "round(sum(irate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress), 0.001)", "format": "time_series", "hide": false, "instant": false, "interval": "", "intervalFactor": 1, "legendFormat": "{{ ingress }}", "metric": "network", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Ingress Request Volume", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "max - istio-proxy": "#890f02", "max - master": "#bf1b00", "max - prometheus": "#bf1b00" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": false, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 3 }, "id": 87, "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": false, "hideEmpty": true, "hideZero": false, "max": false, "min": false, "rightSide": true, "show": true, "sideWidth": 300, "sort": "avg", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",ingress=~\"$ingress\",status!~\"[4-5].*\"}[2m])) by (ingress) / sum(rate(nginx_ingress_controller_requests{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", "format": "time_series", "instant": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "{{ ingress }}", "metric": "container_memory_usage:sort_desc", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Ingress Success Rate (non-4|5xx responses)", "tooltip": { "msResolution": false, "shared": true, "sort": 1, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "percentunit", "label": null, "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 6, "w": 8, "x": 0, "y": 10 }, "height": "200px", "id": 32, "isNew": true, "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, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum (irate (nginx_ingress_controller_request_size_sum{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m]))", "format": "time_series", "instant": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "Received", "metric": "network", "refId": "A", "step": 10 }, { "expr": "- sum (irate (nginx_ingress_controller_response_size_sum{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m]))", "format": "time_series", "hide": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "Sent", "metric": "network", "refId": "B", "step": 10 } ], "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "max - istio-proxy": "#890f02", "max - master": "#bf1b00", "max - prometheus": "#bf1b00" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": false, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 6, "w": 8, "x": 8, "y": 10 }, "id": 77, "isNew": true, "legend": { "alignAsTable": true, "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, "stack": false, "steppedLine": false, "targets": [ { "expr": "avg(nginx_ingress_controller_nginx_process_resident_memory_bytes{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}) ", "format": "time_series", "instant": false, "interval": "10s", "intervalFactor": 1, "legendFormat": "nginx", "metric": "container_memory_usage:sort_desc", "refId": "A", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Average 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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "max - istio-proxy": "#890f02", "max - master": "#bf1b00" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 3, "editable": false, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 6, "w": 8, "x": 16, "y": 10 }, "height": "", "id": 79, "isNew": true, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": false, "min": false, "rightSide": false, "show": false, "sort": null, "sortDesc": null, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum (rate (nginx_ingress_controller_nginx_process_cpu_seconds_total{controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\"}[2m])) ", "format": "time_series", "interval": "10s", "intervalFactor": 1, "legendFormat": "nginx", "metric": "container_cpu", "refId": "A", "step": 10 } ], "thresholds": [ { "colorMode": "critical", "fill": true, "line": true, "op": "gt" } ], "timeFrom": null, "timeShift": null, "title": "Average 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": "none", "label": "cores", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "columns": [], "datasource": "${DS_PROMETHEUS}", "fontSize": "100%", "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 }, "hideTimeOverride": false, "id": 75, "links": [], "pageSize": 7, "repeat": null, "repeatDirection": "h", "scroll": true, "showHeader": true, "sort": { "col": 1, "desc": true }, "styles": [ { "alias": "Ingress", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 2, "pattern": "ingress", "preserveFormat": false, "sanitize": false, "thresholds": [], "type": "string", "unit": "short" }, { "alias": "Requests", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 2, "pattern": "Value #A", "thresholds": [ "" ], "type": "number", "unit": "ops" }, { "alias": "Errors", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 2, "pattern": "Value #B", "thresholds": [], "type": "number", "unit": "ops" }, { "alias": "P50 Latency", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 0, "link": false, "pattern": "Value #C", "thresholds": [], "type": "number", "unit": "dtdurations" }, { "alias": "P90 Latency", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 0, "pattern": "Value #D", "thresholds": [], "type": "number", "unit": "dtdurations" }, { "alias": "P99 Latency", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 0, "pattern": "Value #E", "thresholds": [], "type": "number", "unit": "dtdurations" }, { "alias": "IN", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 2, "pattern": "Value #F", "thresholds": [ "" ], "type": "number", "unit": "Bps" }, { "alias": "", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 2, "pattern": "Time", "thresholds": [], "type": "hidden", "unit": "short" }, { "alias": "OUT", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 2, "mappingType": 1, "pattern": "Value #G", "thresholds": [], "type": "number", "unit": "Bps" } ], "targets": [ { "expr": "histogram_quantile(0.50, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", "format": "table", "hide": false, "instant": true, "intervalFactor": 1, "legendFormat": "{{ ingress }}", "refId": "C" }, { "expr": "histogram_quantile(0.90, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", "format": "table", "hide": false, "instant": true, "intervalFactor": 1, "legendFormat": "{{ ingress }}", "refId": "D" }, { "expr": "histogram_quantile(0.99, sum(rate(nginx_ingress_controller_request_duration_seconds_bucket{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (le, ingress))", "format": "table", "hide": false, "instant": true, "intervalFactor": 1, "legendFormat": "{{ destination_service }}", "refId": "E" }, { "expr": "sum(irate(nginx_ingress_controller_request_size_sum{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", "format": "table", "hide": false, "instant": true, "interval": "", "intervalFactor": 1, "legendFormat": "{{ ingress }}", "refId": "F" }, { "expr": "sum(irate(nginx_ingress_controller_response_size_sum{ingress!=\"\",controller_pod=~\"$controller\",controller_class=~\"$controller_class\",controller_namespace=~\"$namespace\",ingress=~\"$ingress\"}[2m])) by (ingress)", "format": "table", "instant": true, "intervalFactor": 1, "legendFormat": "{{ ingress }}", "refId": "G" } ], "timeFrom": null, "title": "Ingress Percentile Response Times and Transfer Rates", "transform": "table", "transparent": false, "type": "table" }, { "columns": [ { "text": "Current", "value": "current" } ], "datasource": "${DS_PROMETHEUS}", "fontSize": "100%", "gridPos": { "h": 8, "w": 24, "x": 0, "y": 24 }, "height": "1024", "id": 85, "links": [], "pageSize": 7, "scroll": true, "showHeader": true, "sort": { "col": 1, "desc": false }, "styles": [ { "alias": "Time", "dateFormat": "YYYY-MM-DD HH:mm:ss", "pattern": "Time", "type": "date" }, { "alias": "TTL", "colorMode": "cell", "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "dateFormat": "YYYY-MM-DD HH:mm:ss", "decimals": 0, "pattern": "Current", "thresholds": [ "0", "691200" ], "type": "number", "unit": "s" }, { "alias": "", "colorMode": null, "colors": [ "rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)" ], "decimals": 2, "pattern": "/.*/", "thresholds": [], "type": "number", "unit": "short" } ], "targets": [ { "expr": "avg(nginx_ingress_controller_ssl_expire_time_seconds{kubernetes_pod_name=~\"$controller\",namespace=~\"$namespace\",ingress=~\"$ingress\"}) by (host) - time()", "format": "time_series", "intervalFactor": 1, "legendFormat": "{{ host }}", "metric": "gke_letsencrypt_cert_expiration", "refId": "A", "step": 1 } ], "title": "Ingress Certificate Expiry", "transform": "timeseries_aggregations", "type": "table" } ], "refresh": "5s", "schemaVersion": 16, "style": "dark", "tags": [ "nginx" ], "templating": { "list": [ { "allValue": ".*", "current": { "text": "All", "value": "$__all" }, "datasource": "${DS_PROMETHEUS}", "hide": 0, "includeAll": true, "label": "Namespace", "multi": false, "name": "namespace", "options": [], "query": "label_values(nginx_ingress_controller_config_hash, controller_namespace)", "refresh": 1, "regex": "", "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": ".*", "current": { "text": "All", "value": "$__all" }, "datasource": "${DS_PROMETHEUS}", "hide": 0, "includeAll": true, "label": "Controller Class", "multi": false, "name": "controller_class", "options": [], "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\"}, controller_class) ", "refresh": 1, "regex": "", "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": ".*", "current": { "text": "All", "value": "$__all" }, "datasource": "${DS_PROMETHEUS}", "hide": 0, "includeAll": true, "label": "Controller", "multi": false, "name": "controller", "options": [], "query": "label_values(nginx_ingress_controller_config_hash{namespace=~\"$namespace\",controller_class=~\"$controller_class\"}, controller_pod) ", "refresh": 1, "regex": "", "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": ".*", "current": { "tags": [], "text": "All", "value": "$__all" }, "datasource": "${DS_PROMETHEUS}", "hide": 0, "includeAll": true, "label": "Ingress", "multi": false, "name": "ingress", "options": [], "query": "label_values(nginx_ingress_controller_requests{namespace=~\"$namespace\",controller_class=~\"$controller_class\",controller=~\"$controller\"}, ingress) ", "refresh": 1, "regex": "", "sort": 2, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "2m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "NGINX Ingress controller", "uid": "nginx", "version": 1 } ... ================================================ FILE: values_overrides/grafana/nodes.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for a dashboard for # the status of all nodes in a deployment --- conf: dashboards: lma: nodes: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.4.1" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "description": "Dashboard to get an overview of one server", "overwrite": true, "editable": true, "gnetId": 22, "graphTooltip": 0, "id": 8, "links": [], "panels": [ { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 0 }, "id": 3, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "100 - (avg by (cpu) (irate(node_cpu{mode=\"idle\", instance=\"$server\"}[5m])) * 100)", "hide": false, "intervalFactor": 10, "legendFormat": "{{cpu}}", "refId": "A", "step": 50 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Idle cpu", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "percent", "label": "cpu usage", "logBase": 1, "max": 100, "min": 0, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 0 }, "id": 9, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "node_load1{instance=\"$server\"}", "intervalFactor": 4, "legendFormat": "load 1m", "refId": "A", "step": 20, "target": "" }, { "expr": "node_load5{instance=\"$server\"}", "intervalFactor": 4, "legendFormat": "load 5m", "refId": "B", "step": 20, "target": "" }, { "expr": "node_load15{instance=\"$server\"}", "intervalFactor": 4, "legendFormat": "load 15m", "refId": "C", "step": 20, "target": "" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "System load", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "percentunit", "label": null, "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 18, "x": 0, "y": 7 }, "id": 4, "legend": { "alignAsTable": false, "avg": false, "current": false, "hideEmpty": false, "hideZero": false, "max": false, "min": false, "rightSide": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "node_memory_SwapFree{instance=\"$server\",job=\"prometheus\"}", "yaxis": 2 } ], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "node_memory_MemTotal{instance=\"$server\"} - node_memory_MemFree{instance=\"$server\"} - node_memory_Buffers{instance=\"$server\"} - node_memory_Cached{instance=\"$server\"}", "hide": false, "interval": "", "intervalFactor": 2, "legendFormat": "memory used", "metric": "", "refId": "C", "step": 10 }, { "expr": "node_memory_Buffers{instance=\"$server\"}", "interval": "", "intervalFactor": 2, "legendFormat": "memory buffers", "metric": "", "refId": "E", "step": 10 }, { "expr": "node_memory_Cached{instance=\"$server\"}", "intervalFactor": 2, "legendFormat": "memory cached", "metric": "", "refId": "F", "step": 10 }, { "expr": "node_memory_MemFree{instance=\"$server\"}", "intervalFactor": 2, "legendFormat": "memory free", "metric": "", "refId": "D", "step": 10 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Memory usage", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 7 }, "id": 5, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "((node_memory_MemTotal{instance=\"$server\"} - node_memory_MemFree{instance=\"$server\"} - node_memory_Buffers{instance=\"$server\"} - node_memory_Cached{instance=\"$server\"}) / node_memory_MemTotal{instance=\"$server\"}) * 100", "intervalFactor": 2, "refId": "A", "step": 60, "target": "" } ], "thresholds": "80, 90", "title": "Memory usage", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 18, "x": 0, "y": 14 }, "id": 6, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "read", "yaxis": 1 }, { "alias": "{instance=\"$server\"}", "yaxis": 2 }, { "alias": "io time", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum by (instance) (rate(node_disk_bytes_read{instance=\"$server\"}[2m]))", "hide": false, "intervalFactor": 4, "legendFormat": "read", "refId": "A", "step": 20, "target": "" }, { "expr": "sum by (instance) (rate(node_disk_bytes_written{instance=\"$server\"}[2m]))", "intervalFactor": 4, "legendFormat": "written", "refId": "B", "step": 20 }, { "expr": "sum by (instance) (rate(node_disk_io_time_ms{instance=\"$server\"}[2m]))", "intervalFactor": 4, "legendFormat": "io time", "refId": "C", "step": 20 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Disk I/O", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "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": "ms", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "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_PROMETHEUS}", "editable": true, "error": false, "format": "percentunit", "gauge": { "maxValue": 1, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 14 }, "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, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(sum(node_filesystem_size{device!=\"rootfs\",instance=\"$server\"}) - sum(node_filesystem_free{device!=\"rootfs\",instance=\"$server\"})) / sum(node_filesystem_size{device!=\"rootfs\",instance=\"$server\"})", "intervalFactor": 2, "refId": "A", "step": 60, "target": "" } ], "thresholds": "0.75, 0.9", "title": "Disk space usage", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 21 }, "id": 8, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "transmitted ", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(node_network_receive_bytes{instance=\"$server\",device!~\"lo\"}[5m])", "hide": false, "intervalFactor": 2, "legendFormat": "{{device}}", "refId": "A", "step": 10, "target": "" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Network received", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "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": "bytes", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "alerting": {}, "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 21 }, "id": 10, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "transmitted ", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(node_network_transmit_bytes{instance=\"$server\",device!~\"lo\"}[5m])", "hide": false, "intervalFactor": 2, "legendFormat": "{{device}}", "refId": "B", "step": 10, "target": "" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Network transmitted", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "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": "bytes", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "refresh": false, "schemaVersion": 18, "style": "dark", "tags": [], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": null, "current": {}, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Server", "multi": false, "name": "host", "options": [], "query": "label_values(node_uname_info, nodename)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": null, "current": {}, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 2, "includeAll": false, "label": "Instance", "multi": false, "name": "server", "options": [], "query": "label_values(node_uname_info{nodename=\"$host\"}, instance)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Nodes", "version": 1 } ... ================================================ FILE: values_overrides/grafana/openstack.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for dashboards for # the openstack control plane as a whole, the individual openstack services, and # rabbitmq --- conf: dashboards: openstack: rabbitmq: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "Prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.2.0" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "list": [] }, "editable": true, "overwrite": true, "gnetId": 2121, "graphTooltip": 0, "hideControls": false, "id": null, "links": [], "refresh": "5s", "rows": [ { "collapse": false, "height": 266, "panels": [ { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(50, 172, 45, 0.97)", "rgba(237, 129, 40, 0.89)", "rgba(245, 54, 54, 0.9)" ], "datasource": "${DS_PROMETHEUS}", "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "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": 3, "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "targets": [ { "expr": "rabbitmq_up", "intervalFactor": 2, "metric": "rabbitmq_up", "refId": "A", "step": 2 } ], "thresholds": "Up,Down", "timeFrom": "30s", "title": "RabbitMQ Server", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" }, { "op": "=", "text": "Down", "value": "0" }, { "op": "=", "text": "Up", "value": "1" } ], "valueName": "current" }, { "alert": { "conditions": [ { "evaluator": { "params": [ 1 ], "type": "lt" }, "operator": { "type": "and" }, "query": { "params": [ "A", "10s", "now" ] }, "reducer": { "params": [], "type": "last" }, "type": "query" }, { "evaluator": { "params": [], "type": "no_value" }, "operator": { "type": "and" }, "query": { "params": [ "A", "10s", "now" ] }, "reducer": { "params": [], "type": "last" }, "type": "query" } ], "executionErrorState": "alerting", "frequency": "60s", "handler": 1, "message": "Some of the RabbitMQ node is down", "name": "Node Stats alert", "noDataState": "no_data", "notifications": [] }, "aliasColors": {}, "bars": true, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "fill": 1, "id": 12, "legend": { "alignAsTable": true, "avg": false, "current": true, "max": false, "min": false, "show": true, "total": false, "values": true }, "lines": false, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 9, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_running", "intervalFactor": 2, "legendFormat": "{{node}}", "metric": "rabbitmq_running", "refId": "A", "step": 2 } ], "thresholds": [ { "colorMode": "critical", "fill": true, "line": true, "op": "lt", "value": 1 } ], "timeFrom": "30s", "timeShift": null, "title": "Node up Stats", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "fill": 1, "id": 6, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 4, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_exchangesTotal", "intervalFactor": 2, "legendFormat": "{{instance}}:exchanges", "metric": "rabbitmq_exchangesTotal", "refId": "A", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Exchanges", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "fill": 1, "id": 4, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 4, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_channelsTotal", "intervalFactor": 2, "legendFormat": "{{instance}}:channels", "metric": "rabbitmq_channelsTotal", "refId": "A", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Channels", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "fill": 1, "id": 3, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 4, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_consumersTotal", "intervalFactor": 2, "legendFormat": "{{instance}}:consumers", "metric": "rabbitmq_consumersTotal", "refId": "A", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Consumers", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "fill": 1, "id": 5, "legend": { "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 4, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_connectionsTotal", "intervalFactor": 2, "legendFormat": "{{instance}}:connections", "metric": "rabbitmq_connectionsTotal", "refId": "A", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Connections", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "fill": 1, "id": 7, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 4, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_queuesTotal", "intervalFactor": 2, "legendFormat": "{{instance}}:queues", "metric": "rabbitmq_queuesTotal", "refId": "A", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Queues", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "fill": 1, "id": 8, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 6, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum by (vhost)(rabbitmq_queue_messages_ready)", "intervalFactor": 2, "legendFormat": "{{vhost}}:ready", "metric": "rabbitmq_queue_messages_ready", "refId": "A", "step": 2 }, { "expr": "sum by (vhost)(rabbitmq_queue_messages_published_total)", "intervalFactor": 2, "legendFormat": "{{vhost}}:published", "metric": "rabbitmq_queue_messages_published_total", "refId": "B", "step": 2 }, { "expr": "sum by (vhost)(rabbitmq_queue_messages_delivered_total)", "intervalFactor": 2, "legendFormat": "{{vhost}}:delivered", "metric": "rabbitmq_queue_messages_delivered_total", "refId": "C", "step": 2 }, { "expr": "sum by (vhost)(rabbitmq_queue_messages_unacknowledged)", "intervalFactor": 2, "legendFormat": "{{vhost}}:unack", "metric": "ack", "refId": "D", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Messages/host", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "decimals": 0, "fill": 1, "id": 2, "legend": { "alignAsTable": true, "avg": false, "current": true, "max": false, "min": false, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 6, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_queue_messages", "intervalFactor": 2, "legendFormat": "{{queue}}:{{durable}}", "metric": "rabbitmq_queue_messages", "refId": "A", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Messages / Queue", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "fill": 1, "id": 9, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 6, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_node_mem_used", "intervalFactor": 2, "legendFormat": "{{node}}:used", "metric": "rabbitmq_node_mem_used", "refId": "A", "step": 2 }, { "expr": "rabbitmq_node_mem_limit", "intervalFactor": 2, "legendFormat": "{{node}}:limit", "metric": "node_mem", "refId": "B", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Memory", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "fill": 1, "id": 10, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 6, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_fd_used", "intervalFactor": 2, "legendFormat": "{{node}}:used", "metric": "", "refId": "A", "step": 2 }, { "expr": "rabbitmq_fd_total", "intervalFactor": 2, "legendFormat": "{{node}}:total", "metric": "node_mem", "refId": "B", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "FIle descriptors", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "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, "datasource": "${DS_PROMETHEUS}", "fill": 1, "id": 11, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "span": 6, "stack": false, "steppedLine": false, "targets": [ { "expr": "rabbitmq_sockets_used", "intervalFactor": 2, "legendFormat": "{{node}}:used", "metric": "", "refId": "A", "step": 2 }, { "expr": "rabbitmq_sockets_total", "intervalFactor": 2, "legendFormat": "{{node}}:total", "metric": "", "refId": "B", "step": 2 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Sockets", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "transparent": false, "type": "graph", "xaxis": { "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": false, "title": "Dashboard Row", "titleSize": "h6" } ], "schemaVersion": 14, "style": "dark", "tags": [], "templating": { "list": [ { "current": { "tags": [], "text": "Prometheus", "value": "Prometheus" }, "hide": 0, "label": null, "name": "datasource", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "type": "datasource" } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "RabbitMQ Metrics", "version": 17, "description": "Basic rabbitmq host stats: Node Stats, Exchanges, Channels, Consumers, Connections, Queues, Messages, Messages per Queue, Memory, File Descriptors, Sockets." } openstack_control_plane: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.5.2" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" }, { "type": "panel", "id": "text", "name": "Text", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": false, "overwrite": true, "gnetId": null, "graphTooltip": 1, "id": 11, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 28, "panels": [], "repeat": null, "title": "OpenStack Services", "type": "row" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 0, "y": 1 }, "id": 24, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=keystone", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_keystone_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Keystone", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 2, "y": 1 }, "id": 23, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=glance", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_glance_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Glance", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(202, 58, 40, 0.86)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 4, "y": 1 }, "id": 22, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=heat", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_heat_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Heat", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 6, "y": 1 }, "id": 21, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=neutron", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_neutron_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Neutron", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(208, 53, 34, 0.82)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 8, "y": 1 }, "id": 20, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=nova", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_nova_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Nova", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 10, "y": 1 }, "id": 19, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=swift", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_swift_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Ceph", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 12, "y": 1 }, "id": 18, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=cinder", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_cinder_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Cinder", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 14, "y": 1 }, "id": 17, "interval": "> 60s", "links": [ { "dashboard": "Openstack Service", "name": "Drilldown dashboard", "params": "var-Service=placement", "title": "Openstack Service", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_placement_api{job=\"openstack-metrics\", region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Placement", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(208, 53, 34, 0.82)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 16, "y": 1 }, "id": 16, "interval": "> 60s", "links": [ { "dashboard": "RabbitMQ Metrics", "name": "Drilldown dashboard", "title": "RabbitMQ Metrics", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "min(rabbitmq_up)", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "RabbitMQ", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(208, 53, 34, 0.82)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 18, "y": 1 }, "id": 15, "interval": "> 60s", "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "min(mysql_global_status_wsrep_ready)", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "MariaDB", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(225, 177, 40, 0.59)", "rgba(208, 53, 34, 0.82)", "rgba(118, 245, 40, 0.73)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 20, "y": 1 }, "id": 14, "interval": "> 60s", "links": [ { "dashboard": "Nginx Stats", "name": "Drilldown dashboard", "title": "Nginx Stats", "type": "dashboard" } ], "mappingType": 2, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "1", "text": "OK", "to": "99999999999999" }, { "from": "0", "text": "CRIT", "to": "0" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "sum_over_time(nginx_connections_total{type=\"active\", namespace=\"openstack\"}[5m])", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "0,1", "title": "Nginx", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(208, 53, 34, 0.82)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 2, "x": 22, "y": 1 }, "id": 13, "interval": "> 60s", "links": [ { "dashboard": "Memcached", "name": "Drilldown dashboard", "title": "Memcached", "type": "dashboard" } ], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "min(memcached_up)", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "1,2", "title": "Memcached", "type": "singlestat", "valueFontSize": "50%", "valueMaps": [ { "op": "=", "text": "no data", "value": "null" }, { "op": "=", "text": "CRIT", "value": "0" }, { "op": "=", "text": "OK", "value": "1" }, { "op": "=", "text": "UNKW", "value": "2" } ], "valueName": "current" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 2, "x": 22, "y": 8 }, "id": 13, "interval": "> 60s", "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 3, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "alias": "free", "column": "value", "expr": "openstack_total_used_disk_GB{job=\"openstack-metrics\", region=\"$region\"} + openstack_total_free_disk_GB{job=\"openstack-metrics\", region=\"$region\"}", "format": "time_series", "function": "mean", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 }, { "alias": "used", "column": "value", "expr": "openstack_total_used_disk_GB{job=\"openstack-metrics\", region=\"$region\"}", "format": "time_series", "function": "mean", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "B", "resultFormat": "time_series", "step": 120 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Disk (used vs total)", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "gbytes", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 15 }, "id": 29, "panels": [], "repeat": null, "title": "Virtual resources", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 16 }, "id": 11, "interval": "> 60s", "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 3, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "alias": "free", "column": "value", "expr": "openstack_total_used_vcpus{job=\"openstack-metrics\", region=\"$region\"} + openstack_total_free_vcpus{job=\"openstack-metrics\", region=\"$region\"}", "format": "time_series", "function": "min", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 }, { "alias": "used", "column": "value", "expr": "openstack_total_used_vcpus{job=\"openstack-metrics\", region=\"$region\"}", "format": "time_series", "function": "max", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "B", "resultFormat": "time_series", "step": 120 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "VCPUs (total vs used)", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 8, "x": 8, "y": 16 }, "id": 12, "interval": "> 60s", "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 3, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "alias": "free", "column": "value", "expr": "openstack_total_used_ram_MB{job=\"openstack-metrics\", region=\"$region\"} + openstack_total_free_ram_MB{job=\"openstack-metrics\", region=\"$region\"}", "format": "time_series", "function": "mean", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 }, { "alias": "used", "column": "value", "expr": "openstack_total_used_ram_MB{job=\"openstack-metrics\", region=\"$region\"}", "format": "time_series", "function": "mean", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "B", "resultFormat": "time_series", "step": 120 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "RAM (total vs used)", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "mbytes", "label": "", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "dashes\"": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 23 }, "id": 27, "interval": "> 60s", "legend": { "alignAsTable": false, "avg": true, "current": true, "hideEmpty": true, "hideZero": false, "max": true, "min": true, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 4, "links": [], "nullPointMode": null, "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "alias": "free", "column": "value", "expr": "sum(openstack_running_instances)", "format": "time_series", "function": "mean", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "interval": "15s", "intervalFactor": 1, "legendFormat": "{{ running_vms }}", "policy": "default", "rawQuery": false, "refID": "A", "refId": "A", "resultFormat": "time_series" }, { "alias": "used", "column": "value", "expr": "sum(openstack_total_running_instances)", "format": "time_series", "function": "mean", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "interval": "15s", "intervalFactor": 1, "legendFormat": "{{ total_vms }}", "policy": "default", "rawQuery": false, "refID": "B", "refId": "B", "resultFormat": "time_series", "step": 120 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "OpenStack Instances", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "transparent": true, "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": false } ], "yaxis": { "align": false, "alignLevel": null } } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": null, "current": {}, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": null, "multi": false, "name": "region", "options": [], "query": "label_values(openstack_exporter_cache_refresh_duration_seconds, region)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "collapse": false, "enable": true, "notice": false, "now": true, "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "status": "Stable", "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ], "type": "timepicker" }, "timezone": "browser", "title": "OpenStack Metrics", "version": 1 } openstack-service: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.5.2" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" } ], "annotations": { "enable": true, "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": false, "overwrite": true, "gnetId": null, "graphTooltip": 1, "id": 29, "links": [], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 14, "panels": [], "repeat": null, "title": "Service Status", "type": "row" }, { "cacheTimeout": null, "colorBackground": true, "colorValue": false, "colors": [ "rgba(225, 177, 40, 0.59)", "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 4, "x": 0, "y": 1 }, "id": 6, "interval": "> 60s", "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "openstack_check_[[Service]]_api{job=\"openstack-metrics\",region=\"$region\"}", "fill": "", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "null" ], "type": "fill" } ], "groupByTags": [], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120 } ], "thresholds": "0,1", "title": "", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "CRITICAL", "value": "0" }, { "op": "=", "text": "OK", "value": "1" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "rgba(200, 54, 35, 0.88)", "rgba(118, 245, 40, 0.73)", "rgba(225, 177, 40, 0.59)" ], "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 7, "w": 4, "x": 4, "y": 1 }, "id": 13, "interval": "> 60s", "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "column": "value", "condition": "", "expr": "sum(nginx_responses_total{server_zone=~\"[[Service]].*\", status_code=\"5xx\",region=\"$region\"})", "fill": "", "format": "time_series", "function": "count", "groupBy": [ { "interval": "auto", "params": [ "auto" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupby_field": "", "interval": "", "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "step": 120, "tags": [] } ], "thresholds": "", "title": "HTTP 5xx errors", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "0", "value": "null" } ], "valueName": "current" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 7, "w": 16, "x": 8, "y": 1 }, "id": 7, "interval": ">60s", "legend": { "alignAsTable": true, "avg": true, "current": false, "max": true, "min": true, "show": true, "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(nginx_upstream_response_msecs_avg{upstream=~\"openstack-[[Service]].*\",region=\"$region\"}) by (upstream)", "format": "time_series", "intervalFactor": 2, "refId": "A", "step": 120 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "HTTP response time", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "s", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 8 }, "id": 9, "interval": "> 60s", "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": true, "targets": [ { "alias": "healthy", "column": "value", "expr": "openstack_check_[[Service]]_api{region=\"$region\"}", "format": "time_series", "function": "last", "groupBy": [ { "params": [ "$interval" ], "type": "time" }, { "params": [ "0" ], "type": "fill" } ], "groupByTags": [], "intervalFactor": 2, "policy": "default", "rawQuery": false, "refId": "A", "resultFormat": "time_series", "select": [], "step": 120, "tags": [] } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "API Availability", "tooltip": { "msResolution": false, "shared": false, "sort": 0, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "none", "label": "", "logBase": 1, "max": 1, "min": 0, "show": false }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": false } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "{status_code=\"2xx\"}": "#629E51", "{status_code=\"5xx\"}": "#BF1B00" }, "bars": true, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 0, "grid": {}, "gridPos": { "h": 7, "w": 16, "x": 8, "y": 8 }, "id": 8, "interval": "> 60s", "legend": { "alignAsTable": false, "avg": false, "current": false, "hideEmpty": false, "max": false, "min": false, "rightSide": false, "show": true, "total": false, "values": false }, "lines": false, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "sum(nginx_responses_total{server_zone=~\"[[Service]].*\",region=\"$region\"}) by (status_code)", "format": "time_series", "intervalFactor": 2, "refId": "A", "step": 120 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Number of HTTP responses", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [], "templating": { "list": [ { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "allValue": null, "current": {}, "datasource": "prometheus", "definition": "", "hide": 0, "includeAll": false, "label": "region", "multi": false, "name": "region", "options": [], "query": "label_values(openstack_exporter_cache_refresh_duration_seconds, region)", "refresh": 1, "regex": "", "skipUrlSync": false, "sort": 0, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": null, "current": { "tags": [], "text": "cinder", "value": "cinder" }, "hide": 0, "includeAll": false, "label": null, "multi": false, "name": "Service", "options": [ { "selected": false, "text": "nova", "value": "nova" }, { "selected": false, "text": "glance", "value": "glance" }, { "selected": false, "text": "keystone", "value": "keystone" }, { "selected": true, "text": "cinder", "value": "cinder" }, { "selected": false, "text": "heat", "value": "heat" }, { "selected": false, "text": "placement", "value": "placement" }, { "selected": false, "text": "neutron", "value": "neutron" } ], "query": "nova,glance,keystone,cinder,heat,placement,neutron", "skipUrlSync": false, "type": "custom" } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "collapse": false, "enable": true, "notice": false, "now": true, "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "status": "Stable", "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ], "type": "timepicker" }, "timezone": "browser", "title": "Openstack Service", "version": 1 } ... ================================================ FILE: values_overrides/grafana/persistentvolume.yaml ================================================ # This overrides file provides a raw json file for a dashboard for # the etcd --- conf: dashboards: openstack: persistent_volume: |- { "__inputs": [ { "name": "prometheus", "label": "Prometheus", "description": "", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "5.0.0" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" } ], "annotations": { "list": [ ] }, "editable": false, "overwrite": true, "gnetId": null, "graphTooltip": 0, "hideControls": false, "id": null, "links": [ ], "refresh": "", "rows": [ { "collapse": false, "collapsed": false, "panels": [ { "aliasColors": { }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "$datasource", "fill": 1, "gridPos": { }, "id": 2, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [ ], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "repeat": null, "seriesOverrides": [ ], "spaceLength": 10, "span": 9, "stack": true, "steppedLine": false, "targets": [ { "expr": "(\n sum without(instance, node) (kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n -\n sum without(instance, node) (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n)\n", "format": "time_series", "intervalFactor": 1, "legendFormat": "Used Space", "refId": "A" }, { "expr": "sum without(instance, node) (kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n", "format": "time_series", "intervalFactor": 1, "legendFormat": "Free Space", "refId": "B" } ], "thresholds": [ ], "timeFrom": null, "timeShift": null, "title": "Volume Space Usage", "tooltip": { "shared": false, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [ ] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": 0, "show": true }, { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ] }, { "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": "$datasource", "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { }, "id": 3, "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": 3, "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "(\n kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"}\n -\n kubelet_volume_stats_available_bytes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"}\n)\n/\nkubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"}\n* 100\n", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A" } ], "thresholds": "80, 90", "title": "Volume Space Usage", "tooltip": { "shared": false }, "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" } ], "repeat": null, "repeatIteration": null, "repeatRowId": null, "showTitle": false, "title": "Dashboard Row", "titleSize": "h6", "type": "row" }, { "collapse": false, "collapsed": false, "panels": [ { "aliasColors": { }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "$datasource", "fill": 1, "gridPos": { }, "id": 4, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": true, "rightSide": false, "show": true, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [ ], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "repeat": null, "seriesOverrides": [ ], "spaceLength": 10, "span": 9, "stack": true, "steppedLine": false, "targets": [ { "expr": "sum without(instance, node) (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n", "format": "time_series", "intervalFactor": 1, "legendFormat": "Used inodes", "refId": "A" }, { "expr": "(\n sum without(instance, node) (kubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n -\n sum without(instance, node) (kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"})\n)\n", "format": "time_series", "intervalFactor": 1, "legendFormat": " Free inodes", "refId": "B" } ], "thresholds": [ ], "timeFrom": null, "timeShift": null, "title": "Volume inodes Usage", "tooltip": { "shared": false, "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": 0, "show": true }, { "format": "none", "label": null, "logBase": 1, "max": null, "min": 0, "show": true } ] }, { "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": "$datasource", "format": "percent", "gauge": { "maxValue": 100, "minValue": 0, "show": true, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { }, "id": 5, "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": 3, "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "kubelet_volume_stats_inodes_used{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"}\n/\nkubelet_volume_stats_inodes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\", persistentvolumeclaim=\"$volume\"}\n* 100\n", "format": "time_series", "intervalFactor": 2, "legendFormat": "", "refId": "A" } ], "thresholds": "80, 90", "title": "Volume inodes Usage", "tooltip": { "shared": false }, "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" } ], "repeat": null, "repeatIteration": null, "repeatRowId": null, "showTitle": false, "title": "Dashboard Row", "titleSize": "h6", "type": "row" } ], "schemaVersion": 14, "style": "dark", "tags": [ "kubernetes-mixin" ], "templating": { "list": [ { "current": { "text": "Prometheus", "value": "Prometheus" }, "hide": 0, "label": null, "name": "datasource", "options": [ ], "query": "prometheus", "refresh": 1, "regex": "", "type": "datasource" }, { "allValue": null, "current": { }, "datasource": "$datasource", "hide": 2, "includeAll": false, "label": "cluster", "multi": false, "name": "cluster", "options": [ ], "query": "label_values(kubelet_volume_stats_capacity_bytes, cluster)", "refresh": 2, "regex": "", "sort": 1, "tagValuesQuery": "", "tags": [ ], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": null, "current": { }, "datasource": "$datasource", "hide": 0, "includeAll": false, "label": "Namespace", "multi": false, "name": "namespace", "options": [ ], "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\"}, namespace)", "refresh": 2, "regex": "", "sort": 1, "tagValuesQuery": "", "tags": [ ], "tagsQuery": "", "type": "query", "useTags": false }, { "allValue": null, "current": { }, "datasource": "$datasource", "hide": 0, "includeAll": false, "label": "PersistentVolumeClaim", "multi": false, "name": "volume", "options": [ ], "query": "label_values(kubelet_volume_stats_capacity_bytes{cluster=\"$cluster\", job=\"kubelet\", namespace=\"$namespace\"}, persistentvolumeclaim)", "refresh": 2, "regex": "", "sort": 1, "tagValuesQuery": "", "tags": [ ], "tagsQuery": "", "type": "query", "useTags": false } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "", "title": "Persistent Volumes", "version": 0 } ... ================================================ FILE: values_overrides/grafana/prometheus.yaml ================================================ # NOTE(srwilkers): This overrides file provides a reference for a dashboard for # Prometheus --- conf: dashboards: lma: prometheus: |- { "__inputs": [ { "name": "DS_PROMETHEUS", "label": "prometheus", "description": "Prometheus which you want to monitor", "type": "datasource", "pluginId": "prometheus", "pluginName": "Prometheus" } ], "__requires": [ { "type": "grafana", "id": "grafana", "name": "Grafana", "version": "4.6.0" }, { "type": "panel", "id": "graph", "name": "Graph", "version": "" }, { "type": "datasource", "id": "prometheus", "name": "Prometheus", "version": "1.0.0" }, { "type": "panel", "id": "singlestat", "name": "Singlestat", "version": "" }, { "type": "panel", "id": "text", "name": "Text", "version": "" } ], "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" }, { "datasource": "${DS_PROMETHEUS}", "enable": true, "expr": "count(sum(up{instance=\"$instance\"}) by (instance) < 1)", "hide": false, "iconColor": "rgb(250, 44, 18)", "limit": 100, "name": "downage", "showIn": 0, "step": "30s", "tagKeys": "instance", "textFormat": "prometheus down", "titleFormat": "Downage", "type": "alert" }, { "datasource": "${DS_PROMETHEUS}", "enable": true, "expr": "sum(changes(prometheus_config_last_reload_success_timestamp_seconds[10m])) by (instance)", "hide": false, "iconColor": "#fceaca", "limit": 100, "name": "Reload", "showIn": 0, "step": "5m", "tagKeys": "instance", "tags": [], "titleFormat": "Reload", "type": "tags" } ] }, "description": "Dashboard for monitoring of Prometheus v2.x.x", "overwrite": true, "editable": false, "gnetId": 3681, "graphTooltip": 1, "id": 41, "links": [ { "icon": "info", "tags": [], "targetBlank": true, "title": "Dashboard's Github ", "tooltip": "Github repo of this dashboard", "type": "link", "url": "https://github.com/FUSAKLA/Prometheus2-grafana-dashboard" }, { "icon": "doc", "tags": [], "targetBlank": true, "title": "Prometheus Docs", "tooltip": "", "type": "link", "url": "http://prometheus.io/docs/introduction/overview/" } ], "panels": [ { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 53, "panels": [], "repeat": null, "title": "Header instance info", "type": "row" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "#299c46", "rgba(237, 129, 40, 0.89)", "#bf1b00" ], "datasource": "${DS_PROMETHEUS}", "decimals": 1, "format": "s", "gauge": { "maxValue": 1000000, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 4, "x": 0, "y": 1 }, "id": 41, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "time() - process_start_time_seconds{instance=\"$instance\"}", "format": "time_series", "instant": false, "intervalFactor": 2, "refId": "A" } ], "thresholds": "", "title": "Uptime", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": true, "colors": [ "#299c46", "rgba(237, 129, 40, 0.89)", "#bf1b00" ], "datasource": "${DS_PROMETHEUS}", "format": "short", "gauge": { "maxValue": 1000000, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 8, "x": 4, "y": 1 }, "id": 42, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": true }, "tableColumn": "", "targets": [ { "expr": "prometheus_tsdb_head_series{instance=\"$instance\"}", "format": "time_series", "instant": false, "intervalFactor": 2, "refId": "A" } ], "thresholds": "500000,800000,1000000", "title": "Total count of time series", "type": "singlestat", "valueFontSize": "150%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a" ], "datasource": "${DS_PROMETHEUS}", "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 4, "x": 12, "y": 1 }, "id": 48, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "version", "targets": [ { "expr": "prometheus_build_info{instance=\"$instance\"}", "format": "table", "instant": true, "intervalFactor": 2, "refId": "A" } ], "thresholds": "", "title": "Version", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": false, "colors": [ "#299c46", "rgba(237, 129, 40, 0.89)", "#d44a3a" ], "datasource": "${DS_PROMETHEUS}", "decimals": 2, "format": "ms", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 4, "x": 16, "y": 1 }, "id": 49, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "prometheus_tsdb_head_max_time{instance=\"$instance\"} - prometheus_tsdb_head_min_time{instance=\"$instance\"}", "format": "time_series", "instant": true, "intervalFactor": 2, "refId": "A" } ], "thresholds": "", "title": "Actual head block length", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "current" }, { "content": "", "gridPos": { "h": 5, "w": 2, "x": 20, "y": 1 }, "height": "", "id": 50, "links": [], "mode": "html", "options": {}, "title": "", "transparent": true, "type": "text" }, { "cacheTimeout": null, "colorBackground": false, "colorValue": true, "colors": [ "#e6522c", "rgba(237, 129, 40, 0.89)", "#299c46" ], "datasource": "${DS_PROMETHEUS}", "decimals": 1, "format": "none", "gauge": { "maxValue": 100, "minValue": 0, "show": false, "thresholdLabels": false, "thresholdMarkers": true }, "gridPos": { "h": 5, "w": 2, "x": 22, "y": 1 }, "id": 52, "interval": null, "links": [], "mappingType": 1, "mappingTypes": [ { "name": "value to text", "value": 1 }, { "name": "range to text", "value": 2 } ], "maxDataPoints": 100, "nullPointMode": "connected", "nullText": null, "options": {}, "postfix": "", "postfixFontSize": "50%", "prefix": "", "prefixFontSize": "50%", "rangeMaps": [ { "from": "null", "text": "N/A", "to": "null" } ], "sparkline": { "fillColor": "rgba(31, 118, 189, 0.18)", "full": false, "lineColor": "rgb(31, 120, 193)", "show": false }, "tableColumn": "", "targets": [ { "expr": "2", "format": "time_series", "intervalFactor": 2, "refId": "A" } ], "thresholds": "10,20", "title": "", "transparent": true, "type": "singlestat", "valueFontSize": "200%", "valueMaps": [ { "op": "=", "text": "N/A", "value": "null" } ], "valueName": "avg" }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 6 }, "id": 54, "panels": [], "repeat": null, "title": "Main info", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 7 }, "id": 15, "legend": { "avg": true, "current": false, "max": false, "min": false, "show": false, "total": false, "values": true }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": true, "steppedLine": false, "targets": [ { "expr": "max(prometheus_engine_query_duration_seconds{instance=\"$instance\"}) by (instance, slice)", "format": "time_series", "intervalFactor": 1, "legendFormat": "max duration for {{slice}}", "metric": "prometheus_local_storage_rushed_mode", "refId": "A", "step": 900 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Query elapsed time", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "s", "label": "", "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 8, "y": 7 }, "id": 17, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(prometheus_tsdb_head_series_created_total{instance=\"$instance\"}[$aggregation_interval])) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "created on {{ instance }}", "metric": "prometheus_local_storage_maintain_series_duration_seconds_count", "refId": "A", "step": 1800 }, { "expr": "sum(increase(prometheus_tsdb_head_series_removed_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) * -1", "format": "time_series", "intervalFactor": 2, "legendFormat": "removed on {{ instance }}", "refId": "B" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Head series created/deleted", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 16, "y": 7 }, "id": 13, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(prometheus_target_scrapes_exceeded_sample_limit_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "exceeded_sample_limit on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "A", "step": 1800 }, { "expr": "sum(increase(prometheus_target_scrapes_sample_duplicate_timestamp_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "duplicate_timestamp on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "B", "step": 1800 }, { "expr": "sum(increase(prometheus_target_scrapes_sample_out_of_bounds_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "out_of_bounds on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "C", "step": 1800 }, { "expr": "sum(increase(prometheus_target_scrapes_sample_out_of_order_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "out_of_order on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "D", "step": 1800 }, { "expr": "sum(increase(prometheus_rule_evaluation_failures_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "rule_evaluation_failure on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "G", "step": 1800 }, { "expr": "sum(increase(prometheus_tsdb_compactions_failed_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "tsdb_compactions_failed on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "K", "step": 1800 }, { "expr": "sum(increase(prometheus_tsdb_reloads_failures_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "tsdb_reloads_failures on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "L", "step": 1800 }, { "expr": "sum(increase(prometheus_tsdb_head_series_not_found{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "head_series_not_found on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "E", "step": 1800 }, { "expr": "sum(increase(prometheus_evaluator_iterations_missed_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "evaluator_iterations_missed on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "O", "step": 1800 }, { "expr": "sum(increase(prometheus_evaluator_iterations_skipped_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "evaluator_iterations_skipped on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "P", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Prometheus errors", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 14 }, "id": 55, "panels": [], "repeat": null, "title": "Scrape & rule duration", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "description": "", "editable": true, "error": false, "fill": 1, "grid": {}, "gridPos": { "h": 7, "w": 12, "x": 0, "y": 15 }, "id": 25, "legend": { "alignAsTable": true, "avg": true, "current": true, "max": true, "min": false, "show": false, "sort": "max", "sortDesc": true, "total": false, "values": true }, "lines": true, "linewidth": 2, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "prometheus_target_interval_length_seconds{instance=\"$instance\",quantile=\"0.99\"} - 60", "format": "time_series", "interval": "2m", "intervalFactor": 1, "legendFormat": "{{instance}}", "metric": "", "refId": "A", "step": 300 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Scrape delay (counts with 1m scrape interval)", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "cumulative" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "s", "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 12, "x": 12, "y": 15 }, "id": 14, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "Queue length", "yaxis": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_evaluator_duration_seconds{instance=\"$instance\"}) by (instance, quantile)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Queue length", "metric": "prometheus_local_storage_indexing_queue_length", "refId": "B", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Rule evaulation duration", "tooltip": { "msResolution": false, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": "0", "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 22 }, "id": 56, "panels": [], "repeat": null, "title": "Requests & queries", "type": "row" }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 0, "y": 23 }, "id": 18, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(http_requests_total{instance=\"$instance\"}[$aggregation_interval])) by (instance, handler) > 0", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ handler }} on {{ instance }}", "metric": "", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Request count", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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 } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 6, "y": 23 }, "id": 16, "legend": { "avg": false, "current": false, "hideEmpty": true, "hideZero": true, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "max(sum(http_request_duration_microseconds{instance=\"$instance\"}) by (instance, handler, quantile)) by (instance, handler) > 0", "format": "time_series", "hide": false, "intervalFactor": 2, "legendFormat": "{{ handler }} on {{ instance }}", "refId": "B" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Request duration per handler", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 12, "y": 23 }, "id": 19, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(http_request_size_bytes{instance=\"$instance\", quantile=\"0.99\"}[$aggregation_interval])) by (instance, handler) > 0", "format": "time_series", "hide": false, "intervalFactor": 2, "legendFormat": "{{ handler }} in {{ instance }}", "refId": "B" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Request size by handler", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Allocated bytes": "#F9BA8F", "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max count collector": "#bf1b00", "Max count harvester": "#bf1b00", "Max to persist": "#3F6833", "RSS": "#890F02" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 23 }, "id": 8, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/Max.*/", "fill": 0, "linewidth": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_engine_queries{instance=\"$instance\"}) by (instance, handler)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Current count ", "metric": "last", "refId": "A", "step": 1800 }, { "expr": "sum(prometheus_engine_queries_concurrent_max{instance=\"$instance\"}) by (instance, handler)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Max count", "metric": "last", "refId": "B", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Cont of concurent queries", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 30 }, "id": 57, "panels": [], "repeat": null, "title": "Alerting", "type": "row" }, { "aliasColors": { "Alert queue capacity on o collector": "#bf1b00", "Alert queue capacity on o harvester": "#bf1b00", "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 31 }, "id": 20, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/.*capacity.*/", "fill": 0, "linewidth": 2 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_notifications_queue_capacity{instance=\"$instance\"})by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Alert queue capacity ", "metric": "prometheus_local_storage_checkpoint_last_size_bytes", "refId": "A", "step": 1800 }, { "expr": "sum(prometheus_notifications_queue_length{instance=\"$instance\"})by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Alert queue size on ", "metric": "prometheus_local_storage_checkpoint_last_size_bytes", "refId": "B", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Alert queue size", "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 8, "y": 31 }, "id": 21, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_notifications_alertmanagers_discovered{instance=\"$instance\"}) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Checkpoint chunks written/s", "metric": "prometheus_local_storage_checkpoint_series_chunks_written_sum", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Count of discovered alertmanagers", "tooltip": { "msResolution": false, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 16, "y": 31 }, "id": 39, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(prometheus_notifications_dropped_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "notifications_dropped on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "F", "step": 1800 }, { "expr": "sum(increase(prometheus_rule_evaluation_failures_total{rule_type=\"alerting\",instance=\"$instance\"}[$aggregation_interval])) by (rule_type,instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "rule_evaluation_failures on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Alerting errors", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 38 }, "id": 58, "panels": [], "repeat": null, "title": "Service discovery", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 0, "y": 39 }, "id": 45, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "increase(prometheus_target_sync_length_seconds_count{scrape_job=\"kubernetes-service-endpoints\"}[$aggregation_interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "Count of target synces", "refId": "A", "step": 240 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Kubernetes SD sync count", "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": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 6, "y": 39 }, "id": 46, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(prometheus_target_scrapes_exceeded_sample_limit_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "exceeded_sample_limit on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "A", "step": 1800 }, { "expr": "sum(increase(prometheus_sd_file_read_errors_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "interval": "", "intervalFactor": 2, "legendFormat": "sd_file_read_error on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "E", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Service discovery errors", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 46 }, "id": 59, "panels": [], "repeat": null, "title": "TSDB stats", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 0, "y": 47 }, "id": 36, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(prometheus_tsdb_reloads_total{instance=\"$instance\"}[30m])) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ instance }}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Reloaded block from disk", "tooltip": { "shared": true, "sort": 2, "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": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 6, "y": 47 }, "id": 5, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_tsdb_blocks_loaded{instance=\"$instance\"}) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "Loaded data blocks", "metric": "prometheus_local_storage_memory_chunkdescs", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Loaded data blocks", "tooltip": { "msResolution": false, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 12, "y": 47 }, "id": 3, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "prometheus_tsdb_head_series{instance=\"$instance\"}", "format": "time_series", "intervalFactor": 2, "legendFormat": "Time series count", "metric": "prometheus_local_storage_memory_series", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Time series total count", "tooltip": { "msResolution": false, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 47 }, "id": 1, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(prometheus_tsdb_head_samples_appended_total{instance=\"$instance\"}[$aggregation_interval])) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "samples/s {{instance}}", "metric": "prometheus_local_storage_ingested_samples_total", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Samples Appended per second", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": "", "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 54 }, "id": 60, "panels": [], "repeat": null, "title": "Head block stats", "type": "row" }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833", "To persist": "#9AC48A" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 55 }, "id": 2, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/Max.*/", "fill": 0 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_tsdb_head_chunks{instance=\"$instance\"}) by (instance)", "format": "time_series", "hide": false, "intervalFactor": 2, "legendFormat": "Head chunk count", "metric": "prometheus_local_storage_memory_chunks", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Head chunks count", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 8, "y": 55 }, "id": 35, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "max(prometheus_tsdb_head_max_time{instance=\"$instance\"}) by (instance) - min(prometheus_tsdb_head_min_time{instance=\"$instance\"}) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ instance }}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Length of head block", "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 } ] }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 16, "y": 55 }, "id": 4, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(prometheus_tsdb_head_chunks_created_total{instance=\"$instance\"}[$aggregation_interval])) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "created on {{ instance }}", "refId": "B" }, { "expr": "sum(rate(prometheus_tsdb_head_chunks_removed_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) * -1", "format": "time_series", "intervalFactor": 2, "legendFormat": "deleted on {{ instance }}", "refId": "C" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Head Chunks Created/Deleted per second", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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 } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 62 }, "id": 61, "panels": [], "repeat": null, "title": "Data maintenance", "type": "row" }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 0, "y": 63 }, "id": 33, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(prometheus_tsdb_compaction_duration_sum{instance=\"$instance\"}[30m]) / increase(prometheus_tsdb_compaction_duration_count{instance=\"$instance\"}[30m])) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ instance }}", "refId": "B" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Compaction duration", "tooltip": { "shared": true, "sort": 2, "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_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 6, "y": 63 }, "id": 34, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_tsdb_head_gc_duration_seconds{instance=\"$instance\"}) by (instance, quantile)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ quantile }} on {{ instance }}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Go Garbage collection duration", "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_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 12, "y": 63 }, "id": 37, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(prometheus_tsdb_wal_truncate_duration_seconds{instance=\"$instance\"}) by (instance, quantile)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ quantile }} on {{ instance }}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "WAL truncate duration seconds", "tooltip": { "shared": true, "sort": 2, "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_PROMETHEUS}", "fill": 1, "gridPos": { "h": 7, "w": 6, "x": 18, "y": 63 }, "id": 38, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "connected", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(tsdb_wal_fsync_duration_seconds{instance=\"$instance\"}) by (instance, quantile)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{ quantile }} {{ instance }}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "WAL fsync duration seconds", "tooltip": { "shared": true, "sort": 2, "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 } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 70 }, "id": 62, "panels": [], "repeat": null, "title": "RAM&CPU", "type": "row" }, { "aliasColors": { "Allocated bytes": "#7EB26D", "Allocated bytes - 1m max": "#BF1B00", "Allocated bytes - 1m min": "#BF1B00", "Allocated bytes - 5m max": "#BF1B00", "Allocated bytes - 5m min": "#BF1B00", "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833", "RSS": "#447EBC" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": null, "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 0, "y": 71 }, "id": 6, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [ { "alias": "/-/", "fill": 0 }, { "alias": "collector heap size", "color": "#E0752D", "fill": 0, "linewidth": 2 }, { "alias": "collector kubernetes memory limit", "color": "#BF1B00", "fill": 0, "linewidth": 3 } ], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(process_resident_memory_bytes{instance=\"$instance\"}) by (instance)", "format": "time_series", "hide": false, "intervalFactor": 2, "legendFormat": "Total resident memory - {{instance}}", "metric": "process_resident_memory_bytes", "refId": "B", "step": 1800 }, { "expr": "sum(go_memstats_alloc_bytes{instance=\"$instance\"}) by (instance)", "format": "time_series", "hide": false, "intervalFactor": 2, "legendFormat": "Total llocated bytes - {{instance}}", "metric": "go_memstats_alloc_bytes", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Memory", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "aliasColors": { "Allocated bytes": "#F9BA8F", "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833", "RSS": "#890F02" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 8, "y": 71 }, "id": 7, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "rate(go_memstats_alloc_bytes_total{instance=\"$instance\"}[$aggregation_interval])", "format": "time_series", "intervalFactor": 2, "legendFormat": "Allocated Bytes/s", "metric": "go_memstats_alloc_bytes", "refId": "A", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Allocations per second", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "decimals": 2, "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 8, "x": 16, "y": 71 }, "id": 9, "legend": { "alignAsTable": false, "avg": false, "current": false, "hideEmpty": false, "max": false, "min": false, "rightSide": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(rate(process_cpu_seconds_total{instance=\"$instance\"}[$aggregation_interval])) by (instance)", "format": "time_series", "intervalFactor": 2, "legendFormat": "CPU/s", "metric": "prometheus_local_storage_ingested_samples_total", "refId": "B", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "CPU per second", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [ "avg" ] }, "yaxes": [ { "format": "none", "label": null, "logBase": 1, "max": null, "min": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] }, { "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 78 }, "id": 63, "panels": [], "repeat": null, "title": "Contrac errors", "type": "row" }, { "aliasColors": { "Chunks": "#1F78C1", "Chunks to persist": "#508642", "Max chunks": "#052B51", "Max to persist": "#3F6833" }, "bars": false, "dashLength": 10, "dashes": false, "datasource": "${DS_PROMETHEUS}", "editable": true, "error": false, "fill": 1, "gridPos": { "h": 7, "w": 24, "x": 0, "y": 79 }, "id": 47, "legend": { "avg": false, "current": false, "max": false, "min": false, "show": false, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "options": {}, "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum(increase(net_conntrack_dialer_conn_failed_total{instance=\"$instance\"}[$aggregation_interval])) by (instance) > 0", "format": "time_series", "hide": false, "interval": "", "intervalFactor": 2, "legendFormat": "conntrack_dialer_conn_failed on {{ instance }}", "metric": "prometheus_local_storage_chunk_ops_total", "refId": "M", "step": 1800 } ], "thresholds": [], "timeFrom": null, "timeShift": null, "title": "Net errors", "tooltip": { "msResolution": false, "shared": true, "sort": 2, "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": "0", "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ] } ], "refresh": "5m", "schemaVersion": 18, "style": "dark", "tags": [ "prometheus" ], "templating": { "list": [ { "auto": true, "auto_count": 30, "auto_min": "2m", "current": { "text": "auto", "value": "$__auto_interval_aggregation_interval" }, "hide": 0, "label": "aggregation intarval", "name": "aggregation_interval", "options": [ { "selected": true, "text": "auto", "value": "$__auto_interval_aggregation_interval" }, { "selected": false, "text": "1m", "value": "1m" }, { "selected": false, "text": "10m", "value": "10m" }, { "selected": false, "text": "30m", "value": "30m" }, { "selected": false, "text": "1h", "value": "1h" }, { "selected": false, "text": "6h", "value": "6h" }, { "selected": false, "text": "12h", "value": "12h" }, { "selected": false, "text": "1d", "value": "1d" }, { "selected": false, "text": "7d", "value": "7d" }, { "selected": false, "text": "14d", "value": "14d" }, { "selected": false, "text": "30d", "value": "30d" } ], "query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d", "refresh": 2, "skipUrlSync": false, "type": "interval" }, { "allValue": null, "current": {}, "datasource": "${DS_PROMETHEUS}", "definition": "", "hide": 0, "includeAll": false, "label": "Instance", "multi": false, "name": "instance", "options": [], "query": "label_values(prometheus_build_info, instance)", "refresh": 2, "regex": "", "skipUrlSync": false, "sort": 2, "tagValuesQuery": "", "tags": [], "tagsQuery": "", "type": "query", "useTags": false }, { "current": { "text": "prometheus", "value": "prometheus" }, "hide": 0, "includeAll": false, "label": "Prometheus datasource", "multi": false, "name": "DS_PROMETHEUS", "options": [], "query": "prometheus", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" }, { "current": { "text": "No data sources found", "value": "" }, "hide": 0, "includeAll": false, "label": "InfluxDB datasource", "multi": false, "name": "influx_datasource", "options": [], "query": "influxdb", "refresh": 1, "regex": "", "skipUrlSync": false, "type": "datasource" } ] }, "time": { "from": "now-1h", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "browser", "title": "Prometheus2.0 (v1.0.0 by FUSAKLA)", "version": 1 } ... ================================================ FILE: values_overrides/grafana/sqlite3.yaml ================================================ --- dependencies: static: grafana: jobs: null services: null manifests: job_db_init: false job_db_init_session: false job_db_session_sync: false job_image_repo_sync: true job_run_migrator: false job_set_admin_user: false secret_db: false secret_db_session: false conf: grafana: database: type: sqlite3 path: /var/lib/grafana/data/sqlite3.db session: provider: file provider_config: sessions ... ================================================ FILE: values_overrides/grafana/tls.yaml ================================================ --- conf: grafana: database: ssl_mode: true ca_cert_path: /etc/mysql/certs/ca.crt client_key_path: /etc/mysql/certs/tls.key client_cert_path: /etc/mysql/certs/tls.crt provisioning: datasources: template: | {{ $prom_host := tuple "monitoring" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" }} {{ $prom_uri := printf "https://%s" $prom_host }} apiVersion: 1 datasources: - name: prometheus type: prometheus access: proxy orgId: 1 editable: true basicAuth: true basicAuthUser: {{ .Values.endpoints.monitoring.auth.user.username }} jsonData: tlsAuthWithCACert: true secureJsonData: basicAuthPassword: {{ .Values.endpoints.monitoring.auth.user.password }} tlsCACert: $CACERT url: {{ $prom_uri }} endpoints: grafana: host_fqdn_override: default: tls: issuerRef: name: ca-issuer kind: ClusterIssuer manifests: certificates: true ... ================================================ FILE: values_overrides/heat/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" heat_db_sync: "quay.io/airshipit/heat:2024.2-ubuntu_jammy" heat_api: "quay.io/airshipit/heat:2024.2-ubuntu_jammy" heat_cfn: "quay.io/airshipit/heat:2024.2-ubuntu_jammy" heat_engine: "quay.io/airshipit/heat:2024.2-ubuntu_jammy" heat_engine_cleaner: "quay.io/airshipit/heat:2024.2-ubuntu_jammy" heat_purge_deleted: "quay.io/airshipit/heat:2024.2-ubuntu_jammy" ... ================================================ FILE: values_overrides/heat/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" heat_db_sync: "quay.io/airshipit/heat:2025.1-ubuntu_jammy" heat_api: "quay.io/airshipit/heat:2025.1-ubuntu_jammy" heat_cfn: "quay.io/airshipit/heat:2025.1-ubuntu_jammy" heat_engine: "quay.io/airshipit/heat:2025.1-ubuntu_jammy" heat_engine_cleaner: "quay.io/airshipit/heat:2025.1-ubuntu_jammy" heat_purge_deleted: "quay.io/airshipit/heat:2025.1-ubuntu_jammy" ... ================================================ FILE: values_overrides/heat/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" heat_db_sync: "quay.io/airshipit/heat:2025.1-ubuntu_noble" heat_api: "quay.io/airshipit/heat:2025.1-ubuntu_noble" heat_cfn: "quay.io/airshipit/heat:2025.1-ubuntu_noble" heat_engine: "quay.io/airshipit/heat:2025.1-ubuntu_noble" heat_engine_cleaner: "quay.io/airshipit/heat:2025.1-ubuntu_noble" heat_purge_deleted: "quay.io/airshipit/heat:2025.1-ubuntu_noble" ... ================================================ FILE: values_overrides/heat/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" heat_db_sync: "quay.io/airshipit/heat:2025.2-ubuntu_noble" heat_api: "quay.io/airshipit/heat:2025.2-ubuntu_noble" heat_cfn: "quay.io/airshipit/heat:2025.2-ubuntu_noble" heat_engine: "quay.io/airshipit/heat:2025.2-ubuntu_noble" heat_engine_cleaner: "quay.io/airshipit/heat:2025.2-ubuntu_noble" heat_purge_deleted: "quay.io/airshipit/heat:2025.2-ubuntu_noble" ... ================================================ FILE: values_overrides/heat/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" heat_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: heat: custom.tld/key: "value" tls: orchestration_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/heat/apparmor.yaml ================================================ --- pod: security_context: heat: container: heat_api: appArmorProfile: type: RuntimeDefault heat_cfn: appArmorProfile: type: RuntimeDefault heat_engine: appArmorProfile: type: RuntimeDefault engine_cleaner: container: heat_engine_cleaner: appArmorProfile: type: RuntimeDefault ks_user: container: heat_ks_domain_user: appArmorProfile: type: RuntimeDefault trusts: container: heat_trusts: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/heat/gateway.yaml ================================================ # Gateway API overrides for Heat. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: orchestration: host_fqdn_override: public: host: heat.openstack-helm.org cloudformation: host_fqdn_override: public: host: cloudformation.openstack-helm.org manifests: ingress_api: false ingress_cfn: false service_ingress_api: false service_ingress_cfn: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: heat-api-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.orchestration.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: heat-api port: 8004 - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: heat-cfn-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.cloudformation.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: heat-cfn port: 8000 ... ================================================ FILE: values_overrides/heat/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" db_init: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" ks_service: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" heat_db_sync: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" heat_api: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" heat_cfn: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" heat_engine: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" heat_engine_cleaner: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" heat_purge_deleted: "quay.io/airshipit/heat:2025.1-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/heat/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" db_init: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" ks_service: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" heat_db_sync: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" heat_api: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" heat_cfn: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" heat_engine: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" heat_engine_cleaner: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" heat_purge_deleted: "quay.io/airshipit/heat:2025.2-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/heat/mariadb-operator.yaml ================================================ --- conf: heat: database: connection: null manifests: job_db_init: false etcSources: heat_api: - heat-db-conn heat_db_sync: - heat-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: heat namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: heat namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: heat-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: heat-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "heat" table: "*" username: heat grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: heat-db-conn spec: mariaDbRef: name: mariadb username: heat passwordSecretKeyRef: name: heat-db-password key: password database: heat secretName: heat-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/heat/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: heat: ingress: - from: - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: ingress - podSelector: matchLabels: application: horizon ports: - protocol: TCP port: 8000 - protocol: TCP port: 8003 - protocol: TCP port: 8004 egress: - to: - podSelector: matchLabels: application: neutron - to: - podSelector: matchLabels: application: nova - to: - podSelector: matchLabels: application: glance - to: - podSelector: matchLabels: application: cinder - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/heat/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: heat: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # heat: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/heat/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt heat: cacert: /etc/ssl/certs/openstack-helm.crt heat_trustee: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/heat/tls.yaml ================================================ --- conf: software: apache2: binary: apache2 start_parameters: -DFOREGROUND site_dir: /etc/apache2/sites-enabled conf_dir: /etc/apache2/conf-enabled mods_dir: /etc/apache2/mods-available a2enmod: - ssl a2dismod: null mpm_event: | ServerLimit 1024 StartServers 32 MinSpareThreads 32 MaxSpareThreads 256 ThreadsPerChild 25 MaxRequestsPerChild 128 ThreadLimit 720 wsgi_heat: | {{- $portInt := tuple "orchestration" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen {{ $portInt }} Require all granted ServerName {{ printf "%s.%s.svc.%s" "heat-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} WSGIDaemonProcess heat-api processes=1 threads=1 user=heat display-name=%{GROUP} WSGIProcessGroup heat-api WSGIScriptAlias / /var/lib/openstack/bin/heat-wsgi-api WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On AllowEncodedSlashes On SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded SSLEngine on SSLCertificateFile /etc/heat/certs/tls.crt SSLCertificateKeyFile /etc/heat/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on wsgi_cfn: | {{- $portInt := tuple "cloudformation" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen {{ $portInt }} Require all granted ServerName {{ printf "%s.%s.svc.%s" "heat-api-cfn" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} WSGIDaemonProcess heat-api-cfn processes=1 threads=1 user=heat display-name=%{GROUP} WSGIProcessGroup heat-api-cfn WSGIScriptAlias / /var/lib/openstack/bin/heat-wsgi-api-cfn WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On AllowEncodedSlashes On SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded SSLEngine on SSLCertificateFile /etc/heat/certs/tls.crt SSLCertificateKeyFile /etc/heat/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on heat: clients_neutron: ca_file: /etc/heat/certs/ca.crt clients_cinder: ca_file: /etc/heat/certs/ca.crt clients_glance: ca_file: /etc/heat/certs/ca.crt clients_nova: ca_file: /etc/heat/certs/ca.crt clients_swift: ca_file: /etc/heat/certs/ca.crt ssl: ca_file: /etc/heat/certs/ca.crt keystone_authtoken: cafile: /etc/heat/certs/ca.crt clients: ca_file: /etc/heat/certs/ca.crt clients_keystone: ca_file: /etc/heat/certs/ca.crt oslo_messaging_rabbit: ssl: true ssl_ca_file: /etc/rabbitmq/certs/ca.crt ssl_cert_file: /etc/rabbitmq/certs/tls.crt ssl_key_file: /etc/rabbitmq/certs/tls.key network: api: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" cfn: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" pod: security_context: heat: container: heat_api: readOnlyRootFilesystem: false runAsUser: 0 heat_cfn: readOnlyRootFilesystem: false runAsUser: 0 endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt heat: cacert: /etc/ssl/certs/openstack-helm.crt heat_trustee: cacert: /etc/ssl/certs/openstack-helm.crt heat_stack_user: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt scheme: default: https port: api: default: 443 orchestration: host_fqdn_override: default: tls: secretName: heat-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https service: https port: api: public: 443 cloudformation: host_fqdn_override: default: tls: secretName: heat-tls-cfn issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https service: https port: api: public: 443 ingress: port: ingress: default: 443 oslo_messaging: port: https: default: 15680 manifests: certificates: true ... ================================================ FILE: values_overrides/horizon/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: db_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy horizon_db_sync: quay.io/airshipit/horizon:2024.2-ubuntu_jammy horizon: quay.io/airshipit/horizon:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/horizon/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy horizon_db_sync: quay.io/airshipit/horizon:2025.1-ubuntu_jammy horizon: quay.io/airshipit/horizon:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/horizon/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble horizon_db_sync: quay.io/airshipit/horizon:2025.1-ubuntu_noble horizon: quay.io/airshipit/horizon:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/horizon/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble horizon_db_sync: quay.io/airshipit/horizon:2025.2-ubuntu_noble horizon: quay.io/airshipit/horizon:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/horizon/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" horizon: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: horizon: custom.tld/key: "value" tls: dashboard_dashboard_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/horizon/apparmor.yaml ================================================ --- pod: security_context: horizon: container: horizon: appArmorProfile: type: RuntimeDefault db_sync: container: horizon_db_sync: appArmorProfile: type: RuntimeDefault test: container: horizon_test: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/horizon/gateway.yaml ================================================ # Gateway API overrides for Horizon. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: dashboard: host_fqdn_override: public: host: horizon.openstack-helm.org manifests: ingress_api: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: horizon-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.dashboard.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: horizon-int port: 80 ... ================================================ FILE: values_overrides/horizon/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci horizon_db_sync: quay.io/airshipit/horizon:2025.1-ubuntu_noble_loci horizon: quay.io/airshipit/horizon:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/horizon/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci horizon_db_sync: quay.io/airshipit/horizon:2025.2-ubuntu_noble_loci horizon: quay.io/airshipit/horizon:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/horizon/logo.yaml ================================================ --- manifests: configmap_logo: true conf: horizon: branding: favicon: | AAABAAMAMDAAAAEAIACoJQAANgAAACAgAgABAAEAMAEAAN4lAAAQEAIAAQABALAAAAAOJwAAKAAA ADAAAABgAAAAAQAgAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAQxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f8AAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAEMY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAEMY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MX7ZlDF+2ZQxftmUMX7ZlDF+2ZQxftmUMX7ZlDF+2ZQxftmUMX7ZlDF+2ZAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDF+2ZQxftmUMX7ZlD F+2ZQxftmUMX7ZlDF+2ZQxftmUMX7ZlDF+2ZQxftmQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABD GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMX7ZlDF+2ZQxftmUMX7ZlDF+2ZQxftmUMX7ZlDF+2Z QxftmUMX7ZlDF+2ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AABDF+2ZQxftmUMX7ZlDF+2ZQxftmUMX7ZlDF+2ZQxftmUMX7ZlDF+2ZQxftmUMY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/wAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/wAAAABDGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY 7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/AAAAAAAAAAAAAAAAQxjt/0MY7f9DGO3/Qxjt /0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/ Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9D GO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f9DGO3/Qxjt/0MY7f8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAP///////wAAwAAAAAADAACAAAAAAAEAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8AAA AAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAA////////AAD///////8AAP///////wAA AB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAAH///+AAAAAAf///4AAAAAB////gAAAAA H///+AAAAAAf///4AAAAAB////gAAAD///////8AAP///////wAA////////AAAAH///+AAAAAAf ///4AAAAAB////gAAAAAH///+AAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAQAAwAAAAAADAAD///// //8AACgAAAAgAAAAQAAAAAEAAQAAAAAAgAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAQxjtAD////x/ ///+/////////////////////////////////gAAf/4AAH8AAAAAAAAAAP4AAH/+AAB//gAAf/4A AH/+AAB//gAAf/4AAH/+AAB/AAAAAAAAAAD+AAB//gAAf/////////////////////////////// /3////4////8wAAAA4AAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//+AAf//gP////////// Af//gAH//4AB//+AAf//gAH//4AB//+AAf//gAH//4D//////////wH//4AB//+AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAgAAAAcAAAAMoAAAAEAAAACAAAAABAAEAAAAAAEAAAAAAAAAAAAAAAAIA AAAAAAAAAAAAAEMY7QB//gAA//8AAP//AAD//wAA8A8AAAAAAADwDwAA8A8AAPAPAADwDwAAAAAA APAPAAD//wAA//8AAP//AAB//gAAgAEAAAAAAAAAAAAAAAAAAA/wAAD//wAAD/AAAA/wAAAP8AAA D/AAAP//AAAP8AAAAAAAAAAAAAAAAAAAgAEAAA== logo: | PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxz dmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMj IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeG1sbnM6 Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJs Lm9yZy9kYy9lbGVtZW50cy8xLjEvIiB2aWV3Qm94PSIwIDAgNjAwLjc3NTg5IDEwNi43MzczNyI+ CiA8ZGVmcz4KICA8Y2xpcFBhdGggaWQ9ImEiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNl Ij4KICAgPHBhdGggZD0ibTAgNjEyaDc5MnYtNjEyaC03OTJ2NjEyeiIvPgogIDwvY2xpcFBhdGg+ CiA8L2RlZnM+CiA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzMuODk4IC01My4yNzkpIj4KICA8 ZyB0cmFuc2Zvcm09Im1hdHJpeCgxLjI1IDAgMCAtMS4yNSAtMTYwLjE0IDQ5MC42OSkiPgogICA8 ZyBjbGlwLXBhdGg9InVybCgjYSkiPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjM0LjM3 IDM0OS45MykiPgogICAgIDxwYXRoIGQ9Im0wIDBoLTcxLjAzNmMtNC40NTggMC04LjEwNi0zLjY0 OC04LjEwNi04LjEwN3YtMTkuMTAyaDE5LjcwM3YzLjEyMWMwIDIuNDIyIDEuOTYzIDQuMzg1IDQu Mzg1IDQuMzg1aDM5LjA3M2MyLjQyMSAwIDQuMzg0LTEuOTYzIDQuMzg0LTQuMzg1di0zLjEyMWgx OS43MDR2MTkuMTAyYzAgNC40NTktMy42NDggOC4xMDctOC4xMDcgOC4xMDciIGZpbGw9IiNkYTFh MzEiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIyMi43NyAyODguNjMp Ij4KICAgICA8cGF0aCBkPSJtMCAwYzAtMi40MjItMS45NjMtNC4zODUtNC4zODUtNC4zODVoLTM5 LjA3MmMtMi40MjIgMC00LjM4NSAxLjk2My00LjM4NSA0LjM4NXYzLjEyMWgtMTkuNzAzdi0xOS4x MDNjMC00LjQ1OCAzLjY0OC04LjEwNiA4LjEwNi04LjEwNmg3MS4wMzZjNC40NTkgMCA4LjEwNiAz LjY0OCA4LjEwNiA4LjEwNnYxOS4xMDNoLTE5LjcwM3YtMy4xMjF6IiBmaWxsPSIjZGExYTMxIi8+ CiAgICA8L2c+CiAgICA8cGF0aCBkPSJtMTc0LjkzIDMxNy4wOWgtMTkuNzAzdi0xOS43MDNoMTku NzAzdjE5LjcwM3oiIGZpbGw9IiNkYTFhMzEiLz4KICAgIDxwYXRoIGQ9Im0yNDIuNDggMzE3LjA5 aC0xOS43MDN2LTE5LjcwM2gxOS43MDN2MTkuNzAzeiIgZmlsbD0iI2RhMWEzMSIvPgogICAgPGcg dHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjMwLjMxIDI4Ni41KSI+CiAgICAgPHBhdGggZD0ibTAgMGMt Mi4zMDUgMC00LjE4MSAxLjg3NS00LjE4MSA0LjE4MSAwIDIuMzA1IDEuODc2IDQuMTggNC4xODEg NC4xOHM0LjE4MS0xLjg3NSA0LjE4MS00LjE4YzAtMi4zMDYtMS44NzYtNC4xODEtNC4xODEtNC4x ODFtNS41NDMgNC4xODFjMCAzLjA1Ni0yLjQ4NyA1LjU0Mi01LjU0MyA1LjU0MnMtNS41NDMtMi40 ODYtNS41NDMtNS41NDJjMC0zLjA1NyAyLjQ4Ny01LjU0MyA1LjU0My01LjU0M3M1LjU0MyAyLjQ4 NiA1LjU0MyA1LjU0MyIgZmlsbD0iIzRlNDY0MCIvPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3Jt PSJ0cmFuc2xhdGUoNjMxLjI1IDI5MS42NikiPgogICAgIDxwYXRoIGQ9Im0wIDBjMC0wLjQ4OS0w LjMxLTAuODE1LTAuODg1LTAuODE1aC0wLjgzdjEuNjM4aDAuODA3YzAuNTc1IDAgMC45MDgtMC4y NzIgMC45MDgtMC44MTV2LTAuMDA4em0xLjEzMyAwLjAzMXYwLjAzMWMwIDAuNTM2LTAuMTYzIDAu OTYyLTAuNDU4IDEuMjU3LTAuMzQyIDAuMzQyLTAuODQ1IDAuNTItMS40NzQgMC41MmgtMi4wNHYt NS40MzFoMS4xMjR2MS43ODRoMC43MDZsMS4wMDEtMS43ODRoMS4yODhsLTEuMTU2IDIuMDE3YzAu NTk4IDAuMjY0IDEuMDA5IDAuNzg0IDEuMDA5IDEuNjA2IiBmaWxsPSIjNGU0NjQwIi8+CiAgICA8 L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzEuNjIgMzA3LjAyKSI+CiAgICAgPHBh dGggZD0ibTAgMHYwLjUwMWMwIDguMjcgNC4yNiAxNC4zNjYgMTAuODU4IDE0LjM2NiA2LjQzMSAw IDExLjAyNS02LjE4MSAxMS4wMjUtMTQuNDQ5di0wLjUwMWMwLTguMjY5LTQuMjYtMTQuNDQ5LTEw Ljg1OC0xNC40NDktNi40MzIgMC0xMS4wMjUgNi4yNjQtMTEuMDI1IDE0LjUzMm0zMS4zMi0wLjE2 NnYwLjc1MmMwIDEzLjExMy04LjYwMiAyMi42MzQtMjAuMjk1IDIyLjYzNC0xMS43NzcgMC0yMC40 NjMtOS42ODktMjAuNDYzLTIyLjcxOXYtMC43NTFjMC0xMy4xMTMgOC42MDMtMjIuNTUxIDIwLjI5 Ni0yMi41NTEgMTEuNzc2IDAgMjAuNDYyIDkuNjA1IDIwLjQ2MiAyMi42MzUiIGZpbGw9IiM0ZTQ2 NDAiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxNy41NSAzMDYuODYp Ij4KICAgICA8cGF0aCBkPSJtMCAwdjAuODM1YzAgOC42ODYgNC44NDUgMTQuMTk4IDEwLjUyMyAx NC4xOTggNS42OCAwIDEwLjI3NC01LjQyOSAxMC4yNzQtMTQuMjgxdi0wLjc1MmMwLTguODU0LTQu NTExLTE0LjE5OS0xMC4yNzQtMTQuMTk5LTUuNjc4IDAtMTAuNTIzIDUuNTEzLTEwLjUyMyAxNC4x OTltMzAuMzE5LTAuMTY4djEuMTdjMCAxNC45NTEtOC4zNTMgMjIuMzg0LTE3LjIwNiAyMi4zODQt Ni4zNDggMC0xMC4xOS0zLjY3NS0xMi45NDYtNy45MzV2Ny4xaC05LjQzOHYtNTYuODc5aDkuNDM4 djE5LjI5NGMyLjY3My0zLjkyNSA2LjUxNS03LjUxNyAxMi45NDYtNy41MTcgOC45MzYgMCAxNy4y MDYgNy41MTcgMTcuMjA2IDIyLjM4MyIgZmlsbD0iIzRlNDY0MCIvPgogICAgPC9nPgogICAgPGcg dHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzcxLjg5IDMyMi4zMSkiPgogICAgIDxwYXRoIGQ9Im0wIDBj NS41MTMgMCA4LjY4Ni01LjA5NCA5LjE4OC0xMi4xMWgtMTguNzA5YzAuNjY4IDcuNTE3IDQuMzQz IDEyLjExIDkuNTIxIDEyLjExbTE2Ljg3MS0zMS4yMzctNC45MjggNS44NDhjLTIuOTIzLTIuODQt Ni4wMTMtNC42NzgtMTAuMTg5LTQuNjc4LTUuNzYzIDAtMTAuMzU3IDQuMDA5LTExLjE5MiAxMS40 NDJoMjcuNzI5YzAuMDgzIDEuMzM2IDAuMDgzIDIuNjc0IDAuMDgzIDMuMjU4IDAgMTMuMjc5LTYu MzQ3IDIzLjMwMy0xOC4zNzQgMjMuMzAzLTEwLjg1OCAwLTE4Ljg3Ni05LjUyMi0xOC44NzYtMjIu ODAzdi0wLjY2N2MwLTEzLjg2NSA4Ljg1My0yMi41NTEgMjAuMjEzLTIyLjU1MSA2LjU5OCAwIDEx LjUyNiAyLjU4OSAxNS41MzQgNi44NDgiIGZpbGw9IiM0ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxn IHRyYW5zZm9ybT0idHJhbnNsYXRlKDQxNy45OCAzMzAuMjQpIj4KICAgICA8cGF0aCBkPSJtMCAw Yy02LjAxMyAwLTkuNjA1LTMuNDI1LTEyLjExMS03LjM1djYuNTE1aC05LjQzOHYtNDQuMjY3aDku NDM4djI2LjgxYzAgNi4wOTcgMy40MjUgOS43NzIgOC4zNTMgOS43NzIgNS4wMTEgMCA3LjkzNC0z LjQyMyA3LjkzNC05LjYwNHYtMjYuOTc4aDkuNDM4djI5LjY1YzAgOS40MzgtNS4wOTUgMTUuNDUy LTEzLjYxNCAxNS40NTIiIGZpbGw9IiM0ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9y bT0idHJhbnNsYXRlKDQ2OS42NCAyOTcuNzUpIj4KICAgICA8cGF0aCBkPSJtMCAwdjAuMDgzYzAg Ni45MzMtNS4xNzkgMTAuMTA1LTEyLjAyNyAxMy4xOTYtNS4xNzkgMi4zMzktOC42ODYgMy44NDIt OC42ODYgNi43NjV2MC4xNjhjMCAyLjQyMiAyLjA4NyA0LjM0MiA1LjU5NSA0LjM0MnM3LjE4My0x LjY3IDEwLjUyNC0zLjkyNWw0LjAwOSA2LjkzM2MtNC4xNzYgMy4wMDYtOS40MzggNC43Ni0xNC4z NjYgNC43Ni04LjI2OCAwLTE0LjYxNi01LjAxMS0xNC42MTYtMTIuOTQ1di0wLjE2OGMwLTcuMjY2 IDUuNTEzLTEwLjI3MyAxMi4xMTEtMTMuMTEyIDUuMjYxLTIuMjU2IDguNjg2LTMuNjc1IDguNjg2 LTYuODQ5di0wLjA4M2MwLTIuNzU3LTIuMjU1LTQuODQ1LTYuMTgxLTQuODQ1LTMuOTI1IDAtOC4x ODUgMS45MjItMTIuMTkzIDUuMTc4bC00LjQyNy02Ljc2NWM1LjA5NS00LjI1OSAxMS4xOTItNi4x OCAxNi40NTMtNi4xOCA4LjUyIDAgMTUuMTE4IDQuNzYxIDE1LjExOCAxMy40NDciIGZpbGw9IiM0 ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ5OC44NiAyODYu NCkiPgogICAgIDxwYXRoIGQ9Im0wIDB2Ny43NjhjLTEuNTg3LTAuODM2LTMuMjU4LTEuMjUzLTUu MDk1LTEuMjUzLTMuMDA3IDAtNC43NjEgMS40MTktNC43NjEgNC44NDR2MjMuNTUzaDkuOTM5djgu MTAyaC05LjkzOXYxMS45NDNoLTkuNDM4di0xMS45NDNoLTQuODQ0bDEuNTUtOC4xMDJoMy4yOTR2 LTI1LjQ3NGMwLTguNjAzIDQuOTI4LTExLjM1OSAxMS40NDMtMTEuMzU5IDMuMTc0IDAgNS42Nzkg MC43NTEgNy44NTEgMS45MjEiIGZpbGw9IiM0ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5z Zm9ybT0idHJhbnNsYXRlKDUzMC4zNSAzMDAuMDEpIj4KICAgICA8cGF0aCBkPSJtMCAwYzAtNS4w MTEtNC4xNzYtOC42ODYtOS42MDUtOC42MDMtNC4wOTIgMC4wODMtNy4xODIgMi41OS03LjE4MiA3 LjAxNnYwLjE2OGMwIDQuNjc2IDMuMTczIDcuNDMzIDguNjAyIDcuNDMzIDMuMTc0IDAgNi4wMTQt MC42NjkgOC4xODUtMS41ODd2LTQuNDI3em00LjY3NyAyNS4zOTFjLTIuODM5IDIuOTIzLTcuMjY2 IDQuNTEtMTMuMDI5IDQuNTEtNS45MyAwLTEwLjM1Ny0xLjQyMS0xNC42MTctMy41MDlsMi42NzMt Ny41MTZjMi45MjQgMS4zMzYgNi40MzIgMi42NzMgMTAuNjkxIDIuNjczIDYuMDE0IDAgOS41MjIt My4wOTEgOS41MjItOS4wMnYtMS44MzhjLTMuMDA3IDEuMDAzLTYuMDE0IDEuNzUzLTEwLjE5IDEu NzUzLTkuMzU0IDAtMTUuNzAyLTQuNjc2LTE1LjcwMi0xNC4xOTh2LTAuNDE3YzAtOC42MDMgNi4x ODEtMTMuNTMxIDEzLjUzMS0xMy41MzEgNS43NjMgMCA5LjY4OCAyLjUwNiAxMi4yNzcgNi4yNjR2 LTUuNDI5aDkuMjcxdjI3LjQ3OWMwIDUuNTEyLTEuNTA0IDkuODU2LTQuNDI3IDEyLjc3OSIgZmls bD0iIzRlNDY0MCIvPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTc5LjU3 IDI5MC45MSkiPgogICAgIDxwYXRoIGQ9Im0wIDAtNS4wOTQgNi4yNjRjLTIuNTktMi41ODktNS4x NzktNC41MS05LjAyMS00LjUxLTYuNDMxIDAtMTAuOTQxIDUuNzYzLTEwLjk0MSAxNC4zNjV2MC40 MThjMCA4LjM1MyA0LjUxIDE0LjI4MiAxMC42OTEgMTQuMjgyIDQuMDA5IDAgNi41OTgtMi4wMDQg OC45MzYtNC40MjdsNS4yNjMgNi45MzNjLTMuNjc1IDMuNjc1LTcuODUyIDYuMDE0LTE0LjE5OSA2 LjAxNC0xMS42MSAwLTIwLjIxMy05LjUyMS0yMC4yMTMtMjIuNzE5di0wLjgzNWMwLTEzLjE5NiA4 LjM1My0yMi40NjYgMTkuODc5LTIyLjQ2NiA2Ljc2NSAwIDExLjE5MSAyLjc1NSAxNC42OTkgNi42 ODEiIGZpbGw9IiM0ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRl KDYwOC40NiAzMDguMTIpIj4KICAgICA8cGF0aCBkPSJtMCAwLTYuNjI1LTcuMTIxIDguODg2LTE1 Ljg1NGgxMC45NDFsLTEzLjIwMiAyMi45NzV6IiBmaWxsPSIjNGU0NjQwIi8+CiAgICA8L2c+CiAg ICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MTAuMDUgMzI5LjQxKSI+CiAgICAgPHBhdGggZD0i bTAgMC0xNS4xMTctMTkuNDYxdjM1LjQ5N2gtOS40Mzh2LTYwLjMwM2g5LjQzOHYxMi43NzlsMjYu MzA5IDMxLjQ4OGgtMTEuMTkyeiIgZmlsbD0iIzRlNDY0MCIvPgogICAgPC9nPgogICA8L2c+CiAg PC9nPgogPC9nPgo8L3N2Zz4K logo_splash: | PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxz dmcgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMj IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeG1sbnM6 Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJs Lm9yZy9kYy9lbGVtZW50cy8xLjEvIiB2aWV3Qm94PSIwIDAgNTg2LjY1NTc2IDI4My4wOTIxMyI+ CiA8ZGVmcz4KICA8Y2xpcFBhdGggaWQ9ImIiIGNsaXBQYXRoVW5pdHM9InVzZXJTcGFjZU9uVXNl Ij4KICAgPHBhdGggZD0ibTAgNjEyaDc5MnYtNjEyaC03OTJ2NjEyeiIvPgogIDwvY2xpcFBhdGg+ CiAgPGNsaXBQYXRoIGlkPSJhIiBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CiAgIDxw YXRoIGQ9Im0zMzEuMDIgNDI0Ljg3aDExNi4yNHYtMTEzLjc2aC0xMTYuMjR2MTEzLjc2eiIvPgog IDwvY2xpcFBhdGg+CiA8L2RlZnM+CiA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtLjk1Nzg0IC0y LjI0NDcpIj4KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgxLjI1IDAgMCAtMS4yNSAtMjAxLjg2IDUz My4zNCkiPgogICA8ZyBjbGlwLXBhdGg9InVybCgjYikiPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFu c2xhdGUoNjI0LjYyIDIxNS45NikiPgogICAgIDxwYXRoIGQ9Im0wIDBjLTIuODk2IDAtNS4yNTIg Mi4zNTYtNS4yNTIgNS4yNTIgMCAyLjg5NyAyLjM1NiA1LjI1MiA1LjI1MiA1LjI1MnM1LjI1Mi0y LjM1NSA1LjI1Mi01LjI1MmMwLTIuODk2LTIuMzU2LTUuMjUyLTUuMjUyLTUuMjUybTYuOTYzIDUu MjUyYzAgMy44NC0zLjEyMyA2Ljk2NC02Ljk2MyA2Ljk2NHMtNi45NjMtMy4xMjQtNi45NjMtNi45 NjQgMy4xMjMtNi45NjMgNi45NjMtNi45NjMgNi45NjMgMy4xMjMgNi45NjMgNi45NjMiIGZpbGw9 IiM0ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyNS44IDIy Mi40MykiPgogICAgIDxwYXRoIGQ9Im0wIDBjMC0wLjYxNC0wLjM5LTEuMDI0LTEuMTEyLTEuMDI0 aC0xLjA0MnYyLjA1OGgxLjAxM2MwLjcyMiAwIDEuMTQxLTAuMzQyIDEuMTQxLTEuMDI0di0wLjAx em0xLjQyNCAwLjAzOXYwLjAzOWMwIDAuNjczLTAuMjA1IDEuMjA5LTAuNTc2IDEuNTgtMC40Mjkg MC40MjgtMS4wNjIgMC42NTItMS44NTIgMC42NTJoLTIuNTYzdi02LjgyM2gxLjQxM3YyLjI0Mmgw Ljg4NmwxLjI1OC0yLjI0MmgxLjYxOWwtMS40NTMgMi41MzVjMC43NTEgMC4zMzEgMS4yNjggMC45 ODQgMS4yNjggMi4wMTciIGZpbGw9IiM0ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9y bT0idHJhbnNsYXRlKDE3NC4xMSAyNDEuNzQpIj4KICAgICA8cGF0aCBkPSJtMCAwdjAuNjI5YzAg MTAuMzkgNS4zNTIgMTguMDQ4IDEzLjY0MSAxOC4wNDggOC4wNzkgMCAxMy44NTEtNy43NjUgMTMu ODUxLTE4LjE1MnYtMC42M2MwLTEwLjM4Ny01LjM1Mi0xOC4xNTItMTMuNjQxLTE4LjE1Mi04LjA4 IDAtMTMuODUxIDcuODY5LTEzLjg1MSAxOC4yNTdtMzkuMzQ4LTAuMjA5djAuOTQ1YzAgMTYuNDc0 LTEwLjgwNyAyOC40MzUtMjUuNDk3IDI4LjQzNS0xNC43OTYgMC0yNS43MDgtMTIuMTcyLTI1Ljcw OC0yOC41NDJ2LTAuOTQzYzAtMTYuNDc0IDEwLjgwOC0yOC4zMzEgMjUuNDk4LTI4LjMzMSAxNC43 OTUgMCAyNS43MDcgMTIuMDY2IDI1LjcwNyAyOC40MzYiIGZpbGw9IiM0ZTQ2NDAiLz4KICAgIDwv Zz4KICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIzMS44MSAyNDEuNTMpIj4KICAgICA8cGF0 aCBkPSJtMCAwdjEuMDQ5YzAgMTAuOTEzIDYuMDg2IDE3LjgzNyAxMy4yMjEgMTcuODM3czEyLjkw Ni02LjgyIDEyLjkwNi0xNy45NDF2LTAuOTQ1YzAtMTEuMTIzLTUuNjY2LTE3LjgzOS0xMi45MDYt MTcuODM5LTcuMTM1IDAtMTMuMjIxIDYuOTI3LTEzLjIyMSAxNy44MzltMzguMDktMC4yMTF2MS40 NjljMCAxOC43ODQtMTAuNDk0IDI4LjEyMi0yMS42MTYgMjguMTIyLTcuOTc1IDAtMTIuODAyLTQu NjE3LTE2LjI2NC05Ljk2OXY4LjkyaC0xMS44NTd2LTcxLjQ1OGgxMS44NTd2MjQuMjM5YzMuMzU4 LTQuOTMxIDguMTg1LTkuNDQzIDE2LjI2NC05LjQ0MyAxMS4yMjcgMCAyMS42MTYgOS40NDMgMjEu NjE2IDI4LjEyIiBmaWxsPSIjNGU0NjQwIi8+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRy YW5zbGF0ZSgzMDAuMDkgMjYwLjk0KSI+CiAgICAgPHBhdGggZD0ibTAgMGM2LjkyNSAwIDEwLjkx Mi02LjQgMTEuNTQyLTE1LjIxNGgtMjMuNTA0YzAuODQgOS40NDMgNS40NTcgMTUuMjE0IDExLjk2 MiAxNS4yMTRtMjEuMTk2LTM5LjI0NC02LjE5MSA3LjM0N2MtMy42NzMtMy41NjgtNy41NTUtNS44 NzctMTIuODAxLTUuODc3LTcuMjQgMC0xMy4wMTIgNS4wMzctMTQuMDYxIDE0LjM3NWgzNC44MzZj MC4xMDUgMS42NzkgMC4xMDUgMy4zNTkgMC4xMDUgNC4wOTMgMCAxNi42ODMtNy45NzQgMjkuMjc2 LTIzLjA4NCAyOS4yNzYtMTMuNjQxIDAtMjMuNzE0LTExLjk2Mi0yMy43MTQtMjguNjQ3di0wLjgz OGMwLTE3LjQxOSAxMS4xMjItMjguMzMxIDI1LjM5My0yOC4zMzEgOC4yOSAwIDE0LjQ4IDMuMjUy IDE5LjUxNyA4LjYwMiIgZmlsbD0iIzRlNDY0MCIvPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3Jt PSJ0cmFuc2xhdGUoMzU3Ljk5IDI3MC45MSkiPgogICAgIDxwYXRoIGQ9Im0wIDBjLTcuNTU1IDAt MTIuMDY3LTQuMzAzLTE1LjIxNS05LjIzNHY4LjE4NWgtMTEuODU3di01NS42MTNoMTEuODU3djMz LjY4MmMwIDcuNjYgNC4zMDMgMTIuMjc3IDEwLjQ5MyAxMi4yNzcgNi4yOTYgMCA5Ljk2OC00LjMw MiA5Ljk2OC0xMi4wNjZ2LTMzLjg5M2gxMS44NTd2MzcuMjQ5YzAgMTEuODU3LTYuNDAxIDE5LjQx My0xNy4xMDMgMTkuNDEzIiBmaWxsPSIjNGU0NjQwIi8+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zv cm09InRyYW5zbGF0ZSg0MjIuODkgMjMwLjA5KSI+CiAgICAgPHBhdGggZD0ibTAgMHYwLjEwNWMw IDguNzA5LTYuNTA2IDEyLjY5NS0xNS4xMSAxNi41NzgtNi41MDYgMi45MzktMTAuOTEzIDQuODI2 LTEwLjkxMyA4LjQ5OXYwLjIxMWMwIDMuMDQzIDIuNjIzIDUuNDU1IDcuMDMgNS40NTVzOS4wMjQt Mi4wOTkgMTMuMjIxLTQuOTMxbDUuMDM3IDguNzA5Yy01LjI0NiAzLjc3Ny0xMS44NTcgNS45OC0x OC4wNDggNS45OC0xMC4zODcgMC0xOC4zNjItNi4yOTUtMTguMzYyLTE2LjI2M3YtMC4yMTFjMC05 LjEyNyA2LjkyNS0xMi45MDYgMTUuMjE1LTE2LjQ3MiA2LjYxLTIuODM0IDEwLjkxMi00LjYxNyAx MC45MTItOC42MDV2LTAuMTA0YzAtMy40NjMtMi44MzMtNi4wODctNy43NjUtNi4wODctNC45MzEg MC0xMC4yODMgMi40MTQtMTUuMzE5IDYuNTA1bC01LjU2Mi04LjQ5OGM2LjQwMS01LjM1MSAxNC4w NjEtNy43NjUgMjAuNjcxLTcuNzY1IDEwLjcwNCAwIDE4Ljk5MyA1Ljk4MiAxOC45OTMgMTYuODk0 IiBmaWxsPSIjNGU0NjQwIi8+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0 NTkuNiAyMTUuODIpIj4KICAgICA8cGF0aCBkPSJtMCAwdjkuNzU5Yy0xLjk5NC0xLjA1LTQuMDky LTEuNTc0LTYuNDAxLTEuNTc0LTMuNzc4IDAtNS45ODEgMS43ODMtNS45ODEgNi4wODZ2MjkuNTg5 aDEyLjQ4N3YxMC4xNzloLTEyLjQ4N3YxNS4wMDVoLTExLjg1N3YtMTUuMDA1aC02LjA4NmwxLjk0 OC0xMC4xNzloNC4xMzh2LTMyLjAwM2MwLTEwLjgwOCA2LjE5MS0xNC4yNzEgMTQuMzc2LTE0LjI3 MSAzLjk4NyAwIDcuMTM0IDAuOTQ1IDkuODYzIDIuNDE0IiBmaWxsPSIjNGU0NjQwIi8+CiAgICA8 L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0OTkuMTYgMjMyLjkyKSI+CiAgICAgPHBh dGggZD0ibTAgMGMwLTYuMjk1LTUuMjQ2LTEwLjkxMi0xMi4wNjctMTAuODA4LTUuMTQxIDAuMTA1 LTkuMDIzIDMuMjU0LTkuMDIzIDguODE0djAuMjExYzAgNS44NzUgMy45ODcgOS4zMzkgMTAuODA3 IDkuMzM5IDMuOTg4IDAgNy41NTUtMC44NDEgMTAuMjgzLTEuOTk0di01LjU2MnptNS44NzYgMzEu ODk5Yy0zLjU2NyAzLjY3Mi05LjEyOCA1LjY2Ni0xNi4zNjggNS42NjYtNy40NSAwLTEzLjAxMi0x Ljc4NS0xOC4zNjQtNC40MDhsMy4zNTgtOS40NDNjMy42NzMgMS42NzkgOC4wOCAzLjM1OSAxMy40 MzEgMy4zNTkgNy41NTYgMCAxMS45NjItMy44ODQgMTEuOTYyLTExLjMzM3YtMi4zMDljLTMuNzc3 IDEuMjYtNy41NTQgMi4yMDMtMTIuODAxIDIuMjAzLTExLjc1MiAwLTE5LjcyNy01Ljg3NS0xOS43 MjctMTcuODM3di0wLjUyNWMwLTEwLjgwNyA3Ljc2NS0xNi45OTggMTYuOTk5LTE2Ljk5OCA3LjI0 IDAgMTIuMTcyIDMuMTQ3IDE1LjQyNCA3Ljg2OXYtNi44MmgxMS42NDd2MzQuNTIyYzAgNi45MjQt MS44ODggMTIuMzgyLTUuNTYxIDE2LjA1NCIgZmlsbD0iIzRlNDY0MCIvPgogICAgPC9nPgogICAg PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTYxIDIyMS40OCkiPgogICAgIDxwYXRoIGQ9Im0wIDAt Ni40IDcuODY5Yy0zLjI1My0zLjI1Mi02LjUwNi01LjY2Ni0xMS4zMzItNS42NjYtOC4wODEgMC0x My43NDYgNy4yNC0xMy43NDYgMTguMDQ4djAuNTI1YzAgMTAuNDk0IDUuNjY1IDE3Ljk0MyAxMy40 MzEgMTcuOTQzIDUuMDM2IDAgOC4yODktMi41MTkgMTEuMjI3LTUuNTYybDYuNjExIDguNzFjLTQu NjE3IDQuNjE3LTkuODY0IDcuNTU1LTE3LjgzOCA3LjU1NS0xNC41ODYgMC0yNS4zOTMtMTEuOTYx LTI1LjM5My0yOC41NDJ2LTEuMDQ5YzAtMTYuNTc5IDEwLjQ5My0yOC4yMjUgMjQuOTczLTI4LjIy NSA4LjQ5OSAwIDE0LjA2IDMuNDYxIDE4LjQ2NyA4LjM5NCIgZmlsbD0iIzRlNDY0MCIvPgogICAg PC9nPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNTk3LjI5IDI0My4xMSkiPgogICAgIDxw YXRoIGQ9Im0wIDAtOC4zMjMtOC45NDYgMTEuMTY0LTE5LjkxOGgxMy43NDVsLTE2LjU4NiAyOC44 NjR6IiBmaWxsPSIjNGU0NjQwIi8+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0 ZSg1OTkuMjkgMjY5Ljg2KSI+CiAgICAgPHBhdGggZD0ibTAgMC0xOC45OTItMjQuNDV2NDQuNTk2 aC0xMS44NTd2LTc1Ljc1OWgxMS44NTd2MTYuMDU0bDMzLjA1MyAzOS41NTloLTE0LjA2MXoiIGZp bGw9IiM0ZTQ2NDAiLz4KICAgIDwvZz4KICAgIDxnIG9wYWNpdHk9IjAuOTgiIGNsaXAtcGF0aD0i dXJsKCNhKSI+CiAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDM2LjQ2IDQyNC44NykiPgog ICAgICA8cGF0aCBkPSJtMCAwaC05NC42MzhjLTUuOTQgMC0xMC44LTQuODYtMTAuOC0xMC44di0y NS40NWgyNi4yNXY0LjE1OWMwIDMuMjI2IDIuNjE2IDUuODQxIDUuODQyIDUuODQxaDUyLjA1NWMz LjIyNiAwIDUuODQxLTIuNjE1IDUuODQxLTUuODQxdi00LjE1OWgyNi4yNXYyNS40NWMwLjAwMiA1 Ljk0LTQuODU4IDEwLjgtMTAuNzk4IDEwLjgiIGZpbGw9IiNlZDE4NDQiLz4KICAgICA8L2c+CiAg ICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDIxLjAxIDM0My4yKSI+CiAgICAgIDxwYXRoIGQ9 Im0wIDBjMC0zLjIyNi0yLjYxNS01Ljg0Mi01Ljg0MS01Ljg0MmgtNTIuMDU1Yy0zLjIyNiAwLTUu ODQyIDIuNjE2LTUuODQyIDUuODQydjQuMTU4aC0yNi4yNXYtMjUuNDQ5YzAtNS45NDEgNC44Ni0x MC44IDEwLjgtMTAuOGg5NC42MzhjNS45NCAwIDEwLjggNC44NTkgMTAuOCAxMC44djI1LjQ0OWgt MjYuMjV2LTQuMTU4eiIgZmlsbD0iI2VkMTg0NCIvPgogICAgIDwvZz4KICAgICA8cGF0aCBkPSJt MzU3LjI4IDM4MS4xMmgtMjYuMjV2LTI2LjI1aDI2LjI1djI2LjI1eiIgZmlsbD0iI2VkMTg0NCIv PgogICAgIDxwYXRoIGQ9Im00NDcuMjYgMzgxLjEyaC0yNi4yNXYtMjYuMjVoMjYuMjV2MjYuMjV6 IiBmaWxsPSIjZWQxODQ0Ii8+CiAgICA8L2c+CiAgIDwvZz4KICA8L2c+CiA8L2c+Cjwvc3ZnPgo= ... ================================================ FILE: values_overrides/horizon/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: horizon: ingress: - from: - podSelector: matchLabels: application: horizon - from: - podSelector: matchLabels: application: prometheus-openstack-exporter - from: - podSelector: matchLabels: application: ingress ports: - port: 80 protocol: TCP - port: 443 protocol: TCP egress: - to: - podSelector: matchLabels: application: neutron - to: - podSelector: matchLabels: application: nova - to: - podSelector: matchLabels: application: glance - to: - podSelector: matchLabels: application: cinder - to: - podSelector: matchLabels: application: keystone - to: - podSelector: matchLabels: application: heat - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/horizon/tls.yaml ================================================ --- network: dashboard: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" conf: software: apache2: a2enmod: - headers - rewrite - ssl horizon: apache: | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded ServerName horizon-int.openstack.svc.cluster.local RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L] ServerName horizon-int.openstack.svc.cluster.local WSGIScriptReloading On WSGIDaemonProcess horizon-http processes=5 threads=1 user=horizon group=horizon display-name=%{GROUP} python-path=/var/lib/kolla/venv/lib/python2.7/site-packages WSGIProcessGroup horizon-http WSGIScriptAlias / /var/www/cgi-bin/horizon/django.wsgi WSGIPassAuthorization On RewriteEngine On RewriteCond %{REQUEST_METHOD} !^(POST|PUT|GET|DELETE|PATCH) RewriteRule .* - [F] Require all granted Alias /static /var/www/html/horizon SetHandler static ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout TransferLog /dev/stdout SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded ErrorLog /dev/stdout SSLEngine on SSLCertificateFile /etc/openstack-dashboard/certs/tls.crt SSLCertificateKeyFile /etc/openstack-dashboard/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on local_settings: config: use_ssl: "True" csrf_cookie_secure: "True" csrf_cookie_httponly: "True" enforce_password_check: "True" session_cookie_secure: "True" session_cookie_httponly: "True" endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt scheme: default: https port: api: default: 443 dashboard: host_fqdn_override: default: tls: secretName: horizon-tls-web issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https public: https port: web: default: 443 public: 443 ingress: port: ingress: default: 443 manifests: certificates: true ... ================================================ FILE: values_overrides/ironic/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" ironic_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: ironic: custom.tld/key: "value" ... ================================================ FILE: values_overrides/ironic/gateway.yaml ================================================ # Gateway API overrides for Ironic. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: baremetal: host_fqdn_override: public: host: ironic.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: ironic-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.baremetal.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: ironic-api port: 6385 ... ================================================ FILE: values_overrides/ironic/mariadb-operator.yaml ================================================ --- conf: ironic: database: connection: null manifests: job_db_init: false etcSources: ironic_api: - ironic-db-conn ironic_db_sync: - ironic-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: ironic namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: ironic namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: ironic-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: ironic-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "ironic" table: "*" username: ironic grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: ironic-db-conn spec: mariaDbRef: name: mariadb username: ironic passwordSecretKeyRef: name: ironic-db-password key: password database: ironic secretName: ironic-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/ironic/standalone.yaml ================================================ --- conf: ironic: DEFAULT: auth_strategy: noauth conductor: automated_clean: false dhcp: dhcp_provider: none network: pxe: device: br-simulator bootstrap: image: enabled: false openstack: enabled: false network: enabled: false openstack: enabled: false object_store: enabled: false openstack: enabled: false dependencies: static: api: jobs: - ironic-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging bootstrap: jobs: null services: null conductor: jobs: - ironic-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: oslo_messaging secrets: identity: admin: ironic-keystone-admin ironic: ironic-keystone-user manifests: job_ks_endpoints: false job_ks_service: false job_ks_user: false job_manage_cleaning_network: false secret_keystone: false ... ================================================ FILE: values_overrides/keystone/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" keystone_api: "quay.io/airshipit/keystone:2024.2-ubuntu_jammy" keystone_bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" keystone_credential_rotate: "quay.io/airshipit/keystone:2024.2-ubuntu_jammy" keystone_credential_setup: "quay.io/airshipit/keystone:2024.2-ubuntu_jammy" keystone_db_sync: "quay.io/airshipit/keystone:2024.2-ubuntu_jammy" keystone_domain_manage: "quay.io/airshipit/keystone:2024.2-ubuntu_jammy" keystone_fernet_rotate: "quay.io/airshipit/keystone:2024.2-ubuntu_jammy" keystone_fernet_setup: "quay.io/airshipit/keystone:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ... ================================================ FILE: values_overrides/keystone/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" keystone_api: "quay.io/airshipit/keystone:2025.1-ubuntu_jammy" keystone_bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" keystone_credential_rotate: "quay.io/airshipit/keystone:2025.1-ubuntu_jammy" keystone_credential_setup: "quay.io/airshipit/keystone:2025.1-ubuntu_jammy" keystone_db_sync: "quay.io/airshipit/keystone:2025.1-ubuntu_jammy" keystone_domain_manage: "quay.io/airshipit/keystone:2025.1-ubuntu_jammy" keystone_fernet_rotate: "quay.io/airshipit/keystone:2025.1-ubuntu_jammy" keystone_fernet_setup: "quay.io/airshipit/keystone:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ... ================================================ FILE: values_overrides/keystone/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" keystone_api: "quay.io/airshipit/keystone:2025.1-ubuntu_noble" keystone_bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" keystone_credential_rotate: "quay.io/airshipit/keystone:2025.1-ubuntu_noble" keystone_credential_setup: "quay.io/airshipit/keystone:2025.1-ubuntu_noble" keystone_db_sync: "quay.io/airshipit/keystone:2025.1-ubuntu_noble" keystone_domain_manage: "quay.io/airshipit/keystone:2025.1-ubuntu_noble" keystone_fernet_rotate: "quay.io/airshipit/keystone:2025.1-ubuntu_noble" keystone_fernet_setup: "quay.io/airshipit/keystone:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ... ================================================ FILE: values_overrides/keystone/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" keystone_api: "quay.io/airshipit/keystone:2025.2-ubuntu_noble" keystone_bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" keystone_credential_rotate: "quay.io/airshipit/keystone:2025.2-ubuntu_noble" keystone_credential_setup: "quay.io/airshipit/keystone:2025.2-ubuntu_noble" keystone_db_sync: "quay.io/airshipit/keystone:2025.2-ubuntu_noble" keystone_domain_manage: "quay.io/airshipit/keystone:2025.2-ubuntu_noble" keystone_fernet_rotate: "quay.io/airshipit/keystone:2025.2-ubuntu_noble" keystone_fernet_setup: "quay.io/airshipit/keystone:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ... ================================================ FILE: values_overrides/keystone/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" keystone_api: another.tld/foo: "bar" job: default: custom.tld/key: "value" custom.tld/key2: "value2" keystone_credential_setup: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: keystone: custom.tld/key: "value" tls: identity_api_public: custom.tld/key: "value" ldap: tls: custom.tld/key: "value" ... ================================================ FILE: values_overrides/keystone/apparmor.yaml ================================================ --- pod: security_context: keystone: container: keystone_api: appArmorProfile: type: RuntimeDefault credential_setup: container: keystone_credential_setup: appArmorProfile: type: RuntimeDefault fernet_setup: container: keystone_fernet_setup: appArmorProfile: type: RuntimeDefault domain_manage: container: keystone_domain_manage: appArmorProfile: type: RuntimeDefault keystone_domain_manage_init: appArmorProfile: type: RuntimeDefault test: container: keystone_test: appArmorProfile: type: RuntimeDefault keystone_test_ks_user: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/keystone/gateway.yaml ================================================ # Gateway API overrides for Keystone. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: identity: host_fqdn_override: public: host: keystone.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: keystone-route namespace: openstack spec: parentRefs: - name: gateway-default namespace: envoy-gateway-system hostnames: - "{{ .Values.endpoints.identity.host_fqdn_override.public.host }}" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: keystone-api port: 5000 ... ================================================ FILE: values_overrides/keystone/internal-reverse-proxy.yaml ================================================ --- endpoints: identity: host_fqdn_override: public: example.com scheme: default: https public: https internal: https service: http port: api: default: 443 internal: 443 service: 5000 ... ================================================ FILE: values_overrides/keystone/ldap.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- conf: keystone: identity: driver: sql default_domain_id: default domain_specific_drivers_enabled: True domain_configurations_from_database: True domain_config_dir: /etc/keystone/domains ks_domains: ldapdomain: identity: driver: ldap ldap: url: "ldap://ldap.openstack.svc.cluster.local:389" user: "cn=admin,dc=cluster,dc=local" password: password suffix: "dc=cluster,dc=local" user_attribute_ignore: "enabled,email,tenants,default_project_id" query_scope: sub user_enabled_emulation: True user_enabled_emulation_dn: "cn=overwatch,ou=Groups,dc=cluster,dc=local" user_tree_dn: "ou=People,dc=cluster,dc=local" user_enabled_mask: 2 user_enabled_default: 512 user_name_attribute: cn user_id_attribute: sn user_mail_attribute: mail user_pass_attribute: userPassword group_tree_dn: "ou=Groups,dc=cluster,dc=local" group_filter: "" group_objectclass: posixGroup group_id_attribute: cn group_name_attribute: cn group_desc_attribute: description group_member_attribute: memberUID use_pool: true pool_size: 27 pool_retry_max: 3 pool_retry_delay: 0.1 pool_connection_timeout: 15 pool_connection_lifetime: 600 use_auth_pool: true auth_pool_size: 100 auth_pool_connection_lifetime: 60 ... ================================================ FILE: values_overrides/keystone/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" keystone_api: "quay.io/airshipit/keystone:2025.1-ubuntu_noble_loci" keystone_bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" keystone_credential_rotate: "quay.io/airshipit/keystone:2025.1-ubuntu_noble_loci" keystone_credential_setup: "quay.io/airshipit/keystone:2025.1-ubuntu_noble_loci" keystone_db_sync: "quay.io/airshipit/keystone:2025.1-ubuntu_noble_loci" keystone_domain_manage: "quay.io/airshipit/keystone:2025.1-ubuntu_noble_loci" keystone_fernet_rotate: "quay.io/airshipit/keystone:2025.1-ubuntu_noble_loci" keystone_fernet_setup: "quay.io/airshipit/keystone:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/keystone/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" keystone_api: "quay.io/airshipit/keystone:2025.2-ubuntu_noble_loci" keystone_bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" keystone_credential_rotate: "quay.io/airshipit/keystone:2025.2-ubuntu_noble_loci" keystone_credential_setup: "quay.io/airshipit/keystone:2025.2-ubuntu_noble_loci" keystone_db_sync: "quay.io/airshipit/keystone:2025.2-ubuntu_noble_loci" keystone_domain_manage: "quay.io/airshipit/keystone:2025.2-ubuntu_noble_loci" keystone_fernet_rotate: "quay.io/airshipit/keystone:2025.2-ubuntu_noble_loci" keystone_fernet_setup: "quay.io/airshipit/keystone:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/keystone/mariadb-operator.yaml ================================================ --- conf: keystone: database: connection: null manifests: job_db_init: false etcSources: keystone_api: - keystone-db-conn keystone_db_sync: - keystone-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: keystone namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: keystone namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: keystone-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: keystone-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "keystone" table: "*" username: keystone grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: keystone-db-conn spec: mariaDbRef: name: mariadb username: keystone passwordSecretKeyRef: name: keystone-db-password key: password database: keystone secretName: keystone-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/keystone/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: keystone: ingress: - from: - podSelector: matchLabels: application: ceph - podSelector: matchLabels: application: ingress - podSelector: matchLabels: application: keystone - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: glance - podSelector: matchLabels: application: cinder - podSelector: matchLabels: application: barbican - podSelector: matchLabels: application: ceilometer - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: ironic - podSelector: matchLabels: application: magnum - podSelector: matchLabels: application: mistral - podSelector: matchLabels: application: nova - podSelector: matchLabels: application: neutron - podSelector: matchLabels: application: placement - podSelector: matchLabels: application: prometheus-openstack-exporter ports: - protocol: TCP port: 5000 egress: - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/keystone/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: keystone: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # keystone: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/keystone/tls-custom.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt secrets: tls: identity: api: # manually created internal: keystone-tls-api tls: identity: true ... ================================================ FILE: values_overrides/keystone/tls.yaml ================================================ --- network: api: ingress: annotations: nginx.ingress.kubernetes.io/rewrite-target: null nginx.ingress.kubernetes.io/backend-protocol: "https" pod: security_context: keystone: pod: runAsUser: 0 container: keystone_api: readOnlyRootFilesystem: false allowPrivilegeEscalation: false conf: software: apache2: a2enmod: - ssl keystone: oslo_messaging_rabbit: ssl: true ssl_ca_file: /etc/rabbitmq/certs/ca.crt ssl_cert_file: /etc/rabbitmq/certs/tls.crt ssl_key_file: /etc/rabbitmq/certs/tls.key wsgi_keystone: | {{- $portInt := tuple "identity" "service" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen 0.0.0.0:{{ $portInt }} LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout ServerName {{ printf "%s.%s.svc.%s" "keystone-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} WSGIDaemonProcess keystone-public processes=1 threads=1 user=keystone group=keystone display-name=%{GROUP} WSGIProcessGroup keystone-public WSGIScriptAlias / /var/www/cgi-bin/keystone/wsgi.py WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded SSLEngine on SSLCertificateFile /etc/keystone/certs/tls.crt SSLCertificateKeyFile /etc/keystone/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt host_fqdn_override: default: tls: secretName: keystone-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https public: https service: https port: api: default: 443 oslo_messaging: port: https: default: 15680 manifests: certificates: true tls: identity: true oslo_messaging: true oslo_db: true ... ================================================ FILE: values_overrides/kibana/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: register_kibana_indexes: quay.io/airshipit/heat:2024.2-ubuntu_jammy flush_kibana_metadata: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/kibana/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: register_kibana_indexes: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy flush_kibana_metadata: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/kibana/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: register_kibana_indexes: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble flush_kibana_metadata: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/kibana/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: register_kibana_indexes: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble flush_kibana_metadata: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/kibana/apparmor.yaml ================================================ --- pod: security_context: dashboard: container: kibana: appArmorProfile: type: RuntimeDefault apache_proxy: appArmorProfile: type: RuntimeDefault register_kibana_indexes: container: register_kibana_indexes: appArmorProfile: type: RuntimeDefault flush_kibana_metadata: container: flush_kibana_metadata: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/kibana/gateway.yaml ================================================ # Gateway API overrides for Kibana. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: kibana: host_fqdn_override: public: host: kibana.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: kibana-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.kibana.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: kibana-dash port: 5601 ... ================================================ FILE: values_overrides/kibana/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: register_kibana_indexes: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci flush_kibana_metadata: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/kibana/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: register_kibana_indexes: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci flush_kibana_metadata: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/kibana/tls.yaml ================================================ --- conf: kibana: elasticsearch: ssl: certificateAuthorities: ["/etc/elasticsearch/certs/ca.crt"] verificationMode: certificate endpoints: elasticsearch: scheme: default: "https" port: http: default: 443 kibana: host_fqdn_override: default: tls: issuerRef: name: ca-issuer kind: ClusterIssue manifests: certificates: true ... ================================================ FILE: values_overrides/kubernetes-keystone-webhook/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: scripted_test: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/kubernetes-keystone-webhook/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: scripted_test: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/kubernetes-keystone-webhook/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: scripted_test: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/kubernetes-keystone-webhook/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: scripted_test: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/kubernetes-keystone-webhook/gateway.yaml ================================================ # Gateway API overrides for Kubernetes Keystone Webhook. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: kubernetes_keystone_webhook: host_fqdn_override: public: host: k8sksauth.openstack-helm.org manifests: ingress_webhook: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: k8sksauth-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.kubernetes_keystone_webhook.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: k8sksauth-api port: 8443 ... ================================================ FILE: values_overrides/kubernetes-keystone-webhook/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: scripted_test: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/kubernetes-keystone-webhook/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: scripted_test: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/kubernetes-node-problem-detector/apparmor.yaml ================================================ --- pod: security_context: node_problem_detector: container: node_problem_detector: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/libvirt/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: libvirt: quay.io/airshipit/libvirt:2024.2-ubuntu_noble ... ================================================ FILE: values_overrides/libvirt/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: libvirt: quay.io/airshipit/libvirt:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/libvirt/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: libvirt: quay.io/airshipit/libvirt:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/libvirt/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: libvirt: quay.io/airshipit/libvirt:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/libvirt/apparmor.yaml ================================================ --- pod: security_context: libvirt: container: libvirt: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/libvirt/cinder-external-ceph-backend.yaml ================================================ # Note: This yaml file serves as an example for overriding the manifest # to enable additional externally managed Ceph Cinder backend. When additional # externally managed Ceph Cinder backend is provisioned as shown in # cinder/values_overrides/external-ceph-backend.yaml of repo openstack-helm, # below override is needed to store the secret key of the cinder user in # libvirt. --- conf: ceph: cinder: external_ceph: enabled: true user: cinder2 secret_uuid: 3f0133e4-8384-4743-9473-fecacc095c74 user_secret_name: cinder-volume-external-rbd-keyring ... ================================================ FILE: values_overrides/libvirt/inovex_exporter.yaml ================================================ --- libvirt: extraContainers: - name: libvirt-exporter image: ghcr.io/inovex/prometheus-libvirt-exporter:2.3.0 imagePullPolicy: IfNotPresent args: - --libvirt.uri=/run/libvirt/libvirt-sock-ro ports: - name: metrics protocol: TCP containerPort: 9177 livenessProbe: httpGet: path: /metrics port: 9177 initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 5 readinessProbe: httpGet: path: /metrics port: 9177 initialDelaySeconds: 15 periodSeconds: 60 timeoutSeconds: 5 securityContext: privileged: true volumeMounts: - name: run mountPath: /run mountPropagation: Bidirectional ... ================================================ FILE: values_overrides/libvirt/netpol.yaml ================================================ --- manifests: network_policy: true ... ================================================ FILE: values_overrides/libvirt/node_overrides.yaml ================================================ --- # We have two nodes labeled with node-nics-type=4nics and node-nics-type=2nics # on first node we pick up libvirt bind address from ens3 interface # on second node we pick up libvirt bind address from ens0 interface overrides: libvirt_libvirt: overrides_default: false labels: node-nics-type::4nics: values: conf: dynamic_options: libvirt: listen_interface: ens3 node-nics-type::2nics: values: conf: dynamic_options: libvirt: listen_interface: ens0 ... ================================================ FILE: values_overrides/libvirt/ovn.yaml ================================================ --- dependencies: dynamic: targeted: openvswitch: libvirt: pod: [] ... ================================================ FILE: values_overrides/libvirt/ssl.yaml ================================================ --- conf: libvirt: listen_tcp: "0" listen_tls: "1" listen_addr: 0.0.0.0 ... ================================================ FILE: values_overrides/libvirt/vexxhost_exporter.yaml ================================================ --- libvirt: extraContainers: - name: libvirt-exporter image: vexxhost/libvirtd-exporter:latest imagePullPolicy: IfNotPresent args: - "--libvirt.nova" ports: - name: metrics protocol: TCP containerPort: 9474 livenessProbe: httpGet: path: /metrics port: 9474 initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 5 readinessProbe: httpGet: path: /metrics port: 9474 initialDelaySeconds: 15 periodSeconds: 60 timeoutSeconds: 5 securityContext: privileged: true volumeMounts: - name: run mountPath: /run mountPropagation: Bidirectional ... ================================================ FILE: values_overrides/local-storage/local-storage.yaml ================================================ --- conf: persistent_volumes: - name: local-persistent-volume-0 reclaim_policy: Delete storage_capacity: "1Gi" access_modes: ["ReadWriteOnce"] local_path: /srv/local-volume-0 - name: local-persistent-volume-1 reclaim_policy: Delete storage_capacity: "1Gi" access_modes: ["ReadWriteOnce"] local_path: /srv/local-volume-1 - name: local-persistent-volume-2 reclaim_policy: Delete storage_capacity: "1Gi" access_modes: ["ReadWriteOnce"] local_path: /srv/local-volume-2 - name: local-persistent-volume-3 reclaim_policy: Delete storage_capacity: "1Gi" access_modes: ["ReadWriteOnce"] local_path: /srv/local-volume-3 - name: local-persistent-volume-4 reclaim_policy: Delete storage_capacity: "1Gi" access_modes: ["ReadWriteOnce"] local_path: /srv/local-volume-4 - name: local-persistent-volume-5 reclaim_policy: Delete storage_capacity: "1Gi" access_modes: ["ReadWriteOnce"] local_path: /srv/local-volume-5 manifests: storage_class: true persistent_volumes: true ... ================================================ FILE: values_overrides/magnum/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" magnum_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: magnum: custom.tld/key: "value" ... ================================================ FILE: values_overrides/magnum/gateway.yaml ================================================ # Gateway API overrides for Magnum. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: container_infra: host_fqdn_override: public: host: magnum.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: magnum-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.container_infra.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: magnum-api port: 9511 ... ================================================ FILE: values_overrides/magnum/mariadb-operator.yaml ================================================ --- conf: magnum: database: connection: null manifests: job_db_init: false etcSources: magnum_api: - magnum-db-conn magnum_db_sync: - magnum-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: magnum namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: magnum namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: magnum-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: magnum-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "magnum" table: "*" username: magnum grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: magnum-db-conn spec: mariaDbRef: name: mariadb username: magnum passwordSecretKeyRef: name: magnum-db-password key: password database: magnum secretName: magnum-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/manila/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy manila_db_sync: quay.io/airshipit/manila:2024.2-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy manila_api: quay.io/airshipit/manila:2024.2-ubuntu_jammy manila_data: quay.io/airshipit/manila:2024.2-ubuntu_jammy manila_scheduler: quay.io/airshipit/manila:2024.2-ubuntu_jammy manila_share: quay.io/airshipit/manila:2024.2-ubuntu_jammy conf: manila_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/manila-wsgi ... ================================================ FILE: values_overrides/manila/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy manila_db_sync: quay.io/airshipit/manila:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy manila_api: quay.io/airshipit/manila:2025.1-ubuntu_jammy manila_data: quay.io/airshipit/manila:2025.1-ubuntu_jammy manila_scheduler: quay.io/airshipit/manila:2025.1-ubuntu_jammy manila_share: quay.io/airshipit/manila:2025.1-ubuntu_jammy conf: manila_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/manila-wsgi ... ================================================ FILE: values_overrides/manila/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble manila_db_sync: quay.io/airshipit/manila:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble manila_api: quay.io/airshipit/manila:2025.1-ubuntu_noble manila_data: quay.io/airshipit/manila:2025.1-ubuntu_noble manila_scheduler: quay.io/airshipit/manila:2025.1-ubuntu_noble manila_share: quay.io/airshipit/manila:2025.1-ubuntu_noble conf: manila_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/manila-wsgi ... ================================================ FILE: values_overrides/manila/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble manila_db_sync: quay.io/airshipit/manila:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble manila_api: quay.io/airshipit/manila:2025.2-ubuntu_noble manila_data: quay.io/airshipit/manila:2025.2-ubuntu_noble manila_scheduler: quay.io/airshipit/manila:2025.2-ubuntu_noble manila_share: quay.io/airshipit/manila:2025.2-ubuntu_noble conf: manila_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/manila-wsgi ... ================================================ FILE: values_overrides/manila/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" manila_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: manila: custom.tld/key: "value" tls: share_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/manila/apparmor.yaml ================================================ --- pod: security_context: manila: container: manila_api: appArmorProfile: type: RuntimeDefault test: container: manila_test: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/manila/gateway.yaml ================================================ # Gateway API overrides for Manila. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: sharev2: host_fqdn_override: public: host: manila.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: manila-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.sharev2.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: manila-api port: 8786 ... ================================================ FILE: values_overrides/manila/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci manila_db_sync: quay.io/airshipit/manila:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci manila_api: quay.io/airshipit/manila:2025.1-ubuntu_noble_loci manila_data: quay.io/airshipit/manila:2025.1-ubuntu_noble_loci manila_scheduler: quay.io/airshipit/manila:2025.1-ubuntu_noble_loci manila_share: quay.io/airshipit/manila:2025.1-ubuntu_noble_loci conf: manila_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/manila-wsgi ... ================================================ FILE: values_overrides/manila/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci manila_db_sync: quay.io/airshipit/manila:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci manila_api: quay.io/airshipit/manila:2025.2-ubuntu_noble_loci manila_data: quay.io/airshipit/manila:2025.2-ubuntu_noble_loci manila_scheduler: quay.io/airshipit/manila:2025.2-ubuntu_noble_loci manila_share: quay.io/airshipit/manila:2025.2-ubuntu_noble_loci conf: manila_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/manila-wsgi ... ================================================ FILE: values_overrides/manila/mariadb-operator.yaml ================================================ --- conf: manila: database: connection: null manifests: job_db_init: false etcSources: manila_api: - manila-db-conn manila_db_sync: - manila-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: manila namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: manila namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: manila-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: manila-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "manila" table: "*" username: manila grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: manila-db-conn spec: mariaDbRef: name: mariadb username: manila passwordSecretKeyRef: name: manila-db-password key: password database: manila secretName: manila-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/manila/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: manila: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # manila: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/manila/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt manila: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/manila/tls.yaml ================================================ --- manifests: certificates: true ... ================================================ FILE: values_overrides/mariadb/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/mariadb/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/mariadb/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/mariadb/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/mariadb/apparmor.yaml ================================================ --- pod: security_context: server: container: mariadb: appArmorProfile: type: RuntimeDefault exporter: appArmorProfile: type: RuntimeDefault perms: appArmorProfile: type: RuntimeDefault mariadb_backup: container: mariadb_backup: appArmorProfile: type: RuntimeDefault verify_perms: appArmorProfile: type: RuntimeDefault backup_perms: appArmorProfile: type: RuntimeDefault tests: container: test: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/mariadb/backups.yaml ================================================ --- conf: backup: enabled: true remote_backup: enabled: true volume: backup: enabled: true manifests: pvc_backup: true job_ks_user: false cron_job_mariadb_backup: true secret_backup_restore: true endpoints: identity: auth: mariadb: auth_url: null role: admin region_name: RegionOne username: mariadb-backup-user password: password project_name: service user_domain_name: service project_domain_name: service mariadb_failover: auth_url: null role: admin region_name: RegionOne username: mariadb-backup-user-failover password: password project_name: service user_domain_name: service project_domain_name: service ... ================================================ FILE: values_overrides/mariadb/local-storage.yaml ================================================ --- pod: replicas: server: 1 volume: size: 1Gi class_name: local-storage monitoring: prometheus: enabled: false ... ================================================ FILE: values_overrides/mariadb/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/mariadb/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/mariadb/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: mariadb: egress: - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ingress: - from: - podSelector: matchLabels: application: keystone - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: glance - podSelector: matchLabels: application: cinder - podSelector: matchLabels: application: aodh - podSelector: matchLabels: application: barbican - podSelector: matchLabels: application: ceilometer - podSelector: matchLabels: application: designate - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: ironic - podSelector: matchLabels: application: magnum - podSelector: matchLabels: application: mistral - podSelector: matchLabels: application: nova - podSelector: matchLabels: application: neutron - podSelector: matchLabels: application: rally - podSelector: matchLabels: application: senlin - podSelector: matchLabels: application: placement - podSelector: matchLabels: application: prometheus-mysql-exporter - podSelector: matchLabels: application: mariadb - podSelector: matchLabels: application: mariadb-backup ports: - protocol: TCP port: 3306 - protocol: TCP port: 4567 - protocol: TCP port: 80 - protocol: TCP port: 8080 ... ================================================ FILE: values_overrides/mariadb/remote_backups.yaml ================================================ --- conf: backup: enabled: true remote_backup: enabled: true volume: backup: enabled: true endpoints: identity: auth: mariadb: # Auth URL of null indicates local authentication # HTK will form the URL unless specified here auth_url: https://rgw-1.test.local region_name: RegionOne username: mariadb-backup-user password: password project_name: service user_domain_name: service project_domain_name: service mariadb_failover: # # Auth URL of null indicates local authentication # # HTK will form the URL unless specified here auth_url: https://rgw-2.test.local region_name: RegionOne username: mariadb-backup-user password: password project_name: service user_domain_name: service project_domain_name: service manifests: pvc_backup: true job_ks_user: true cron_job_mariadb_backup: true secret_backup_restore: true ... ================================================ FILE: values_overrides/mariadb/staggered-backups.yaml ================================================ --- conf: backup: enabled: true remote_backup: enabled: false pod: labels: backup: staggered_backups: enabled affinity: mariadb_backup: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: status.phase operator: NotIn values: - Running - key: staggered-backups operator: In values: - enabled namespaces: - openstack - osh-infra - ucp topologyKey: kubernetes.io/os volume: backup: enabled: true manifests: pvc_backup: true job_ks_user: false cron_job_mariadb_backup: true secret_backup_restore: true ... ================================================ FILE: values_overrides/mariadb/tls.yaml ================================================ --- pod: security_context: server: container: perms: readOnlyRootFilesystem: false mariadb: runAsUser: 0 allowPrivilegeEscalation: true readOnlyRootFilesystem: false endpoints: oslo_db: host_fqdn_override: default: tls: secretName: mariadb-tls-direct issuerRef: name: ca-issuer kind: ClusterIssuer manifests: certificates: true ... ================================================ FILE: values_overrides/mariadb/wait-for-cluster.yaml ================================================ --- manifests: job_cluster_wait: true ... ================================================ FILE: values_overrides/mariadb-backup/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/mariadb-backup/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/mariadb-backup/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/mariadb-backup/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/mariadb-backup/apparmor.yaml ================================================ --- pod: security_context: mariadb_backup: container: mariadb_backup: appArmorProfile: type: RuntimeDefault verify_perms: appArmorProfile: type: RuntimeDefault backup_perms: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/mariadb-backup/backups.yaml ================================================ --- conf: backup: enabled: true remote_backup: enabled: false volume: backup: enabled: true manifests: pvc_backup: true job_ks_user: false cron_job_mariadb_backup: true secret_backup_restore: true ... ================================================ FILE: values_overrides/mariadb-backup/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/mariadb-backup/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/mariadb-backup/staggered-backups.yaml ================================================ --- conf: backup: enabled: true remote_backup: enabled: false pod: labels: backup: staggered_backups: enabled affinity: mariadb_backup: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: status.phase operator: NotIn values: - Running - key: staggered-backups operator: In values: - enabled namespaces: - openstack - osh-infra - ucp topologyKey: kubernetes.io/os volume: backup: enabled: true manifests: pvc_backup: true job_ks_user: false cron_job_mariadb_backup: true secret_backup_restore: true ... ================================================ FILE: values_overrides/mariadb-backup/tls.yaml ================================================ --- endpoints: oslo_db: host_fqdn_override: default: tls: secretName: mariadb-tls-direct issuerRef: name: ca-issuer kind: ClusterIssuer manifests: certificates: true ... ================================================ FILE: values_overrides/mariadb-cluster/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/mariadb-cluster/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/mariadb-cluster/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/mariadb-cluster/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/mariadb-cluster/apparmor.yaml ================================================ --- pod: security_context: server: container: mariadb: appArmorProfile: type: RuntimeDefault agent: appArmorProfile: type: RuntimeDefault perms: appArmorProfile: type: RuntimeDefault tests: container: test: appArmorProfile: type: RuntimeDefault mariadb_cluster_refresh_statefulset: container: main: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/mariadb-cluster/downscaled.yaml ================================================ --- conf: galera: enabled: false pod: replicas: server: 1 ... ================================================ FILE: values_overrides/mariadb-cluster/local-storage.yaml ================================================ --- pod: replicas: server: 1 volume: size: 1Gi class_name: local-storage monitoring: prometheus: enabled: false ... ================================================ FILE: values_overrides/mariadb-cluster/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/mariadb-cluster/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/mariadb-cluster/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: mariadb: egress: - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ingress: - from: - podSelector: matchLabels: application: keystone - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: glance - podSelector: matchLabels: application: cinder - podSelector: matchLabels: application: aodh - podSelector: matchLabels: application: barbican - podSelector: matchLabels: application: ceilometer - podSelector: matchLabels: application: designate - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: ironic - podSelector: matchLabels: application: magnum - podSelector: matchLabels: application: mistral - podSelector: matchLabels: application: nova - podSelector: matchLabels: application: neutron - podSelector: matchLabels: application: rally - podSelector: matchLabels: application: senlin - podSelector: matchLabels: application: placement - podSelector: matchLabels: application: prometheus-mysql-exporter - podSelector: matchLabels: application: mariadb - podSelector: matchLabels: application: mariadb-backup ports: - protocol: TCP port: 3306 - protocol: TCP port: 4567 - protocol: TCP port: 80 - protocol: TCP port: 8080 ... ================================================ FILE: values_overrides/mariadb-cluster/prometheus.yaml ================================================ --- monitoring: prometheus: enabled: true manifests: monitoring: prometheus: configmap_bin: true deployment_exporter: true job_user_create: true secret_etc: true service_exporter: true network_policy_exporter: true ... ================================================ FILE: values_overrides/mariadb-cluster/tls.yaml ================================================ --- endpoints: oslo_db: host_fqdn_override: default: tls: secretName: mariadb-tls-direct issuerRef: name: ca-issuer kind: ClusterIssuer manifests: certificates: true ... ================================================ FILE: values_overrides/mariadb-cluster/upscaled.yaml ================================================ --- conf: galera: enabled: true pod: replicas: server: 3 ... ================================================ FILE: values_overrides/masakari/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" masakari_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: masakari: custom.tld/key: "value" ... ================================================ FILE: values_overrides/masakari/mariadb-operator.yaml ================================================ --- conf: masakari: database: connection: null taskflow: connection: null manifests: job_db_init: false etcSources: masakari_api: - masakari-db-conn masakari_db_sync: - masakari-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: masakari namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: masakari namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: masakari-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: masakari-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "masakari" table: "*" username: masakari grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: masakari-db-conn spec: mariaDbRef: name: mariadb username: masakari passwordSecretKeyRef: name: masakari-db-password key: password database: masakari secretName: masakari-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/memcached/apparmor.yaml ================================================ --- pod: security_context: server: container: memcached: appArmorProfile: type: RuntimeDefault memcached_exporter: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/memcached/exporter.yaml ================================================ --- memcached: extraServicePorts: - name: metrics port: 9150 targetPort: 9150 protocol: TCP extraContainers: - name: memcached-exporter image: docker.io/prom/memcached-exporter:v0.15.5 imagePullPolicy: IfNotPresent command: - /bin/memcached_exporter args: - --memcached.address=127.0.0.1:11211 ports: - name: metrics containerPort: 9150 livenessProbe: httpGet: path: /metrics port: 9150 initialDelaySeconds: 15 periodSeconds: 60 timeoutSeconds: 10 readinessProbe: httpGet: path: /metrics port: 9150 initialDelaySeconds: 5 periodSeconds: 60 timeoutSeconds: 10 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: requests: memory: "128Mi" cpu: "500m" limits: memory: "1024Mi" cpu: "2000m" ... ================================================ FILE: values_overrides/memcached/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: memcached: ingress: - from: - podSelector: matchLabels: application: ingress - podSelector: matchLabels: application: keystone - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: glance - podSelector: matchLabels: application: cinder - podSelector: matchLabels: application: barbican - podSelector: matchLabels: application: ceilometer - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: ironic - podSelector: matchLabels: application: magnum - podSelector: matchLabels: application: mistral - podSelector: matchLabels: application: nova - podSelector: matchLabels: application: neutron - podSelector: matchLabels: application: senlin - podSelector: matchLabels: application: placement - podSelector: matchLabels: application: prometheus_memcached_exporter - podSelector: matchLabels: application: aodh - podSelector: matchLabels: application: rally - podSelector: matchLabels: application: memcached ports: - port: 11211 protocol: TCP - port: 9150 protocol: TCP egress: - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/mistral/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble mistral_db_sync: quay.io/airshipit/mistral:2025.1-ubuntu_noble mistral_api: quay.io/airshipit/mistral:2025.1-ubuntu_noble mistral_engine: quay.io/airshipit/mistral:2025.1-ubuntu_noble mistral_event_engine: quay.io/airshipit/mistral:2025.1-ubuntu_noble mistral_executor: quay.io/airshipit/mistral:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/mistral/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble mistral_db_sync: quay.io/airshipit/mistral:2025.2-ubuntu_noble mistral_api: quay.io/airshipit/mistral:2025.2-ubuntu_noble mistral_engine: quay.io/airshipit/mistral:2025.2-ubuntu_noble mistral_event_engine: quay.io/airshipit/mistral:2025.2-ubuntu_noble mistral_executor: quay.io/airshipit/mistral:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/mistral/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" mistral_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: mistral: custom.tld/key: "value" ... ================================================ FILE: values_overrides/mistral/gateway.yaml ================================================ # Gateway API overrides for Mistral. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: workflowv2: host_fqdn_override: public: host: mistral.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: mistral-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.workflowv2.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: mistral-api port: 8989 ... ================================================ FILE: values_overrides/mistral/mariadb-operator.yaml ================================================ --- conf: mistral: database: connection: null manifests: job_db_init: false etcSources: mistral_api: - mistral-db-conn mistral_db_sync: - mistral-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: mistral namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: mistral namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: mistral-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: mistral-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "mistral" table: "*" username: mistral grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: mistral-db-conn spec: mariaDbRef: name: mariadb username: mistral passwordSecretKeyRef: name: mistral-db-password key: password database: mistral secretName: mistral-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/nagios/apparmor.yaml ================================================ --- pod: security_context: monitoring: container: nagios: appArmorProfile: type: RuntimeDefault define_nagios_hosts: appArmorProfile: type: RuntimeDefault apache_proxy: appArmorProfile: type: RuntimeDefault helm_tests: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/nagios/elasticsearch-objects.yaml ================================================ --- conf: nagios: objects: fluent: template: | define service { check_command check_prom_alert!fluentd_not_running!CRITICAL- fluentd is not running on {instance}!OK- Flunetd is working on all nodes check_interval 60 hostgroup_name prometheus-hosts service_description Fluentd_status use notifying_service } define service { check_command check_prom_alert!prom_exporter_fluentd_unavailable!CRITICAL- Fluentd exporter is not collecting metrics for alerting!OK- Fluentd exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_Fluentd use generic-service } elasticsearch: template: | define command { command_line $USER1$/query_elasticsearch.py $USER9$ '$ARG1$' '$ARG2$' '$ARG3$' '$ARG4$' '$ARG5$' --simple_query '$ARG6$' --simple_query_fields '$ARG7$' --match '$ARG8$' --range '$ARG9$' command_name check_es_query } define command { command_line $USER1$/query_elasticsearch.py $USER9$ '$ARG1$' '$ARG2$' '$ARG3$' '$ARG4$' '$ARG5$' --simple_query '$ARG6$' --simple_query_fields '$ARG7$' --query_file '/opt/nagios/etc/objects/query_es_clauses.json' --query_clause '$ARG8$' --match '$ARG9$' --range '$ARG10$' command_name check_es_query_w_file } define service { check_command check_prom_alert!prom_exporter_elasticsearch_unavailable!CRITICAL- Elasticsearch exporter is not collecting metrics for alerting!OK- Elasticsearch exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_Elasticsearch use generic-service } define service { check_command check_prom_alert!es_high_process_open_files_count!CRITICAL- Elasticsearch {host} has high process open file count!OK- Elasticsearch process open file count is normal. hostgroup_name prometheus-hosts service_description ES_high-process-open-file-count use generic-service } define service { check_command check_prom_alert!es_high_process_cpu_percent!CRITICAL- Elasticsearch {instance} has high process CPU percent!OK- Elasticsearch process cpu usage is normal. hostgroup_name prometheus-hosts service_description ES_high-process-cpu-percent use generic-service } define service { check_command check_prom_alert!es_fs_usage_high!CRITICAL- Elasticsearch {instance} has high filesystem usage!OK- Elasticsearch filesystem usage is normal. hostgroup_name prometheus-hosts service_description ES_high-filesystem-usage use generic-service } define service { check_command check_prom_alert!es_unassigned_shards!CRITICAL- Elasticsearch has unassinged shards!OK- Elasticsearch has no unassigned shards. hostgroup_name prometheus-hosts service_description ES_unassigned-shards use generic-service } define service { check_command check_prom_alert!es_cluster_health_timed_out!CRITICAL- Elasticsearch Cluster health status call timedout!OK- Elasticsearch cluster health is retrievable. hostgroup_name prometheus-hosts service_description ES_cluster-health-timedout use generic-service } define service { check_command check_prom_alert!es_cluster_health_status_alert!CRITICAL- Elasticsearch cluster health status is not green. One or more shards or replicas are unallocated!OK- Elasticsearch cluster health is green. hostgroup_name prometheus-hosts service_description ES_cluster-health-status use generic-service } define service { check_command check_prom_alert!es_cluster_health_too_few_nodes_running!CRITICAL- Elasticsearch Cluster has < 3 nodes running!OK- Elasticsearch cluster has 3 or more nodes running. hostgroup_name prometheus-hosts service_description ES_cluster-running-node-count use generic-service } define service { check_command check_prom_alert!es_cluster_health_too_few_data_nodes_running!CRITICAL- Elasticsearch Cluster has < 3 data nodes running!OK- Elasticsearch cluster has 3 or more data nodes running. hostgroup_name prometheus-hosts service_description ES_cluster-running-data-node-count use generic-service } ... ================================================ FILE: values_overrides/nagios/gateway.yaml ================================================ # Gateway API overrides for Nagios. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: nagios: host_fqdn_override: public: host: nagios.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nagios-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.nagios.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: nagios-metrics port: 8000 ... ================================================ FILE: values_overrides/nagios/openstack-objects.yaml ================================================ --- conf: nagios: objects: mariadb: template: | define service { check_command check_prom_alert!prom_exporter_mariadb_unavailable!CRITICAL- MariaDB exporter is not collecting metrics for alerting!OK- MariaDB exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_MariaDB use generic-service } define service { check_command check_prom_alert!mariadb_table_lock_wait_high!CRITICAL- Mariadb has high number of table lock waits!OK- No issues found with table lock waits. hostgroup_name prometheus-hosts service_description Mariadb_table-lock-waits-high use generic-service } define service { check_command check_prom_alert!mariadb_node_not_ready!CRITICAL- Mariadb {instance} is not ready!OK- All galera cluster nodes are ready. hostgroup_name prometheus-hosts service_description Mariadb_node-ready use generic-service } define service { check_command check_prom_alert!mariadb_galera_node_out_of_sync!CRITICAL- Mariadb {instance} is out of sync!OK- All galera cluster nodes are in sync hostgroup_name prometheus-hosts service_description Mariadb_node-synchronized use generic-service } define service { check_command check_prom_alert!mariadb_innodb_replication_fallen_behind!CRITICAL- Innodb replication has fallen behind and not recovering!OK- innodb replication lag is nominal. hostgroup_name prometheus-hosts service_description Mariadb_innodb-replication-lag use generic-service } rabbitmq: template: | define service { check_command check_prom_alert!rabbitmq_network_pratitions_detected!CRITICAL- Rabbitmq instance {instance} has network partitions!OK- no network partitions detected in rabbitmq hostgroup_name prometheus-hosts service_description Rabbitmq_network-partitions-exist use generic-service } define service { check_command check_prom_alert!rabbitmq_down!CRITICAL- Rabbitmq instance {instance} is down!OK- rabbitmq is available hostgroup_name prometheus-hosts service_description Rabbitmq_up use generic-service } define service { check_command check_prom_alert!rabbitmq_file_descriptor_usage_high!CRITICAL- Rabbitmq instance {instance} has file desciptor usage more than 80 percent!OK- rabbitmq file descriptor usage is normal hostgroup_name prometheus-hosts service_description Rabbitmq_file-descriptor-usage use generic-service } define service { check_command check_prom_alert!rabbitmq_node_disk_free_alarm!CRITICAL- Rabbitmq instance {instance} has a disk usage alarm!OK- rabbitmq node disk has no alarms hostgroup_name prometheus-hosts service_description Rabbitmq_node-disk-alarm use generic-service } define service { check_command check_prom_alert!rabbitmq_node_memory_alarm!CRITICAL- Rabbitmq instance {instance} has a memory alarm!OK- rabbitmq node memory has no alarms hostgroup_name prometheus-hosts service_description Rabbitmq_node-memory-alarm use generic-service } define service { check_command check_prom_alert!rabbitmq_less_than_3_nodes!CRITICAL- Rabbitmq has less than 3 nodes to serve!OK- rabbitmq has atleast 3 nodes serving hostgroup_name prometheus-hosts service_description Rabbitmq_high-availability use generic-service } define service { check_command check_prom_alert!rabbitmq_queue_messages_returned_high!CRITICAL- Rabbitmq has high percent of messages being returned!OK- rabbitmq messages are consumed and low or no returns exist. hostgroup_name prometheus-hosts service_description Rabbitmq_message-return-percent use generic-service } define service { check_command check_prom_alert!rabbitmq_consumers_low_utilization!CRITICAL- Rabbitmq consumer message consumption rate is slow!OK- rabbitmq message consumption speed is normal hostgroup_name prometheus-hosts service_description Rabbitmq_consumer-utilization use generic-service } define service { check_command check_prom_alert!rabbitmq_high_message_load!CRITICAL- Rabbitmq unacknowledged message count is high!OK- rabbitmq unacknowledged message count is high hostgroup_name prometheus-hosts service_description Rabbitmq_rabbitmq-queue-health use generic-service } openstack: template: | define service { check_command check_prom_alert!os_glance_api_availability!CRITICAL- Glance API at {url} is not available!OK- Glance API is available check_interval 60 hostgroup_name prometheus-hosts service_description API_glance use notifying_service } define service { check_command check_prom_alert!os_nova_api_availability!CRITICAL- Nova API at {url} is not available!OK- Nova API is available check_interval 60 hostgroup_name prometheus-hosts service_description API_nova use notifying_service } define service { check_command check_prom_alert!os_keystone_api_availability!CRITICAL- Keystone API at {url} is not available!OK- Keystone API is available check_interval 60 hostgroup_name prometheus-hosts service_description API_keystone use notifying_service } define service { check_command check_prom_alert!os_neutron_api_availability!CRITICAL- Neutron API at {url} is not available!OK- Neutron API is available check_interval 60 hostgroup_name prometheus-hosts service_description API_neutron use notifying_service } define service { check_command check_prom_alert!os_neutron_metadata_agent_availability!CRITICAL- Some Neutron metadata agents are not available!OK- All the neutron metadata agents are up check_interval 60 hostgroup_name prometheus-hosts service_description Service_neutron-metadata-agent use notifying_service } define service { check_command check_prom_alert!os_neutron_openvswitch_agent_availability!CRITICAL- Some Neutron openvswitch agents are not available!OK- All the neutron openvswitch agents are up check_interval 60 hostgroup_name prometheus-hosts service_description Service_neutron-openvswitch-agent use notifying_service } define service { check_command check_prom_alert!os_neutron_dhcp_agent_availability!CRITICAL- Some Neutron dhcp agents are not available!OK- All the neutron dhcp agents are up check_interval 60 hostgroup_name prometheus-hosts service_description Service_neutron-dhcp-agent use notifying_service } define service { check_command check_prom_alert!os_neutron_l3_agent_availability!CRITICAL- Some Neutron dhcp agents are not available!OK- All the neutron l3 agents are up check_interval 60 hostgroup_name prometheus-hosts service_description Service_neutron-l3-agent use notifying_service } define service { check_command check_prom_alert!os_swift_api_availability!CRITICAL- Swift API at {url} is not available!OK- Swift API is available check_interval 60 hostgroup_name prometheus-hosts service_description API_swift use notifying_service } define service { check_command check_prom_alert!os_cinder_api_availability!CRITICAL- Cinder API at {url} is not available!OK- Cinder API is available hostgroup_name prometheus-hosts service_description API_cinder use notifying_service } define service { check_command check_prom_alert!os_heat_api_availability!CRITICAL- Heat API at {url} is not available!OK- Heat API is available check_interval 60 hostgroup_name prometheus-hosts service_description API_heat use notifying_service } define service { check_command check_prom_alert!os_cinder_api_availability!CRITICAL- Cinder API at {url} is not available!OK- Cinder API is available check_interval 60 hostgroup_name prometheus-hosts service_description API_cinder use notifying_service } define service { check_command check_prom_alert!os_cinder_scheduler_availability!CRITICAL- Cinder scheduler is not available!OK- Cinder scheduler is available check_interval 60 hostgroup_name prometheus-hosts service_description Service_cinder-scheduler use notifying_service } define service { check_command check_prom_alert!os_nova_compute_down!CRITICAL- nova-compute services are down on certain hosts!OK- nova-compute services are up on all hosts check_interval 60 hostgroup_name prometheus-hosts service_description Service_nova-compute use notifying_service } define service { check_command check_prom_alert!os_nova_conductor_down!CRITICAL- nova-conductor services are down on certain hosts!OK- nova-conductor services are up on all hosts check_interval 60 hostgroup_name prometheus-hosts service_description Service_nova-conductor use notifying_service } define service { check_command check_prom_alert!os_nova_consoleauth_down!CRITICAL- nova-consoleauth services are down on certain hosts!OK- nova-consoleauth services are up on all hosts check_interval 60 hostgroup_name prometheus-hosts service_description Service_nova-consoleauth use notifying_service } define service { check_command check_prom_alert!openstack_nova_scheduler_down!CRITICAL- nova-scheduler services are down on certain hosts!OK- nova-scheduler services are up on all hosts check_interval 60 hostgroup_name prometheus-hosts service_description Service_nova-scheduler use notifying_service } define service { check_command check_prom_alert!os_vm_vcpu_usage_high!CRITICAL- vcpu usage for openstack VMs is more than 80 percent of available!OK- Openstack VMs vcpu usage is less than 80 percent of available. check_interval 60 hostgroup_name prometheus-hosts service_description OS-Total-Quota_VCPU-usage use notifying_service } define service { check_command check_prom_alert!os_vm_ram_usage_high!CRITICAL- RAM usage for openstack VMs is more than 80 percent of available!OK- Openstack VMs RAM usage is less than 80 percent of available. check_interval 60 hostgroup_name prometheus-hosts service_description OS-Total-Quota_RAM-usage use notifying_service } define service { check_command check_prom_alert!os_vm_disk_usage_high!CRITICAL- Disk usage for openstack VMs is more than 80 percent of available!OK- Openstack VMs Disk usage is less than 80 percent of available. check_interval 60 hostgroup_name prometheus-hosts service_description OS-Total-Quota_Disk-usage use notifying_service } define service { check_command check_prom_alert!prom_exporter_openstack_unavailable!CRITICAL- Openstack exporter is not collecting metrics for alerting!OK- Openstack exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_Openstack use generic-service } ... ================================================ FILE: values_overrides/nagios/postgresql-objects.yaml ================================================ --- conf: nagios: objects: postgresql: template: | define service { check_command check_prom_alert!prom_exporter_postgresql_unavailable!CRITICAL- Postgresql exporter is not collecting metrics for alerting!OK- Postgresql exporter metrics are available. hostgroup_name prometheus-hosts service_description Prometheus-exporter_Postgresql use generic-service } define service { check_command check_prom_alert!pg_replication_fallen_behind!CRITICAL- Postgres Replication lag is over 2 minutes!OK- postgresql replication lag is nominal. hostgroup_name prometheus-hosts service_description Postgresql_replication-lag use generic-service } define service { check_command check_prom_alert!pg_connections_too_high!CRITICAL- Postgres has more than 95% of available connections in use.!OK- postgresql open connections are within bounds. hostgroup_name prometheus-hosts service_description Postgresql_connections use generic-service } define service { check_command check_prom_alert!pg_deadlocks_detected!CRITICAL- Postgres server is experiencing deadlocks!OK- postgresql is not showing any deadlocks. hostgroup_name prometheus-hosts service_description Postgresql_deadlocks use generic-service } ... ================================================ FILE: values_overrides/nagios/tls.yaml ================================================ --- endpoints: monitoring: scheme: default: "https" port: http: default: 443 elasticsearch: scheme: default: "https" port: http: default: 443 manifests: certificates: true ... ================================================ FILE: values_overrides/neutron/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" neutron_db_sync: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_dhcp: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_l3: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_l2gw: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_linuxbridge_agent: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_metadata: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_ovn_metadata: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_openvswitch_agent: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_server: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_rpc_server: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_bagpipe_bgp: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" neutron_netns_cleanup_cron: "quay.io/airshipit/neutron:2024.2-ubuntu_jammy" ... ================================================ FILE: values_overrides/neutron/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" neutron_db_sync: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_dhcp: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_l3: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_l2gw: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_linuxbridge_agent: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_metadata: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_ovn_metadata: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_openvswitch_agent: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_server: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_rpc_server: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_bagpipe_bgp: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" neutron_netns_cleanup_cron: "quay.io/airshipit/neutron:2025.1-ubuntu_jammy" ... ================================================ FILE: values_overrides/neutron/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" neutron_db_sync: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_dhcp: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_l3: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_l2gw: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_linuxbridge_agent: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_metadata: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_ovn_metadata: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_openvswitch_agent: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_server: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_rpc_server: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_bagpipe_bgp: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" neutron_netns_cleanup_cron: "quay.io/airshipit/neutron:2025.1-ubuntu_noble" ... ================================================ FILE: values_overrides/neutron/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" neutron_db_sync: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_dhcp: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_l3: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_l2gw: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_linuxbridge_agent: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_metadata: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_ovn_metadata: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_openvswitch_agent: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_server: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_rpc_server: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_bagpipe_bgp: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" neutron_netns_cleanup_cron: "quay.io/airshipit/neutron:2025.2-ubuntu_noble" ... ================================================ FILE: values_overrides/neutron/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" neutron_server: another.tld/foo: "bar" neutron_rpc_server: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: neutron: custom.tld/key: "value" tls: network_server_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/neutron/apparmor.yaml ================================================ --- pod: security_context: neutron_dhcp_agent: container: neutron_dhcp_agent: appArmorProfile: type: RuntimeDefault neutron_dhcp_agent_init: appArmorProfile: type: RuntimeDefault neutron_l3_agent: container: neutron_l3_agent: appArmorProfile: type: RuntimeDefault neutron_l3_agent_init: appArmorProfile: type: RuntimeDefault neutron_lb_agent: container: neutron_lb_agent: appArmorProfile: type: RuntimeDefault neutron_lb_agent_init: appArmorProfile: type: RuntimeDefault neutron_lb_agent_kernel_modules: appArmorProfile: type: RuntimeDefault neutron_metadata_agent: container: neutron_metadata_agent_init: appArmorProfile: type: RuntimeDefault neutron_ovs_agent: container: neutron_ovs_agent: appArmorProfile: type: RuntimeDefault neutron_openvswitch_agent_kernel_modules: appArmorProfile: type: RuntimeDefault neutron_ovs_agent_init: appArmorProfile: type: RuntimeDefault netoffload: appArmorProfile: type: RuntimeDefault neutron_sriov_agent: container: neutron_sriov_agent: appArmorProfile: type: RuntimeDefault neutron_sriov_agent_init: appArmorProfile: type: RuntimeDefault neutron_netns_cleanup_cron: container: neutron_netns_cleanup_cron: appArmorProfile: type: RuntimeDefault neutron_server: container: neutron_server: appArmorProfile: type: RuntimeDefault nginx: appArmorProfile: type: RuntimeDefault neutron_rpc_server: container: neutron_rpc_server: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/neutron/bagpipe_bgp.yaml ================================================ --- conf: neutron: DEFAULT: service_plugins: router, bgpvpn service_providers: service_provider: BGPVPN:BaGPipe:networking_bgpvpn.neutron.services.service_drivers.bagpipe.bagpipe_v2.BaGPipeBGPVPNDriver:default plugins: openvswitch_agent: agent: extensions: bagpipe_bgpvpn bagpipe_bgp: bgp: local_address: 192.168.143.88 # IP address for mpls/gre tunnels peers: 192.168.143.96 # IP addresses of BGP peers my_as: 23242 # Autonomous System number enable_rtc: true # Enable RT Constraint (RFC4684) common: root_helper: sudo /var/lib/openstack/bin/neutron-rootwrap /etc/neutron/rootwrap.conf api: host: localhost port: 8082 dataplane_driver_ipvpn: dataplane_driver: ovs ovs_bridge: br-mpls mpls_interface: '*gre*' proxy_arp: false auto_bridge_add: br-mpls: null manifests: daemonset_bagpipe_bgp: true ... ================================================ FILE: values_overrides/neutron/dpdk-bond.yaml ================================================ --- network: interface: tunnel: br-phy-bond0 conf: plugins: openvswitch_agent: agent: tunnel_types: vxlan ovs: bridge_mappings: public:br-ex datapath_type: netdev vhostuser_socket_dir: /var/run/openvswitch/vhostuser ovs_dpdk: enabled: true driver: uio_pci_generic nics: [] bonds: # CHANGE-ME: modify below parameters according to your hardware - name: dpdkbond0 bridge: br-phy-bond0 # The IP from the first nic in nics list shall be used migrate_ip: true ovs_options: "bond_mode=active-backup" nics: - name: dpdk_b0s0 pci_id: '0000:00:05.0' - name: dpdk_b0s1 pci_id: '0000:00:06.0' bridges: - name: br-phy-bond0 ... ================================================ FILE: values_overrides/neutron/dpdk.yaml ================================================ --- network: interface: tunnel: null conf: plugins: openvswitch_agent: agent: tunnel_types: vxlan ovs: bridge_mappings: public:br-ex datapath_type: netdev vhostuser_socket_dir: /var/run/openvswitch/vhostuser ovs_dpdk: enabled: true driver: uio_pci_generic nics: [] # CHANGE-ME: modify pci_id according to your hardware # - name: dpdk0 # pci_id: '0000:05:00.0' # bridge: br-tun # migrate_ip: true bridges: - name: br-tun bonds: [] ... ================================================ FILE: values_overrides/neutron/gate.yaml ================================================ --- network: interface: tunnel: docker0 conf: neutron: DEFAULT: l3_ha: False max_l3_agents_per_router: 1 l3_ha_network_type: vxlan dhcp_agents_per_network: 1 plugins: ml2_conf: ml2_type_flat: flat_networks: public openvswitch_agent: agent: tunnel_types: vxlan ovs: bridge_mappings: public:br-ex linuxbridge_agent: linux_bridge: bridge_mappings: public:br-ex ... ================================================ FILE: values_overrides/neutron/gateway.yaml ================================================ # Gateway API overrides for Neutron. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: network: host_fqdn_override: public: host: neutron.openstack-helm.org manifests: ingress_server: false service_ingress_server: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: neutron-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.network.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: neutron-server port: 9696 ... ================================================ FILE: values_overrides/neutron/l2gateway.yaml ================================================ --- conf: neutron: DEFAULT: service_plugins: router, networking_l2gw.services.l2gateway.plugin.L2GatewayPlugin plugins: l2gateway: DEFAULT: quota_l2_gateway: 10 periodic_monitoring_interval: 5 service_providers: service_provider: L2GW:l2gw:networking_l2gw.services.l2gateway.service_drivers.rpc_l2gw.L2gwRpcDriver:default l2gateway_agent: DEFAULT: debug: false ovsdb: # ::[,::] # - ovsdb_name: a symbolic name that helps identifies keys and certificate files # - ip address: the address or dns name for the ovsdb server # - port: the port (ssl is supported) ovsdb_hosts: ovsdbx:127.0.0.1:6632 socket_timeout: 30 manifests: daemonset_l2gw_agent: true ... ================================================ FILE: values_overrides/neutron/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" neutron_db_sync: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_dhcp: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_l3: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_l2gw: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_linuxbridge_agent: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_metadata: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_ovn_metadata: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_openvswitch_agent: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_server: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_rpc_server: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_bagpipe_bgp: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" neutron_netns_cleanup_cron: "quay.io/airshipit/neutron:2025.1-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/neutron/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" neutron_db_sync: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_dhcp: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_l3: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_l2gw: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_linuxbridge_agent: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_metadata: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_ovn_metadata: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_openvswitch_agent: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_server: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_rpc_server: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_bagpipe_bgp: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" neutron_netns_cleanup_cron: "quay.io/airshipit/neutron:2025.2-ubuntu_noble_loci" ... ================================================ FILE: values_overrides/neutron/mariadb-operator.yaml ================================================ --- conf: neutron: database: connection: null manifests: job_db_init: false etcSources: neutron_api: - neutron-db-conn neutron_db_sync: - neutron-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: neutron namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: neutron namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: neutron-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: neutron-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "neutron" table: "*" username: neutron grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: neutron-db-conn spec: mariaDbRef: name: mariadb username: neutron passwordSecretKeyRef: name: neutron-db-password key: password database: neutron secretName: neutron-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/neutron/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: neutron: egress: - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/neutron/ovn.yaml ================================================ --- network: backend: - ovn conf: neutron: DEFAULT: router_distributed: True service_plugins: ovn-router l3_ha_network_type: geneve plugins: ml2_conf: ml2: extension_drivers: port_security type_drivers: flat,vxlan,geneve tenant_network_types: geneve ovn: ovn_l3_scheduler: leastloaded dns_servers: 8.8.8.8,1.1.1.1 neutron_sync_mode: repair manifests: daemonset_dhcp_agent: false daemonset_l3_agent: false daemonset_metadata_agent: false daemonset_netns_cleanup_cron: false daemonset_ovs_agent: false deployment_rpc_server: false daemonset_ovn_metadata_agent: true ... ================================================ FILE: values_overrides/neutron/ovn_vpn.yaml ================================================ --- network: backend: - ovn conf: neutron: DEFAULT: router_distributed: true service_plugins: ovn-router,ovn-vpnaas l3_ha_network_type: geneve ovn_vpn_agent: service_providers: service_provider: VPN:strongswan:neutron_vpnaas.services.vpn.service_drivers.ovn_ipsec.IPsecOvnVPNDriver:default plugins: ml2_conf: ml2: extension_drivers: port_security type_drivers: flat,vxlan,geneve tenant_network_types: geneve ovn: ovn_l3_scheduler: leastloaded dns_servers: 8.8.8.8,1.1.1.1 neutron_sync_mode: repair manifests: daemonset_dhcp_agent: false daemonset_l3_agent: false daemonset_metadata_agent: false daemonset_netns_cleanup_cron: false daemonset_ovs_agent: false deployment_rpc_server: false daemonset_ovn_metadata_agent: true daemonset_ovn_vpn_agent: true ... ================================================ FILE: values_overrides/neutron/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: neutron: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # neutron: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/neutron/shared-sriov-ovs-dpdk-bond.yaml ================================================ --- network: interface: sriov: - device: enp3s0f0 num_vfs: 32 promisc: false - device: enp66s0f1 num_vfs: 32 promisc: false tunnel: br-phy-bond0 backend: - openvswitch - sriov conf: auto_bridge_add: br-ex: null neutron: DEFAULT: l3_ha: False max_l3_agents_per_router: 1 l3_ha_network_type: vxlan dhcp_agents_per_network: 1 service_plugins: router plugins: ml2_conf: ml2: mechanism_drivers: l2population,openvswitch,sriovnicswitch type_drivers: vlan,flat,vxlan tenant_network_types: vxlan ml2_type_flat: flat_networks: public ml2_type_vlan: network_vlan_ranges: ovsnet:2:4094,sriovnet1:100:4000,sriovnet2:100:4000 openvswitch_agent: default: ovs_vsctl_timeout: 30 agent: tunnel_types: vxlan securitygroup: enable_security_group: False firewall_driver: neutron.agent.firewall.NoopFirewallDriver ovs: bridge_mappings: public:br-ex,ovsnet:br-phy-bond0 datapath_type: netdev vhostuser_socket_dir: /var/run/openvswitch/vhostuser of_connect_timeout: 60 of_request_timeout: 30 sriov_agent: securitygroup: firewall_driver: neutron.agent.firewall.NoopFirewallDriver sriov_nic: physical_device_mappings: sriovnet1:enp3s0f0,sriovnet2:enp66s0f1 exclude_devices: enp3s0f0:0000:00:05.1,enp66s0f1:0000:00:06.1 ovs_dpdk: enabled: true driver: uio_pci_generic nics: [] bonds: # CHANGE-ME: modify below parameters according to your hardware - name: dpdkbond0 bridge: br-phy-bond0 mtu: 9000 # The IP from the first nic in nics list shall be used migrate_ip: true n_rxq: 2 n_rxq_size: 1024 n_txq_size: 1024 ovs_options: "bond_mode=active-backup" nics: - name: dpdk_b0s0 pci_id: '0000:00:05.0' vf_index: 0 - name: dpdk_b0s1 pci_id: '0000:00:06.0' vf_index: 0 bridges: - name: br-phy-bond0 modules: - name: dpdk log_level: info # In case of shared profile (sriov + ovs-dpdk), sriov agent should finish # first so as to let it configure the SRIOV VFs before ovs-agent tries to # bind it with DPDK driver. dependencies: dynamic: targeted: openvswitch: ovs_agent: pod: - requireSameNode: true labels: application: neutron component: neutron-sriov-agent ... ================================================ FILE: values_overrides/neutron/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt neutron: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/neutron/tls.yaml ================================================ --- images: tags: nginx: docker.io/nginx:1.18.0 network: server: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" pod: security_context: neutron_server: pod: runAsUser: 0 container: neutron_server: readOnlyRootFilesystem: false neutron_rpc_server: pod: runAsUser: 0 container: neutron_rpc_server: readOnlyRootFilesystem: false resources: nginx: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" conf: neutron_api_uwsgi: uwsgi: http-socket: 127.0.0.1:9696 nginx: | worker_processes 1; daemon off; user nginx; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65s; tcp_nodelay on; log_format main '[nginx] method=$request_method path=$request_uri ' 'status=$status upstream_status=$upstream_status duration=$request_time size=$body_bytes_sent ' '"$remote_user" "$http_referer" "$http_user_agent"'; access_log /dev/stdout main; upstream websocket { server 127.0.0.1:$PORT; } server { server_name {{ printf "%s.%s.svc.%s" "${SHORTNAME}" .Release.Namespace .Values.endpoints.cluster_domain_suffix }}; listen $POD_IP:$PORT ssl; client_max_body_size 0; ssl_certificate /etc/nginx/certs/tls.crt; ssl_certificate_key /etc/nginx/certs/tls.key; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; location / { proxy_pass_request_headers on; proxy_http_version 1.1; proxy_pass http://websocket; proxy_read_timeout 90; } } } neutron: DEFAULT: bind_host: 127.0.0.1 nova: cafile: /etc/neutron/certs/ca.crt keystone_authtoken: cafile: /etc/neutron/certs/ca.crt oslo_messaging_rabbit: ssl: true ssl_ca_file: /etc/rabbitmq/certs/ca.crt ssl_cert_file: /etc/rabbitmq/certs/tls.crt ssl_key_file: /etc/rabbitmq/certs/tls.key metadata_agent: DEFAULT: auth_ca_cert: /etc/ssl/certs/openstack-helm.crt nova_metadata_port: 443 nova_metadata_protocol: https endpoints: compute: scheme: default: https port: api: public: 443 compute_metadata: hosts: default: metadata scheme: default: https port: metadata: default: 443 identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt neutron: cacert: /etc/ssl/certs/openstack-helm.crt nova: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt scheme: default: https port: api: default: 443 network: host_fqdn_override: default: tls: secretName: neutron-tls-server issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https port: api: public: 443 ingress: port: ingress: default: 443 oslo_messaging: port: https: default: 15680 manifests: certificates: true ... ================================================ FILE: values_overrides/nova/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" nova_api: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_cell_setup: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_cell_setup_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" nova_compute: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_compute_ssh: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_conductor: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_db_sync: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_novncproxy: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_novncproxy_assets: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_scheduler: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_spiceproxy: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_spiceproxy_assets: "quay.io/airshipit/nova:2024.2-ubuntu_jammy" nova_service_cleaner: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/nova/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" nova_api: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_cell_setup: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_cell_setup_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" nova_compute: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_compute_ssh: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_conductor: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_db_sync: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_novncproxy: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_novncproxy_assets: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_scheduler: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_spiceproxy: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_spiceproxy_assets: "quay.io/airshipit/nova:2025.1-ubuntu_jammy" nova_service_cleaner: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/nova/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" nova_api: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_cell_setup: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_cell_setup_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" nova_compute: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_compute_ssh: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_conductor: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_db_sync: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_novncproxy: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_novncproxy_assets: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_scheduler: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_spiceproxy: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_spiceproxy_assets: "quay.io/airshipit/nova:2025.1-ubuntu_noble" nova_service_cleaner: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/nova/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" nova_api: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_cell_setup: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_cell_setup_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" nova_compute: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_compute_ssh: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_conductor: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_db_sync: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_novncproxy: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_novncproxy_assets: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_scheduler: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_spiceproxy: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_spiceproxy_assets: "quay.io/airshipit/nova:2025.2-ubuntu_noble" nova_service_cleaner: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/nova/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" nova_api_osapi: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: nova: custom.tld/key: "value" tls: compute_osapi_public: custom.tld/key: "value" ssh: keys: custom.tld/key: "value" ... ================================================ FILE: values_overrides/nova/apparmor.yaml ================================================ --- pod: security_context: nova: container: nova_compute: appArmorProfile: type: RuntimeDefault nova_compute_init: appArmorProfile: type: RuntimeDefault nova_compute_vnc_init: appArmorProfile: type: RuntimeDefault nova_api: appArmorProfile: type: RuntimeDefault nova_api_metadata_init: appArmorProfile: type: RuntimeDefault nova_osapi: appArmorProfile: type: RuntimeDefault nova_conductor: appArmorProfile: type: RuntimeDefault nova_novncproxy: appArmorProfile: type: RuntimeDefault nova_novncproxy_init_assets: appArmorProfile: type: RuntimeDefault nova_novncproxy_init: appArmorProfile: type: RuntimeDefault nova_scheduler: appArmorProfile: type: RuntimeDefault nova_cell_setup: container: nova_cell_setup: appArmorProfile: type: RuntimeDefault nova_cell_setup_init: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/nova/cntt.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- conf: nova: DEFAULT: reserved_huge_pages: type: multistring values: - node:0,size:1GB,count:4 - node:1,size:1GB,count:4 reserved_host_memory_mb: 512 ... ================================================ FILE: values_overrides/nova/dpdk.yaml ================================================ --- conf: nova: libvirt: virt_type: kvm cpu_mode: host-model ... ================================================ FILE: values_overrides/nova/gateway.yaml ================================================ # Gateway API overrides for Nova. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: compute: host_fqdn_override: public: host: nova.openstack-helm.org compute_metadata: host_fqdn_override: public: host: metadata.openstack-helm.org compute_novnc_proxy: host_fqdn_override: public: host: novncproxy.openstack-helm.org compute_serial_proxy: host_fqdn_override: public: host: serialproxy.openstack-helm.org compute_spice_proxy: host_fqdn_override: public: host: spiceproxy.openstack-helm.org manifests: ingress_metadata: false ingress_novncproxy: false ingress_serialproxy: false ingress_spiceproxy: false ingress_osapi: false service_ingress_metadata: false service_ingress_novncproxy: false service_ingress_serialproxy: false service_ingress_spiceproxy: false service_ingress_osapi: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nova-route-osapi namespace: openstack spec: hostnames: - "{{ .Values.endpoints.compute.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: nova-api port: 8774 - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nova-route-metadata namespace: openstack spec: hostnames: - "{{ .Values.endpoints.compute_metadata.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: nova-metadata port: 8775 - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nova-route-novncproxy namespace: openstack spec: hostnames: - "{{ .Values.endpoints.compute_novnc_proxy.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: nova-novncproxy port: 6080 - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nova-route-serialproxy namespace: openstack spec: hostnames: - "{{ .Values.endpoints.compute_serial_proxy.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: nova-serialproxy port: 6083 - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: nova-route-spiceproxy namespace: openstack spec: hostnames: - "{{ .Values.endpoints.compute_spice_proxy.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: nova-spiceproxy port: 6082 ... ================================================ FILE: values_overrides/nova/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" nova_api: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_cell_setup: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_cell_setup_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" nova_compute: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_compute_ssh: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_conductor: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_db_sync: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_novncproxy: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_novncproxy_assets: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_scheduler: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_spiceproxy: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_spiceproxy_assets: "quay.io/airshipit/nova:2025.1-ubuntu_noble_loci" nova_service_cleaner: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/nova/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" nova_api: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_cell_setup: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_cell_setup_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" nova_compute: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_compute_ssh: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_conductor: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_db_sync: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_novncproxy: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_novncproxy_assets: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_scheduler: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_spiceproxy: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_spiceproxy_assets: "quay.io/airshipit/nova:2025.2-ubuntu_noble_loci" nova_service_cleaner: "quay.io/airshipit/ceph-config-helper:latest-ubuntu_jammy" ... ================================================ FILE: values_overrides/nova/mariadb-operator.yaml ================================================ --- conf: nova: database: connection: null api_database: connection: null cell0_database: connection: null manifests: job_db_init: false secret_db_api: false secret_db_cell0: false etcSources: nova_api_ospi: - nova-db-conn - nova-api-db-conn - nova-cell0-db-conn nova_api_metadata: - nova-db-conn - nova-api-db-conn - nova-cell0-db-conn nova_conductor: - nova-db-conn - nova-api-db-conn - nova-cell0-db-conn nova_scheduler: - nova-db-conn - nova-api-db-conn - nova-cell0-db-conn nova_cell_setup: - nova-db-conn - nova-api-db-conn - nova-cell0-db-conn nova_db_sync: - nova-db-conn - nova-api-db-conn - nova-cell0-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: nova namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: nova_api namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: nova_cell0 namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: nova namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: nova-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: nova namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "nova" table: "*" username: nova grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: nova-api namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "nova_api" table: "*" username: nova grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: nova-cell0 namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "nova_cell0" table: "*" username: nova grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: nova-db-conn spec: mariaDbRef: name: mariadb username: nova passwordSecretKeyRef: name: nova-db-password key: password database: nova secretName: nova-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: nova-api-db-conn spec: mariaDbRef: name: mariadb username: nova passwordSecretKeyRef: name: nova-db-password key: password database: nova secretName: nova-api-db-conn secretTemplate: key: api_db_conn.conf format: | [api_database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: nova-db-cell0-conn spec: mariaDbRef: name: mariadb username: nova passwordSecretKeyRef: name: nova-db-password key: password database: nova_cell0 secretName: nova-cell0-db-conn secretTemplate: key: cell0_db_conn.conf format: | [cell0_database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/nova/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: nova: egress: - to: - podSelector: matchLabels: application: nova - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/nova/opensuse_15.yaml ================================================ --- conf: software: apache2: binary: apache2ctl start_parameters: -DFOREGROUND -k start site_dir: /etc/apache2/vhosts.d conf_dir: /etc/apache2/conf.d a2enmod: - version security: | Options Indexes FollowSymLinks AllowOverride All Require all granted Order allow,deny Allow from all nova: DEFAULT: mkisofs_cmd: mkisofs ... ================================================ FILE: values_overrides/nova/ovn.yaml ================================================ --- network: backend: - ovn conf: nova: DEFAULT: vif_plugging_is_fatal: true vif_plugging_timeout: 300 ... ================================================ FILE: values_overrides/nova/rabbitmq4.yaml ================================================ --- # Upgrading from rabbitmq 3.x to 4.x requires: # 1: upgrading to the latest rabbitmq 3.x release and enabling all feature flags # 2: removing all rabbitmq 3.x openstack vhost ha policies # 3: setting rabbit_ha_queues to false in all openstack component configs # 4: wiping the rabbitmq database if rabbit_ha_queues and/or vhost ha policies were used with 3.x conf: nova: oslo_messaging_rabbit: rabbit_ha_queues: false # Note: rabbit_ha_queues is true by default for all openstack components in openstack-helm # Steps to wipe rabbitmq database: # 1: rabbitmqctl stop_app # 2: rabbitmqctl force_reset # 3: rabbitmqctl start_app # 4: rerun all openstack component rabbit-init jobs to recreate rabbitmq vhosts and users # Note: rabbitmq classic v2 vs quorum queues # With rabbitmq 4.x classic queues have been replaced with classic v2 queues. Classic v2 queues # do not support high availability. For HA, quorum queues must be used. Quorum queues are HA by default. # Classic v2 queues are the default in Rabbitmq 4.x. # # To enable quorum queues with rabbitmq 4.x you can use: # # conf: # nova: # oslo_messaging_rabbit: # rabbit_ha_queues: false # rabbit_quorum_queues: true # rabbit_transient_quorum_queue: true # use_queue_manager: true ... ================================================ FILE: values_overrides/nova/ssh.yaml ================================================ --- network: ssh: enabled: true public_key: | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfgGkoPxu6jVqyBTGDlhGqoFFaTymMOH3pDRzrzXCVodqrtv1heBAyi7L63+MZ+m/facDDo43hWzhFLmmMgD00AS7L+VH+oeEwKVCfq0HN3asKLadpweBQVAkGX7PzjRKF25qj6J7iVpKAf1NcnJCsWL3b+wC9mwK7TmupOmWra8BrfP7Fvek1RLx3lwk+ZZ9lUlm6o+jwXn/9rCEFa7ywkGpdrPRBNHQshGjDlJPi15boXIKxOmoZ/DszkJq7iLYQnwa4Kdb0dJ9OE/l2LLBiEpkMlTnwXA7QCS5jEHXwW78b4BOZvqrFflga+YldhDmkyRRfnhcF5Ok2zQmx9Q+t root@openstack-helm private_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA34BpKD8buo1asgUxg5YRqqBRWk8pjDh96Q0c681wlaHaq7b9 YXgQMouy+t/jGfpv32nAw6ON4Vs4RS5pjIA9NAEuy/lR/qHhMClQn6tBzd2rCi2n acHgUFQJBl+z840Shduao+ie4laSgH9TXJyQrFi92/sAvZsCu05rqTplq2vAa3z+ xb3pNUS8d5cJPmWfZVJZuqPo8F5//awhBWu8sJBqXaz0QTR0LIRow5ST4teW6FyC sTpqGfw7M5Cau4i2EJ8GuCnW9HSfThP5diywYhKZDJU58FwO0AkuYxB18Fu/G+AT mb6qxX5YGvmJXYQ5pMkUX54XBeTpNs0JsfUPrQIDAQABAoIBAFkEFd3XtL2KSxMY Cm50OLkSfRRQ7yVP4qYNePVZr3uJKUS27xgA78KR7UkKHrNcEW6T+hhxbbLR2AmF wLga40VxKyhGNqgJ5Vx/OAM//Ed4AAVfxYvTkfmsXqPRPiTEjRoPKvoZTh6riFHx ZExAd0aNWaDhyZu6v03GoA6YmaG53CLhUpDjIEpAHT8Q5fiukvpvFNAkSpSU3wWW YD14S5BTXx8Z7v5mNgbxzDIST9P6oGm9jOoMJJCxu3KVF5Xh6k23DP1wukiWNypJ b7dzfE8/NZUZ15Du4g1ZXHZyOATwN+4GQi1tV+oB1o6wI6829lpIMlsmqHhrw867 942SmakCgYEA9R1xFEEVRavBGIUeg/NMbFP+Ssl2DljAdnmcOASCxAFqCx6y3WSK P2xWTD/MCG/uz627EVp+lfbapZimm171rUMpVCqTa5tH+LZ+Lbl+rjoLwSWVqySK MGyIEzpPLq5PrpGdUghZNsGAG7kgTarJM5SYyA+Esqr8AADjDrZdmzcCgYEA6W1C h9nU5i04UogndbkOiDVDWn0LnjUnVDTmhgGhbJDLtx4/hte/zGK7+mKl561q3Qmm xY0s8cSQCX1ULHyrgzS9rc0k42uvuRWgpKKKT5IrjiA91HtfcVM1r9hxa2/dw4wk WbAoaqpadjQAKoB4PNYzRfvITkv/9O+JSyK5BjsCgYEA5p9C68momBrX3Zgyc/gQ qcQFeJxAxZLf0xjs0Q/9cSnbeobxx7h3EuF9+NP1xuJ6EVDmt5crjzHp2vDboUgh Y1nToutENXSurOYXpjHnbUoUETCpt5LzqkgTZ/Pu2H8NXbSIDszoE8rQHEV8jVbp Y+ymK2XedrTF0cMD363aONUCgYEAy5J4+kdUL+VyADAz0awxa0KgWdNCBZivkvWL sYTMhgUFVM7xciTIZXQaIjRUIeeQkfKv2gvUDYlyYIRHm4Cih4vAfEmziQ7KMm0V K1+BpgGBMLMXmS57PzblVFU8HQlzau3Wac2CgfvNZtbU6jweIFhiYP9DYl1PfQpG PxuqJy8CgYBERsjdYfnyGMnFg3DVwgv/W/JspX201jMhQW2EW1OGDf7RQV+qTUnU 2NRGN9QbVYUvdwuRPd7C9wXQfLzXf0/E67oYg6fHHGTBNMjSq56qhZ2dSZnyQCxI UZu0B4/1A5493Mypxp8c2fPhBdfzjTA5latsr75U26OMPxCxgFxm1A== -----END RSA PRIVATE KEY----- ... ================================================ FILE: values_overrides/nova/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt nova: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/nova/tls.yaml ================================================ --- network: osapi: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" metadata: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" novncproxy: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" conf: mpm_event: | ServerLimit 1024 StartServers 32 MinSpareThreads 32 MaxSpareThreads 256 ThreadsPerChild 25 MaxRequestsPerChild 128 ThreadLimit 720 wsgi_nova_api: | {{- $portInt := tuple "compute" "service" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen {{ $portInt }} Require all granted ServerName {{ printf "%s.%s.svc.%s" "nova-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} WSGIDaemonProcess nova-api processes=1 threads=1 user=nova display-name=%{GROUP} WSGIProcessGroup nova-api WSGIScriptAlias / /var/lib/openstack/bin/nova-api-wsgi WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On AllowEncodedSlashes On SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded SSLEngine on SSLCertificateFile /etc/nova/certs/tls.crt SSLCertificateKeyFile /etc/nova/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on wsgi_nova_metadata: | {{- $portInt := tuple "compute_metadata" "service" "metadata" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen {{ $portInt }} Require all granted ServerName {{ printf "%s.%s.svc.%s" "nova-metadata" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} WSGIDaemonProcess nova-metadata processes=1 threads=1 user=nova display-name=%{GROUP} WSGIProcessGroup nova-metadata WSGIScriptAlias / /var/lib/openstack/bin/nova-metadata-wsgi WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On AllowEncodedSlashes On SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded ErrorLogFormat "%{cu}t %M" ErrorLog /dev/stdout CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded SSLEngine on SSLCertificateFile /etc/nova/certs/tls.crt SSLCertificateKeyFile /etc/nova/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on software: apache2: a2enmod: - ssl nova: console: ssl_minimum_version: tlsv1_2 glance: cafile: /etc/nova/certs/ca.crt ironic: cafile: /etc/nova/certs/ca.crt neutron: cafile: /etc/nova/certs/ca.crt keystone_authtoken: cafile: /etc/nova/certs/ca.crt cinder: cafile: /etc/nova/certs/ca.crt placement: cafile: /etc/nova/certs/ca.crt keystone: cafile: /etc/nova/certs/ca.crt oslo_messaging_rabbit: ssl: true ssl_ca_file: /etc/rabbitmq/certs/ca.crt ssl_cert_file: /etc/rabbitmq/certs/tls.crt ssl_key_file: /etc/rabbitmq/certs/tls.key endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt nova: cacert: /etc/ssl/certs/openstack-helm.crt neutron: cacert: /etc/ssl/certs/openstack-helm.crt placement: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt scheme: default: https port: api: default: 443 image: scheme: default: https port: api: public: 443 compute: host_fqdn_override: default: tls: secretName: nova-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: 'https' service: 'https' port: api: public: 443 compute_metadata: host_fqdn_override: default: tls: secretName: metadata-tls-metadata issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https port: metadata: public: 443 compute_novnc_proxy: host_fqdn_override: default: tls: secretName: nova-novncproxy-tls-proxy issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https port: novnc_proxy: public: 443 compute_spice_proxy: host_fqdn_override: default: tls: secretName: nova-tls-spiceproxy issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https compute_serial_proxy: host_fqdn_override: default: tls: secretName: nova-tls-serialproxy issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: wss placement: host_fqdn_override: default: tls: secretName: placement-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https port: api: public: 443 network: scheme: default: https port: api: public: 443 oslo_messaging: port: https: default: 15680 pod: security_context: nova: container: nova_api: runAsUser: 0 readOnlyRootFilesystem: false nova_osapi: runAsUser: 0 readOnlyRootFilesystem: false manifests: certificates: true ... ================================================ FILE: values_overrides/octavia/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy octavia_db_sync: quay.io/airshipit/octavia:2024.2-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 octavia_api: quay.io/airshipit/octavia:2024.2-ubuntu_jammy octavia_driver_agent: quay.io/airshipit/octavia:2024.2-ubuntu_jammy octavia_worker: quay.io/airshipit/octavia:2024.2-ubuntu_jammy octavia_worker_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy octavia_housekeeping: quay.io/airshipit/octavia:2024.2-ubuntu_jammy octavia_health_manager: quay.io/airshipit/octavia:2024.2-ubuntu_jammy octavia_health_manager_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_jammy conf: octavia_api_uwsgi: uwsgi: wsgi-file: /var/lib/openstack/bin/octavia-wsgi ... ================================================ FILE: values_overrides/octavia/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy octavia_db_sync: quay.io/airshipit/octavia:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 octavia_api: quay.io/airshipit/octavia:2025.1-ubuntu_jammy octavia_driver_agent: quay.io/airshipit/octavia:2025.1-ubuntu_jammy octavia_worker: quay.io/airshipit/octavia:2025.1-ubuntu_jammy octavia_worker_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy octavia_housekeeping: quay.io/airshipit/octavia:2025.1-ubuntu_jammy octavia_health_manager: quay.io/airshipit/octavia:2025.1-ubuntu_jammy octavia_health_manager_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_jammy conf: octavia_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/octavia-wsgi ... ================================================ FILE: values_overrides/octavia/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble octavia_db_sync: quay.io/airshipit/octavia:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 octavia_api: quay.io/airshipit/octavia:2025.1-ubuntu_noble octavia_driver_agent: quay.io/airshipit/octavia:2025.1-ubuntu_noble octavia_worker: quay.io/airshipit/octavia:2025.1-ubuntu_noble octavia_worker_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble octavia_housekeeping: quay.io/airshipit/octavia:2025.1-ubuntu_noble octavia_health_manager: quay.io/airshipit/octavia:2025.1-ubuntu_noble octavia_health_manager_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_noble conf: octavia_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/octavia-wsgi ... ================================================ FILE: values_overrides/octavia/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble octavia_db_sync: quay.io/airshipit/octavia:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 octavia_api: quay.io/airshipit/octavia:2025.2-ubuntu_noble octavia_driver_agent: quay.io/airshipit/octavia:2025.2-ubuntu_noble octavia_worker: quay.io/airshipit/octavia:2025.2-ubuntu_noble octavia_worker_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble octavia_housekeeping: quay.io/airshipit/octavia:2025.2-ubuntu_noble octavia_health_manager: quay.io/airshipit/octavia:2025.2-ubuntu_noble octavia_health_manager_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_noble conf: octavia_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/octavia-wsgi ... ================================================ FILE: values_overrides/octavia/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" octavia_api: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: octavia: custom.tld/key: "value" tls: load_balancer_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/octavia/gateway.yaml ================================================ # Gateway API overrides for Octavia. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: load_balancer: host_fqdn_override: public: host: octavia.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: octavia-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.load_balancer.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: octavia-api port: 9876 ... ================================================ FILE: values_overrides/octavia/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci octavia_db_sync: quay.io/airshipit/octavia:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 octavia_api: quay.io/airshipit/octavia:2025.1-ubuntu_noble_loci octavia_driver_agent: quay.io/airshipit/octavia:2025.1-ubuntu_noble_loci octavia_worker: quay.io/airshipit/octavia:2025.1-ubuntu_noble_loci octavia_worker_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci octavia_housekeeping: quay.io/airshipit/octavia:2025.1-ubuntu_noble_loci octavia_health_manager: quay.io/airshipit/octavia:2025.1-ubuntu_noble_loci octavia_health_manager_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_noble conf: octavia_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/octavia-wsgi ... ================================================ FILE: values_overrides/octavia/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci octavia_db_sync: quay.io/airshipit/octavia:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 octavia_api: quay.io/airshipit/octavia:2025.2-ubuntu_noble_loci octavia_driver_agent: quay.io/airshipit/octavia:2025.2-ubuntu_noble_loci octavia_worker: quay.io/airshipit/octavia:2025.2-ubuntu_noble_loci octavia_worker_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci octavia_housekeeping: quay.io/airshipit/octavia:2025.2-ubuntu_noble_loci octavia_health_manager: quay.io/airshipit/octavia:2025.2-ubuntu_noble_loci octavia_health_manager_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_noble conf: octavia_api_uwsgi: uwsgi: # in 2025.2 the wsgi script was removed wsgi-file: /var/lib/openstack/bin/octavia-wsgi ... ================================================ FILE: values_overrides/octavia/mariadb-operator.yaml ================================================ --- conf: octavia: database: connection: null task_flow: persistence_connection: null manifests: job_db_init: false secret_db_persistence: false etcSources: octavia_api: - octavia-db-conn octavia_db_sync: - octavia-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: octavia namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: octavia namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: octavia-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: octavia-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "octavia" table: "*" username: octavia grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: octavia-db-conn spec: mariaDbRef: name: mariadb username: octavia passwordSecretKeyRef: name: octavia-db-password key: password database: octavia secretName: octavia-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/openvswitch/apparmor.yaml ================================================ --- pod: security_context: ovs: container: vswitchd: appArmorProfile: type: RuntimeDefault server: appArmorProfile: type: RuntimeDefault modules: appArmorProfile: type: RuntimeDefault perms: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/openvswitch/dpdk-ubuntu_jammy.yaml ================================================ --- images: tags: openvswitch_db_server: quay.io/airshipit/openvswitch:latest-ubuntu_jammy-dpdk openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_jammy-dpdk pod: resources: enabled: true ovs: vswitchd: requests: memory: "2Gi" cpu: "2" limits: memory: "2Gi" cpu: "2" hugepages-2Mi: "1Gi" conf: ovs_dpdk: enabled: true hugepages_mountpath: /dev/hugepages vhostuser_socket_dir: vhostuser socket_memory: 512 lcore_mask: 0x1 pmd_cpu_mask: 0x4 ... ================================================ FILE: values_overrides/openvswitch/dpdk-ubuntu_noble.yaml ================================================ --- images: tags: openvswitch_db_server: quay.io/airshipit/openvswitch:latest-ubuntu_noble-dpdk openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_noble-dpdk pod: resources: enabled: true ovs: vswitchd: requests: memory: "2Gi" cpu: "2" limits: memory: "2Gi" cpu: "2" hugepages-2Mi: "1Gi" conf: ovs_dpdk: enabled: true hugepages_mountpath: /dev/hugepages vhostuser_socket_dir: vhostuser socket_memory: 512 lcore_mask: 0x1 pmd_cpu_mask: 0x4 ... ================================================ FILE: values_overrides/openvswitch/exporter.yaml ================================================ --- openvswitch: extraContainers: - name: ovs-exporter image: ghcr.io/saeed-mcu/ovs_exporter/openvswitch_exporter:v2.3.2 imagePullPolicy: IfNotPresent ports: - name: metrics containerPort: 9475 protocol: TCP livenessProbe: httpGet: path: /metrics port: 9475 initialDelaySeconds: 30 periodSeconds: 60 timeoutSeconds: 5 readinessProbe: httpGet: path: /metrics port: 9475 initialDelaySeconds: 15 periodSeconds: 30 timeoutSeconds: 5 securityContext: readOnlyRootFilesystem: true resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "256Mi" cpu: "500m" volumeMounts: - name: run mountPath: /run readOnly: true ... ================================================ FILE: values_overrides/openvswitch/netpol.yaml ================================================ --- manifests: network_policy: true ... ================================================ FILE: values_overrides/openvswitch/ovn.yaml ================================================ --- conf: openvswitch_db_server: ptcp_port: 6640 ... ================================================ FILE: values_overrides/openvswitch/ubuntu_jammy.yaml ================================================ --- images: tags: openvswitch_db_server: quay.io/airshipit/openvswitch:latest-ubuntu_jammy openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_jammy ... ================================================ FILE: values_overrides/openvswitch/ubuntu_noble.yaml ================================================ --- images: tags: openvswitch_db_server: quay.io/airshipit/openvswitch:latest-ubuntu_noble openvswitch_vswitchd: quay.io/airshipit/openvswitch:latest-ubuntu_noble ... ================================================ FILE: values_overrides/openvswitch/vswitchd-probes.yaml ================================================ --- pod: probes: ovs_vswitch: ovs_vswitch: liveness: exec: - /bin/bash - -c - '/usr/bin/ovs-appctl bond/list; C1=$?; ovs-vsctl --column statistics list interface dpdk_b0s0 | grep -q -E "rx_|tx_"; C2=$?; ovs-vsctl --column statistics list interface dpdk_b0s1 | grep -q -E "rx_|tx_"; C3=$?; exit $(($C1+$C2+$C3))' ... ================================================ FILE: values_overrides/ovn/ubuntu_jammy.yaml ================================================ --- images: tags: ovn_ovsdb_nb: quay.io/airshipit/ovn:ubuntu_jammy ovn_ovsdb_sb: quay.io/airshipit/ovn:ubuntu_jammy ovn_northd: quay.io/airshipit/ovn:ubuntu_jammy ovn_controller: quay.io/airshipit/ovn:ubuntu_jammy ... ================================================ FILE: values_overrides/ovn/ubuntu_noble.yaml ================================================ --- images: tags: ovn_ovsdb_nb: quay.io/airshipit/ovn:ubuntu_noble ovn_ovsdb_sb: quay.io/airshipit/ovn:ubuntu_noble ovn_northd: quay.io/airshipit/ovn:ubuntu_noble ovn_controller: quay.io/airshipit/ovn:ubuntu_noble ... ================================================ FILE: values_overrides/placement/2024.2-ubuntu_jammy.yaml ================================================ --- images: pull_policy: IfNotPresent tags: placement: "quay.io/airshipit/placement:2024.2-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy" placement_db_sync: "quay.io/airshipit/placement:2024.2-ubuntu_jammy" dep_check: "quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy" image_repo_sync: "docker.io/docker:17.07.0" dependencies: static: db_sync: jobs: - placement-db-init ... ================================================ FILE: values_overrides/placement/2025.1-ubuntu_jammy.yaml ================================================ --- images: pull_policy: IfNotPresent tags: placement: "quay.io/airshipit/placement:2025.1-ubuntu_jammy" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy" placement_db_sync: "quay.io/airshipit/placement:2025.1-ubuntu_jammy" dep_check: "quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy" image_repo_sync: "docker.io/docker:17.07.0" dependencies: static: db_sync: jobs: - placement-db-init ... ================================================ FILE: values_overrides/placement/2025.1-ubuntu_noble.yaml ================================================ --- images: pull_policy: IfNotPresent tags: placement: "quay.io/airshipit/placement:2025.1-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble" placement_db_sync: "quay.io/airshipit/placement:2025.1-ubuntu_noble" dep_check: "quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy" image_repo_sync: "docker.io/docker:17.07.0" dependencies: static: db_sync: jobs: - placement-db-init ... ================================================ FILE: values_overrides/placement/2025.2-ubuntu_noble.yaml ================================================ --- images: pull_policy: IfNotPresent tags: placement: "quay.io/airshipit/placement:2025.2-ubuntu_noble" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble" placement_db_sync: "quay.io/airshipit/placement:2025.2-ubuntu_noble" dep_check: "quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy" image_repo_sync: "docker.io/docker:17.07.0" dependencies: static: db_sync: jobs: - placement-db-init ... ================================================ FILE: values_overrides/placement/annotations.yaml ================================================ --- annotations: pod: default: custom.tld/key: "value" custom.tld/key2: "value2" placement: another.tld/foo: "bar" secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: placement: custom.tld/key: "value" tls: placement_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/placement/apparmor.yaml ================================================ --- pod: security_context: placement: container: placement_api: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/placement/gateway.yaml ================================================ # Gateway API overrides for Placement. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: placement: host_fqdn_override: public: host: placement.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: placement-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.placement.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: placement-api port: 8778 ... ================================================ FILE: values_overrides/placement/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: pull_policy: IfNotPresent tags: placement: "quay.io/airshipit/placement:2025.1-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci" placement_db_sync: "quay.io/airshipit/placement:2025.1-ubuntu_noble_loci" dep_check: "quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy" image_repo_sync: "docker.io/docker:17.07.0" dependencies: static: db_sync: jobs: - placement-db-init ... ================================================ FILE: values_overrides/placement/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: pull_policy: IfNotPresent tags: placement: "quay.io/airshipit/placement:2025.2-ubuntu_noble_loci" ks_user: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_service: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" ks_endpoints: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_init: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" db_drop: "quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci" placement_db_sync: "quay.io/airshipit/placement:2025.2-ubuntu_noble_loci" dep_check: "quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy" image_repo_sync: "docker.io/docker:17.07.0" dependencies: static: db_sync: jobs: - placement-db-init ... ================================================ FILE: values_overrides/placement/mariadb-operator.yaml ================================================ --- conf: placement: placement_database: connection: null manifests: job_db_init: false etcSources: placement_api: - placement-db-conn placement_db_sync: - placement-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: placement namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: placement namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: placement-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: placement-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "placement" table: "*" username: placement grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: placement-db-conn spec: mariaDbRef: name: mariadb username: placement passwordSecretKeyRef: name: placement-db-password key: password database: placement secretName: placement-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/placement/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: placement: egress: - {} ingress: - from: - podSelector: matchLabels: application: nova ports: - protocol: TCP port: 8778 - protocol: TCP port: 80 - protocol: TCP port: 8080 ... ================================================ FILE: values_overrides/placement/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt placement: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/placement/tls.yaml ================================================ --- network: api: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: "https" conf: software: apache2: binary: apache2 start_parameters: -DFOREGROUND site_dir: /etc/apache2/sites-enabled conf_dir: /etc/apache2/conf-enabled mods_dir: /etc/apache2/mods-available a2enmod: - ssl a2dismod: null placement: keystone_authtoken: cafile: /etc/placement/certs/ca.crt wsgi_placement: | {{- $portInt := tuple "placement" "service" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} Listen {{ $portInt }} Require all granted ServerName {{ printf "%s.%s.svc.%s" "placement-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} WSGIDaemonProcess placement-api processes=1 threads=1 user=placement group=placement display-name=%{GROUP} WSGIProcessGroup placement-api WSGIScriptAlias / /var/lib/openstack/bin/placement-api WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On ErrorLogFormat "%{cu}t %M" SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded ErrorLog /dev/stdout CustomLog /dev/stdout combined env=!forwarded CustomLog /dev/stdout proxy env=forwarded SSLEngine on SSLCertificateFile /etc/placement/certs/tls.crt SSLCertificateKeyFile /etc/placement/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt placement: cacert: /etc/ssl/certs/openstack-helm.crt scheme: default: https port: api: default: 443 placement: host_fqdn_override: default: tls: secretName: placement-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: https service: https port: api: public: 443 manifests: certificates: true ... ================================================ FILE: values_overrides/postgresql/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_user: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/postgresql/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/postgresql/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/postgresql/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/postgresql/apparmor.yaml ================================================ --- pod: security_context: server: container: postgresql: appArmorProfile: type: RuntimeDefault set_volume_perms: appArmorProfile: type: RuntimeDefault prometheus_postgresql_exporter: container: postgresql_exporter: appArmorProfile: type: RuntimeDefault create_user: container: prometheus_postgresql_exporter_create_user: appArmorProfile: type: RuntimeDefault postgresql_backup: container: postgresql_backup: appArmorProfile: type: RuntimeDefault backup_perms: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/postgresql/backups.yaml ================================================ --- conf: backup: enabled: true remote_backup: enabled: true volume: backup: enabled: true manifests: pvc_backup: true job_ks_user: false cron_job_postgresql_backup: true secret_backup_restore: true endpoints: identity: auth: postgresql: auth_url: null role: admin region_name: RegionOne username: postgresql-backup-user password: password project_name: service user_domain_name: service project_domain_name: service postgresql_failover: auth_url: null role: admin region_name: RegionOne username: postgresql-backup-user-failover password: password project_name: service user_domain_name: service project_domain_name: service ... ================================================ FILE: values_overrides/postgresql/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/postgresql/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/postgresql/netpol.yaml ================================================ --- manifests: network_policy: true network_policy: postgresql: egress: - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% ... ================================================ FILE: values_overrides/postgresql/staggered-backups.yaml ================================================ --- conf: backup: enabled: true remote_backup: enabled: false pod: labels: backup: staggered_backups: enabled affinity: postgresql_backup: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: status.phase operator: NotIn values: - Running - key: staggered-backups operator: In values: - enabled namespaces: - openstack - osh-infra - ucp topologyKey: kubernetes.io/os volume: backup: enabled: true manifests: pvc_backup: true job_ks_user: false cron_job_postgresql_backup: true secret_backup_restore: true ... ================================================ FILE: values_overrides/postgresql/tls.yaml ================================================ --- conf: postgresql: ssl: 'on' pod: security_context: server: container: perms: readOnlyRootFilesystem: false postgresql: runAsUser: 0 allowPrivilegeEscalation: true readOnlyRootFilesystem: false endpoints: postgresql: host_fqdn_override: default: tls: secretName: postgresql-tls-direct issuerRef: name: ca-issuer kind: ClusterIssuer manifests: certificates: true ... ================================================ FILE: values_overrides/powerdns/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/powerdns/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/powerdns/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/powerdns/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/powerdns/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/powerdns/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/prometheus/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/prometheus/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/prometheus/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/prometheus/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/prometheus/alertmanager.yaml ================================================ --- conf: prometheus: rules: alertmanager: groups: - name: alertmanager.rules rules: - alert: AlertmanagerConfigInconsistent expr: count_values("config_hash", alertmanager_config_hash) BY (service) / ON(service) GROUP_LEFT() label_replace(prometheus_operator_alertmanager_spec_replicas, "service", "alertmanager-$1", "alertmanager", "(.*)") != 1 for: 5m labels: severity: critical annotations: description: The configuration of the instances of the Alertmanager cluster `{{$labels.service}}` are out of sync. summary: Alertmanager configurations are inconsistent - alert: AlertmanagerDownOrMissing expr: label_replace(prometheus_operator_alertmanager_spec_replicas, "job", "alertmanager-$1", "alertmanager", "(.*)") / ON(job) GROUP_RIGHT() sum(up) BY (job) != 1 for: 5m labels: severity: warning annotations: description: An unexpected number of Alertmanagers are scraped or Alertmanagers disappeared from discovery. summary: Alertmanager down or not discovered - alert: FailedReload expr: alertmanager_config_last_reload_successful == 0 for: 10m labels: severity: warning annotations: description: Reloading Alertmanager's configuration has failed for {{ $labels.namespace }}/{{ $labels.pod }}. summary: Alertmanager configuration reload has failed ... ================================================ FILE: values_overrides/prometheus/apparmor.yaml ================================================ --- pod: security_context: api: container: prometheus: appArmorProfile: type: RuntimeDefault prometheus_perms: appArmorProfile: type: RuntimeDefault apache_proxy: appArmorProfile: type: RuntimeDefault test: container: prometheus_helm_tests: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/prometheus/ceph.yaml ================================================ --- conf: prometheus: rules: ceph: groups: - name: ceph.recording_rules rules: - record: ceph_cluster_usage_percent expr: 100 * (ceph_cluster_total_used_bytes / ceph_cluster_total_bytes) - record: ceph_placement_group_degrade_percent expr: 100 * (ceph_pg_degraded / ceph_pg_total) - record: ceph_osd_down_percent expr: 100 * (count(ceph_osd_up == 0) / count(ceph_osd_metadata)) - record: ceph_osd_out_percent expr: 100 * (count(ceph_osd_in == 0) / count(ceph_osd_metadata)) - name: ceph.alerting_rules rules: - alert: prom_exporter_ceph_unavailable expr: absent(ceph_health_status) for: 10m labels: severity: warning annotations: description: Ceph exporter is not collecting metrics or is not available for past 10 minutes title: Ceph exporter is not collecting metrics or is not available - alert: no_active_ceph_mgr expr: avg_over_time(up{job="ceph-mgr"}[5m]) == 0 labels: severity: warning annotations: description: 'no ceph active mgr is present or all ceph mgr are down' summary: 'no ceph active mgt is present' - alert: ceph_monitor_quorum_low expr: ceph_mon_quorum_count < 3 for: 5m labels: severity: page annotations: description: 'ceph monitor quorum has been less than 3 for more than 5 minutes' summary: 'ceph high availability is at risk' - alert: ceph_monitor_quorum_absent expr: absent(avg_over_time(ceph_mon_quorum_status[5m])) labels: severity: page annotations: description: 'ceph monitor quorum has been gone for more than 5 minutes' summary: 'ceph high availability is at risk' - alert: ceph_cluster_usage_high expr: avg_over_time(ceph_cluster_usage_percent[5m]) > 80 labels: severity: page annotations: description: 'ceph cluster capacity usage more than 80 percent' summary: 'ceph cluster usage is more than 80 percent' - alert: ceph_placement_group_degrade_pct_high expr: avg_over_time(ceph_placement_group_degrade_percent[5m]) > 80 labels: severity: critical annotations: description: 'ceph placement group degradation is more than 80 percent' summary: 'ceph placement groups degraded' - alert: ceph_osd_down_pct_high expr: avg_over_time(ceph_osd_down_percent[5m]) > 80 labels: severity: critical annotations: description: 'ceph OSDs down percent is more than 80 percent' summary: 'ceph OSDs down percent is high' - alert: ceph_osd_down expr: avg_over_time(ceph_osd_up[5m]) == 0 labels: severity: critical annotations: description: 'ceph OSD {{ $labels.ceph_daemon }} is down in instance {{ $labels.instance }}.' summary: 'ceph OSD {{ $labels.ceph_daemon }} is down in instance {{ $labels.instance }}.' - alert: ceph_osd_out expr: avg_over_time(ceph_osd_in[5m]) == 0 labels: severity: page annotations: description: 'ceph OSD {{ $labels.ceph_daemon }} is out in instance {{ $labels.instance }}.' summary: 'ceph OSD {{ $labels.ceph_daemon }} is out in instance {{ $labels.instance }}.' ... ================================================ FILE: values_overrides/prometheus/elasticsearch.yaml ================================================ --- conf: prometheus: rules: elasticsearch: groups: - name: elasticsearch.alerting_rules rules: - alert: prom_exporter_elasticsearch_unavailable expr: avg_over_time(up{job="elasticsearch-exporter"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: Elasticsearch exporter is not collecting metrics or is not available for past 10 minutes title: Elasticsearch exporter is not collecting metrics or is not available - alert: es_high_process_open_files_count expr: sum(elasticsearch_process_open_files_count) by (host) > 64000 for: 10m labels: severity: warning annotations: description: 'Elasticsearch at {{ $labels.host }} has more than 64000 process open file count.' summary: 'Elasticsearch has a very high process open file count.' - alert: es_high_process_cpu_percent expr: elasticsearch_process_cpu_percent > 95 for: 10m labels: severity: warning annotations: description: 'Elasticsearch at {{ $labels.instance }} has high process cpu percent of {{ $value }}.' summary: 'Elasticsearch process cpu usage is more than 95 percent.' - alert: es_fs_usage_high expr: (100 * (elasticsearch_filesystem_data_size_bytes - elasticsearch_filesystem_data_free_bytes) / elasticsearch_filesystem_data_size_bytes) > 80 for: 10m labels: severity: warning annotations: description: 'Elasticsearch at {{ $labels.instance }} has filesystem usage of {{ $value }}.' summary: 'Elasticsearch filesystem usage is high.' - alert: es_unassigned_shards expr: elasticsearch_cluster_health_unassigned_shards > 0 for: 10m labels: severity: warning annotations: description: 'Elasticsearch has {{ $value }} unassigned shards.' summary: 'Elasticsearch has unassigned shards and hence a unhealthy cluster state.' - alert: es_cluster_health_timed_out expr: elasticsearch_cluster_health_timed_out > 0 for: 10m labels: severity: warning annotations: description: 'Elasticsearch cluster health status call timedout {{ $value }} times.' summary: 'Elasticsearch cluster health status calls are timing out.' - alert: es_cluster_health_status_alert expr: (sum(elasticsearch_cluster_health_status{color="green"})*2)+sum(elasticsearch_cluster_health_status{color="yellow"}) < 2 for: 10m labels: severity: warning annotations: description: 'Elasticsearch cluster health status is {{ $value }}, not 2 (green). One or more shards or replicas are unallocated.' summary: 'Elasticsearch cluster health status is not green.' - alert: es_cluster_health_too_few_nodes_running expr: elasticsearch_cluster_health_number_of_nodes < 3 for: 10m labels: severity: warning annotations: description: 'There are only {{$value}} < 3 ElasticSearch nodes running' summary: 'ElasticSearch running on less than 3 nodes' - alert: es_cluster_health_too_few_data_nodes_running expr: elasticsearch_cluster_health_number_of_data_nodes < 3 for: 10m labels: severity: warning annotations: description: 'There are only {{$value}} < 3 ElasticSearch data nodes running' summary: 'ElasticSearch running on less than 3 data nodes' - alert: es_cluster_health_too_few_data_nodes_running expr: elasticsearch_cluster_health_number_of_data_nodes < 3 for: 10m labels: severity: warning annotations: description: 'There are only {{$value}} < 3 ElasticSearch data nodes running' summary: 'ElasticSearch running on less than 3 data nodes' fluentd: groups: - name: fluentd.alerting_rules rules: - alert: prom_exporter_fluentd_unavailable expr: avg_over_time(up{job="fluentd-daemonset-exporter"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: Fluentd exporter is not collecting metrics or is not available for past 10 minutes title: Fluentd exporter is not collecting metrics or is not available ... ================================================ FILE: values_overrides/prometheus/gateway.yaml ================================================ # Gateway API overrides for Prometheus. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: monitoring: host_fqdn_override: public: host: prometheus.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: prometheus-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.monitoring.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: prom-metrics port: 9090 ... ================================================ FILE: values_overrides/prometheus/kubernetes.yaml ================================================ --- conf: prometheus: rules: kubernetes: groups: - name: calico.rules rules: - alert: prom_exporter_calico_unavailable expr: avg_over_time(up{job="kubernetes-pods",application="calico"}[5m]) == 0 for: 10m labels: severity: warning annotations: description: Calico exporter is not collecting metrics or is not available for past 10 minutes title: Calico exporter is not collecting metrics or is not available - alert: calico_datapane_failures_high_1h expr: absent(felix_int_dataplane_failures) OR increase(felix_int_dataplane_failures[1h]) > 5 labels: severity: page annotations: description: 'Felix instance {{ $labels.instance }} has seen {{ $value }} dataplane failures within the last hour' summary: 'A high number of dataplane failures within Felix are happening' - alert: calico_datapane_address_msg_batch_size_high_5m expr: absent(felix_int_dataplane_addr_msg_batch_size_sum) OR absent(felix_int_dataplane_addr_msg_batch_size_count) OR (felix_int_dataplane_addr_msg_batch_size_sum/felix_int_dataplane_addr_msg_batch_size_count) > 5 for: 5m labels: severity: page annotations: description: 'Felix instance {{ $labels.instance }} has seen a high value of {{ $value }} dataplane address message batch size' summary: 'Felix address message batch size is higher' - alert: calico_datapane_iface_msg_batch_size_high_5m expr: absent(felix_int_dataplane_iface_msg_batch_size_sum) OR absent(felix_int_dataplane_iface_msg_batch_size_count) OR (felix_int_dataplane_iface_msg_batch_size_sum/felix_int_dataplane_iface_msg_batch_size_count) > 5 for: 5m labels: severity: page annotations: description: 'Felix instance {{ $labels.instance }} has seen a high value of {{ $value }} dataplane interface message batch size' summary: 'Felix interface message batch size is higher' - alert: calico_ipset_errors_high_1h expr: absent(felix_ipset_errors) OR increase(felix_ipset_errors[1h]) > 5 labels: severity: page annotations: description: 'Felix instance {{ $labels.instance }} has seen {{ $value }} ipset errors within the last hour' summary: 'A high number of ipset errors within Felix are happening' - alert: calico_iptable_save_errors_high_1h expr: absent(felix_iptables_save_errors) OR increase(felix_iptables_save_errors[1h]) > 5 labels: severity: page annotations: description: 'Felix instance {{ $labels.instance }} has seen {{ $value }} iptable save errors within the last hour' summary: 'A high number of iptable save errors within Felix are happening' - alert: calico_iptable_restore_errors_high_1h expr: absent(felix_iptables_restore_errors) OR increase(felix_iptables_restore_errors[1h]) > 5 labels: severity: page annotations: description: 'Felix instance {{ $labels.instance }} has seen {{ $value }} iptable restore errors within the last hour' summary: 'A high number of iptable restore errors within Felix are happening' - name: etcd3.rules rules: - alert: etcd_InsufficientMembers expr: count(up{job="etcd"} == 0) > (count(up{job="etcd"}) / 2 - 1) for: 3m labels: severity: critical annotations: description: If one more etcd member goes down the cluster will be unavailable summary: etcd cluster insufficient members - alert: etcd_NoLeader expr: etcd_server_has_leader{job="etcd"} == 0 for: 1m labels: severity: critical annotations: description: etcd member {{ $labels.instance }} has no leader summary: etcd member has no leader - alert: etcd_HighNumberOfLeaderChanges expr: increase(etcd_server_leader_changes_seen_total{job="etcd"}[1h]) > 3 labels: severity: warning annotations: description: etcd instance {{ $labels.instance }} has seen {{ $value }} leader changes within the last hour summary: a high number of leader changes within the etcd cluster are happening - alert: etcd_HighNumberOfFailedGRPCRequests expr: sum(rate(etcd_grpc_requests_failed_total{job="etcd"}[5m])) BY (grpc_method) / sum(rate(etcd_grpc_total{job="etcd"}[5m])) BY (grpc_method) > 0.01 for: 10m labels: severity: warning annotations: description: '{{ $value }}% of requests for {{ $labels.grpc_method }} failed on etcd instance {{ $labels.instance }}' summary: a high number of gRPC requests are failing - alert: etcd_HighNumberOfFailedGRPCRequests expr: sum(rate(etcd_grpc_requests_failed_total{job="etcd"}[5m])) BY (grpc_method) / sum(rate(etcd_grpc_total{job="etcd"}[5m])) BY (grpc_method) > 0.05 for: 5m labels: severity: critical annotations: description: '{{ $value }}% of requests for {{ $labels.grpc_method }} failed on etcd instance {{ $labels.instance }}' summary: a high number of gRPC requests are failing - alert: etcd_GRPCRequestsSlow expr: histogram_quantile(0.99, rate(etcd_grpc_unary_requests_duration_seconds_bucket[5m])) > 0.15 for: 10m labels: severity: critical annotations: description: on etcd instance {{ $labels.instance }} gRPC requests to {{ $labels.grpc_method }} are slow summary: slow gRPC requests - alert: etcd_HighNumberOfFailedHTTPRequests expr: sum(rate(etcd_http_failed_total{job="etcd"}[5m])) BY (method) / sum(rate(etcd_http_received_total{job="etcd"}[5m])) BY (method) > 0.01 for: 10m labels: severity: warning annotations: description: '{{ $value }}% of requests for {{ $labels.method }} failed on etcd instance {{ $labels.instance }}' summary: a high number of HTTP requests are failing - alert: etcd_HighNumberOfFailedHTTPRequests expr: sum(rate(etcd_http_failed_total{job="etcd"}[5m])) BY (method) / sum(rate(etcd_http_received_total{job="etcd"}[5m])) BY (method) > 0.05 for: 5m labels: severity: critical annotations: description: '{{ $value }}% of requests for {{ $labels.method }} failed on etcd instance {{ $labels.instance }}' summary: a high number of HTTP requests are failing - alert: etcd_HTTPRequestsSlow expr: histogram_quantile(0.99, rate(etcd_http_successful_duration_seconds_bucket[5m])) > 0.15 for: 10m labels: severity: warning annotations: description: on etcd instance {{ $labels.instance }} HTTP requests to {{ $labels.method }} are slow summary: slow HTTP requests - alert: etcd_EtcdMemberCommunicationSlow expr: histogram_quantile(0.99, rate(etcd_network_member_round_trip_time_seconds_bucket[5m])) > 0.15 for: 10m labels: severity: warning annotations: description: etcd instance {{ $labels.instance }} member communication with {{ $labels.To }} is slow summary: etcd member communication is slow - alert: etcd_HighNumberOfFailedProposals expr: increase(etcd_server_proposals_failed_total{job="etcd"}[1h]) > 5 labels: severity: warning annotations: description: etcd instance {{ $labels.instance }} has seen {{ $value }} proposal failures within the last hour summary: a high number of proposals within the etcd cluster are failing - alert: etcd_HighFsyncDurations expr: histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[5m])) > 0.5 for: 10m labels: severity: warning annotations: description: etcd instance {{ $labels.instance }} fync durations are high summary: high fsync durations - alert: etcd_HighCommitDurations expr: histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket[5m])) > 0.25 for: 10m labels: severity: warning annotations: description: etcd instance {{ $labels.instance }} commit durations are high summary: high commit durations - name: kubelet.rules rules: - alert: K8SNodeNotReady expr: kube_node_status_condition{condition="Ready", status="unknown"} == 1 or kube_node_status_condition{condition="Ready", status="false"} == 1 for: 1m labels: severity: critical annotations: description: The Kubelet on {{ $labels.node }} has not checked in with the API, or has set itself to NotReady, for more than a minute summary: '{{ $labels.node }} Node status is NotReady and {{ $labels.status }}' - alert: K8SManyNodesNotReady expr: count(kube_node_status_condition{condition="Ready", status="unknown"} == 1) > 1 and (count(kube_node_status_condition{condition="Ready", status="unknown"} == 1) / count(kube_node_status_condition{condition="Ready", status="unknown"})) > 0.2 for: 1m labels: severity: critical annotations: description: '{{ $value }} Kubernetes nodes (more than 10% are in the NotReady state).' summary: Many Kubernetes nodes are Not Ready - alert: K8SManyNodesNotReady expr: count(kube_node_status_condition{condition="Ready", status="false"} == 1) > 1 and (count(kube_node_status_condition{condition="Ready", status="false"} == 1) / count(kube_node_status_condition{condition="Ready", status="false"})) > 0.2 for: 1m labels: severity: critical annotations: description: '{{ $value }} Kubernetes nodes (more than 10% are in the NotReady state).' summary: Many Kubernetes nodes are Not Ready - alert: K8SNodesNotReady expr: count(kube_node_status_condition{condition="Ready", status="false"} == 1) > 0 or count(kube_node_status_condition{condition="Ready", status="unknown"} == 1) > 0 for: 1m labels: severity: critical annotations: description: '{{ $value }} nodes are notReady state.' summary: One or more Kubernetes nodes are Not Ready - alert: K8SKubeletDown expr: count(up{job="kubelet"} == 0) / count(up{job="kubelet"}) > 0.03 for: 1m labels: severity: critical annotations: description: Prometheus failed to scrape {{ $value }}% of kubelets. summary: Many Kubelets cannot be scraped - alert: K8SKubeletDown expr: absent(up{job="kubelet"} == 1) or count(up{job="kubelet"} == 0) / count(up{job="kubelet"}) > 0.1 for: 1m labels: severity: critical annotations: description: Prometheus failed to scrape {{ $value }}% of kubelets, or all Kubelets have disappeared from service discovery. summary: Many Kubelets cannot be scraped - alert: K8SKubeletTooManyPods expr: kubelet_running_pod_count > 100 labels: severity: warning annotations: description: Kubelet {{$labels.instance}} is running {{$value}} pods, close to the limit of 110 summary: Kubelet is close to pod limit - name: kube-apiserver.rules rules: - alert: K8SApiserverDown expr: absent(up{job="apiserver"} == 1) for: 5m labels: severity: critical annotations: description: Prometheus failed to scrape API server(s), or all API servers have disappeared from service discovery. summary: API server unreachable - alert: K8SApiServerLatency expr: histogram_quantile(0.99, sum(apiserver_request_latencies_bucket{verb!~"CONNECT|WATCHLIST|WATCH|PROXY"}) WITHOUT (instance, resource)) / 1e+06 > 1 for: 10m labels: severity: warning annotations: description: 99th percentile Latency for {{ $labels.verb }} requests to the kube-apiserver is higher than 1s. summary: Kubernetes apiserver latency is high - name: kube-controller-manager.rules rules: - alert: K8SControllerManagerDown expr: absent(up{job="kube-controller-manager-discovery"} == 1) for: 5m labels: severity: critical annotations: description: There is no running K8S controller manager. Deployments and replication controllers are not making progress. runbook: https://coreos.com/tectonic/docs/latest/troubleshooting/controller-recovery.html#recovering-a-controller-manager summary: Controller manager is down - name: kubernetes-object.rules rules: - alert: prom_exporter_kube_state_metrics_unavailable expr: avg_over_time(up{job="kube-state-metrics"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: kube-state-metrics exporter is not collecting metrics or is not available for past 10 minutes title: kube-state-metrics exporter is not collecting metrics or is not available - alert: kube_statefulset_replicas_unavailable expr: kube_statefulset_status_replicas < kube_statefulset_replicas for: 5m labels: severity: page annotations: description: 'statefulset {{$labels.statefulset}} has {{$value}} replicas, which is less than desired' summary: '{{$labels.statefulset}}: has inssuficient replicas.' - alert: daemonsets_misscheduled expr: kube_daemonset_status_number_misscheduled > 0 for: 10m labels: severity: warning annotations: description: 'Daemonset {{$labels.daemonset}} is running where it is not supposed to run' summary: 'Daemonsets not scheduled correctly' - alert: daemonsets_not_scheduled expr: kube_daemonset_status_desired_number_scheduled - kube_daemonset_status_current_number_scheduled > 0 for: 10m labels: severity: warning annotations: description: '{{ $value }} of Daemonset {{$labels.daemonset}} scheduled which is less than desired number' summary: 'Less than desired number of daemonsets scheduled' - alert: daemonset_pods_unavailable expr: kube_daemonset_status_number_unavailable > 0 for: 10m labels: severity: warning annotations: description: 'Daemonset {{$labels.daemonset}} currently has pods unavailable' summary: 'Daemonset pods unavailable, due to one of many reasons' - alert: deployment_replicas_unavailable expr: kube_deployment_status_replicas_unavailable > 0 for: 10m labels: severity: page annotations: description: 'deployment {{$labels.deployment}} has {{$value}} replicas unavailable' summary: '{{$labels.deployment}}: has inssuficient replicas.' - alert: rollingupdate_deployment_replica_less_than_spec_max_unavailable expr: kube_deployment_status_replicas_available - kube_deployment_spec_strategy_rollingupdate_max_unavailable < 0 for: 10m labels: severity: page annotations: description: 'deployment {{$labels.deployment}} has {{$value}} replicas available which is less than specified as max unavailable during a rolling update' summary: '{{$labels.deployment}}: has inssuficient replicas during a rolling update.' - alert: job_status_failed expr: kube_job_status_failed > 0 for: 10m labels: severity: page annotations: description: 'Job {{$labels.exported_job}} is in failed status' summary: '{{$labels.exported_job}} has failed status' - alert: pod_status_pending expr: kube_pod_status_phase{phase="Pending"} == 1 for: 10m labels: severity: page annotations: description: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} has been in pending status for more than 10 minutes' summary: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} in pending status' - alert: pod_status_error_image_pull expr: kube_pod_container_status_waiting_reason {reason="ErrImagePull"} == 1 for: 10m labels: severity: page annotations: description: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} has an Image pull error for more than 10 minutes' summary: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} in error status' - alert: pod_status_error_image_pull_backoff expr: kube_pod_container_status_waiting_reason {reason="ImagePullBackOff"} == 1 for: 10m labels: severity: page annotations: description: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} has an ImagePullBackOff error for more than 10 minutes' summary: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} in error status' - alert: pod_error_crash_loop_back_off expr: kube_pod_container_status_waiting_reason {reason="CrashLoopBackOff"} == 1 for: 10m labels: severity: page annotations: description: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} has an CrashLoopBackOff error for more than 10 minutes' summary: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} in error status' - alert: pod_error_config_error expr: kube_pod_container_status_waiting_reason {reason="CreateContainerConfigError"} == 1 for: 10m labels: severity: page annotations: description: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} has a CreateContainerConfigError error for more than 10 minutes' summary: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} in error status' - alert: replicaset_missing_replicas expr: kube_replicaset_spec_replicas - kube_replicaset_status_ready_replicas > 0 for: 10m labels: severity: page annotations: description: 'Replicaset {{$labels.replicaset}} is missing desired number of replicas for more than 10 minutes' summary: 'Replicaset {{$labels.replicaset}} is missing replicas' - alert: pod_container_terminated expr: kube_pod_container_status_terminated_reason{reason=~"OOMKilled|Error|ContainerCannotRun"} > 0 for: 10m labels: severity: page annotations: description: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} has a container terminated for more than 10 minutes' summary: 'Pod {{$labels.pod}} in namespace {{$labels.namespace}} in error status' - alert: volume_claim_capacity_high_utilization expr: 100 * kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes > 80 for: 5m labels: severity: page annotations: description: 'volume claim {{$labels.persistentvolumeclaim}} usage has exceeded 80% of total capacity' summary: '{{$labels.persistentvolumeclaim}} usage has exceeded 80% of total capacity.' ... ================================================ FILE: values_overrides/prometheus/local-storage.yaml ================================================ --- pod: replicas: prometheus: 1 storage: requests: storage: 1Gi storage_class: local-storage ... ================================================ FILE: values_overrides/prometheus/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/prometheus/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/prometheus/nodes.yaml ================================================ --- conf: prometheus: rules: nodes: groups: - name: node.recording_rules rules: - record: node_filesystem_free_percent expr: 100 * {fstype =~ "xfs|ext[34]"} / node_filesystem_size{fstype =~ "xfs|ext[34]"} - record: node_ram_usage_percent expr: 100 * (node_memory_MemFree + node_memory_Buffers + node_memory_Cached) / node_memory_MemTotal - record: node_swap_usage_percent expr: 100 * (node_memory_SwapFree + node_memory_SwapCached) / node_memory_SwapTotal - name: nodes.alerting_rules rules: - alert: prom_exporter_node_unavailable expr: avg_over_time(up{job="node-exporter"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: node exporter is not collecting metrics or is not available for past 10 minutes title: node exporter is not collecting metrics or is not available - alert: node_filesystem_full_80percent expr: avg_over_time(node_filesystem_free_percent[2m]) > 80 for: 5m labels: severity: page annotations: description: '{{$labels.alias}} device {{$labels.device}} on {{$labels.mountpoint}} has less than 20% free space left.' summary: '{{$labels.alias}}: Filesystem is running out of space soon.' - alert: node_filesystem_full_in_4h expr: predict_linear(node_filesystem_free{fstype =~ "xfs|ext[34]"}[1h], 4 * 3600) <= 0 for: 5m labels: severity: page annotations: description: '{{$labels.alias}} device {{$labels.device}} on {{$labels.mountpoint}} is running out of space of in approx. 4 hours' summary: '{{$labels.alias}}: Filesystem is running out of space in 4 hours.' - alert: node_filedescriptors_full_in_3h expr: predict_linear(node_filefd_allocated[1h], 3 * 3600) >= node_filefd_maximum for: 20m labels: severity: page annotations: description: '{{$labels.alias}} is running out of available file descriptors in approx. 3 hours' summary: '{{$labels.alias}} is running out of available file descriptors in 3 hours.' - alert: node_load1_90percent expr: node_load1 / ON(alias) count(node_cpu{mode="system"}) BY (alias) >= 0.9 for: 1h labels: severity: page annotations: description: '{{$labels.alias}} is running with > 90% total load for at least 1h.' summary: '{{$labels.alias}}: Running on high load.' - alert: node_cpu_util_90percent expr: 100 - (avg(irate(node_cpu{mode="idle"}[5m])) BY (alias) * 100) >= 90 for: 1h labels: severity: page annotations: description: '{{$labels.alias}} has total CPU utilization over 90% for at least 1h.' summary: '{{$labels.alias}}: High CPU utilization.' - alert: node_ram_using_90percent expr: avg_over_time(node_ram_usage_percent[2m]) > 90 for: 30m labels: severity: page annotations: description: '{{$labels.alias}} is using at least 90% of its RAM for at least 30 minutes now.' summary: '{{$labels.alias}}: Using lots of RAM.' - alert: node_swap_using_80percent expr: avg_over_time(node_swap_usage_percent[2m]) > 80 for: 10m labels: severity: page annotations: description: '{{$labels.alias}} is using 80% of its swap space for at least 10 minutes now.' summary: '{{$labels.alias}}: Running out of swap soon.' - alert: node_high_cpu_load expr: node_load15 / on(alias) count(node_cpu{mode="system"}) by (alias) >= 0 for: 1m labels: severity: warning annotations: description: '{{$labels.alias}} is running with load15 > 1 for at least 5 minutes: {{$value}}' summary: '{{$labels.alias}}: Running on high load: {{$value}}' - alert: node_high_memory_load expr: avg_over_time(node_ram_usage_percent[2m]) > 85 for: 1m labels: severity: warning annotations: description: Host memory usage is {{ humanize $value }}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}. summary: Server memory is almost full - alert: node_high_storage_load expr: avg_over_time(node_storage_usage_percent{mountpoint="/"}[2m]) > 85 for: 30s labels: severity: warning annotations: description: Host storage usage is {{ humanize $value }}%. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}. summary: Server storage is almost full - alert: node_high_swap expr: (node_memory_SwapTotal - node_memory_SwapFree) < (node_memory_SwapTotal * 0.4) for: 1m labels: severity: warning annotations: description: Host system has a high swap usage of {{ humanize $value }}. Reported by instance {{ $labels.instance }} of job {{ $labels.job }}. summary: Server has a high swap usage - alert: node_high_network_drop_rcv expr: node_network_receive_drop{device!="lo"} > 3000 for: 30s labels: severity: warning annotations: description: Host system has an unusally high drop in network reception ({{ humanize $value }}). Reported by instance {{ $labels.instance }} of job {{ $labels.job }} summary: Server has a high receive drop - alert: node_high_network_drop_send expr: node_network_transmit_drop{device!="lo"} > 3000 for: 30s labels: severity: warning annotations: description: Host system has an unusally high drop in network transmission ({{ humanize $value }}). Reported by instance {{ $labels.instance }} of job {{ $labels.job }} summary: Server has a high transmit drop - alert: node_high_network_errs_rcv expr: node_network_receive_errs{device!="lo"} > 3000 for: 30s labels: severity: warning annotations: description: Host system has an unusally high error rate in network reception ({{ humanize $value }}). Reported by instance {{ $labels.instance }} of job {{ $labels.job }} summary: Server has unusual high reception errors - alert: node_high_network_errs_send expr: node_network_transmit_errs{device!="lo"} > 3000 for: 30s labels: severity: warning annotations: description: Host system has an unusally high error rate in network transmission ({{ humanize $value }}). Reported by instance {{ $labels.instance }} of job {{ $labels.job }} summary: Server has unusual high transmission errors - alert: node_network_conntrack_usage_80percent expr: sort(node_nf_conntrack_entries{job="node-exporter"} > node_nf_conntrack_entries_limit{job="node-exporter"} * 0.8) for: 5m labels: severity: page annotations: description: '{{$labels.instance}} has network conntrack entries of {{ $value }} which is more than 80% of maximum limit' summary: '{{$labels.instance}}: available network conntrack entries are low.' - alert: node_entropy_available_low expr: node_entropy_available_bits < 300 for: 5m labels: severity: page annotations: description: '{{$labels.instance}} has available entropy bits of {{ $value }} which is less than required of 300' summary: '{{$labels.instance}}: is low on entropy bits.' - alert: node_hwmon_high_cpu_temp expr: node_hwmon_temp_crit_celsius*0.9 - node_hwmon_temp_celsius < 0 OR node_hwmon_temp_max_celsius*0.95 - node_hwmon_temp_celsius < 0 for: 5m labels: severity: page annotations: description: '{{$labels.alias}} reports hwmon sensor {{$labels.sensor}}/{{$labels.chip}} temperature value is nearly critical: {{$value}}' summary: '{{$labels.alias}}: Sensor {{$labels.sensor}}/{{$labels.chip}} temp is high: {{$value}}' - alert: node_vmstat_paging_rate_high expr: irate(node_vmstat_pgpgin[5m]) > 80 for: 5m labels: severity: page annotations: description: '{{$labels.alias}} has a memory paging rate of change higher than 80%: {{$value}}' summary: '{{$labels.alias}}: memory paging rate is high: {{$value}}' - alert: node_xfs_block_allocation_high expr: 100*(node_xfs_extent_allocation_blocks_allocated_total{job="node-exporter", instance=~"172.17.0.1.*"} / (node_xfs_extent_allocation_blocks_freed_total{job="node-exporter", instance=~"172.17.0.1.*"} + node_xfs_extent_allocation_blocks_allocated_total{job="node-exporter", instance=~"172.17.0.1.*"})) > 80 for: 5m labels: severity: page annotations: description: '{{$labels.alias}} has xfs allocation blocks higher than 80%: {{$value}}' summary: '{{$labels.alias}}: xfs block allocation high: {{$value}}' - alert: node_network_bond_slaves_down expr: node_net_bonding_slaves - node_net_bonding_slaves_active > 0 for: 5m labels: severity: page annotations: description: '{{ $labels.master }} is missing {{ $value }} slave interface(s).' summary: 'Instance {{ $labels.instance }}: {{ $labels.master }} missing {{ $value }} slave interface(s)' - alert: node_numa_memory_used expr: 100*node_memory_numa_MemUsed / node_memory_numa_MemTotal > 80 for: 5m labels: severity: page annotations: description: '{{$labels.alias}} has more than 80% NUMA memory usage: {{ $value }}' summary: '{{$labels.alias}}: has high NUMA memory usage: {{$value}}' - alert: node_ntp_clock_skew_high expr: abs(node_ntp_drift_seconds) > 2 for: 5m labels: severity: page annotations: description: '{{$labels.alias}} has time difference of more than 2 seconds compared to NTP server: {{ $value }}' summary: '{{$labels.alias}}: time is skewed by : {{$value}} seconds' - alert: node_disk_read_latency expr: (rate(node_disk_read_time_ms[5m]) / rate(node_disk_reads_completed[5m])) > 40 for: 5m labels: severity: page annotations: description: '{{$labels.device}} has a high read latency of {{ $value }}' summary: 'High read latency observed for device {{ $labels.device }}' - alert: node_disk_write_latency expr: (rate(node_disk_write_time_ms[5m]) / rate(node_disk_writes_completed[5m])) > 40 for: 5m labels: severity: page annotations: description: '{{$labels.device}} has a high write latency of {{ $value }}' summary: 'High write latency observed for device {{ $labels.device }}' ... ================================================ FILE: values_overrides/prometheus/openstack.yaml ================================================ --- conf: prometheus: rules: openstack: groups: - name: mariadb.rules rules: - alert: prom_exporter_mariadb_openstack_unavailable expr: avg_over_time(up{job="mysql-exporter",kubernetes_namespace="openstack"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: MariaDB exporter in {{ $labels.kubernetes_namespace }} is not collecting metrics or is not available for past 10 minutes title: MariaDB exporter is not collecting metrics or is not available - alert: prom_exporter_mariadb_osh_infra_unavailable expr: avg_over_time(up{job="mysql-exporter",kubernetes_namespace="osh-infra"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: MariaDB exporter in {{ $labels.kubernetes_namespace }} is not collecting metrics or is not available for past 10 minutes title: MariaDB exporter is not collecting metrics or is not available - alert: mariadb_table_lock_wait_high expr: 100 * mysql_global_status_table_locks_waited/(mysql_global_status_table_locks_waited + mysql_global_status_table_locks_immediate) > 30 for: 10m labels: severity: warning annotations: description: 'Mariadb has high table lock waits of {{ $value }} percentage' summary: 'Mariadb table lock waits are high' - alert: mariadb_node_not_ready expr: mysql_global_status_wsrep_ready != 1 for: 10m labels: severity: warning annotations: description: '{{$labels.job}} on {{$labels.instance}} is not ready.' summary: 'Galera cluster node not ready' - alert: mariadb_galera_node_out_of_sync expr: mysql_global_status_wsrep_local_state != 4 AND mysql_global_variables_wsrep_desync == 0 for: 10m labels: severity: warning annotations: description: '{{$labels.job}} on {{$labels.instance}} is not in sync ({{$value}} != 4)' summary: 'Galera cluster node out of sync' - alert: mariadb_innodb_replication_fallen_behind expr: (mysql_global_variables_innodb_replication_delay > 30) AND on (instance) (predict_linear(mysql_global_variables_innodb_replication_delay[5m], 60*2) > 0) for: 10m labels: severity: warning annotations: description: 'The mysql innodb replication has fallen behind and is not recovering' summary: 'MySQL innodb replication is lagging' - name: openstack.rules rules: - alert: prom_exporter_openstack_unavailable expr: avg_over_time(up{job="openstack-metrics"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: Openstack exporter is not collecting metrics or is not available for past 10 minutes title: Openstack exporter is not collecting metrics or is not available - alert: os_glance_api_availability expr: openstack_check_glance_api != 1 for: 5m labels: severity: page annotations: description: 'Glance API is not available at {{$labels.url}} for more than 5 minutes' summary: 'Glance API is not available at {{$labels.url}}' - alert: os_nova_api_availability expr: openstack_check_nova_api != 1 for: 5m labels: severity: page annotations: description: 'Nova API is not available at {{$labels.url}} for more than 5 minutes' summary: 'Nova API is not available at {{$labels.url}}' - alert: os_keystone_api_availability expr: openstack_check_keystone_api != 1 for: 5m labels: severity: page annotations: description: 'Keystone API is not available at {{$labels.url}} for more than 5 minutes' summary: 'Keystone API is not available at {{$labels.url}}' - alert: os_neutron_api_availability expr: openstack_check_neutron_api != 1 for: 5m labels: severity: page annotations: description: 'Neutron API is not available at {{$labels.url}} for more than 5 minutes' summary: 'Neutron API is not available at {{$labels.url}}' - alert: os_neutron_metadata_agent_availability expr: openstack_services_neutron_metadata_agent_down_total > 0 for: 5m labels: severity: page annotations: description: 'One or more neutron metadata_agents are not available for more than 5 minutes' summary: 'One or more neutron metadata_agents are not available' - alert: os_neutron_openvswitch_agent_availability expr: openstack_services_neutron_openvswitch_agent_down_total > 0 for: 5m labels: severity: page annotations: description: 'One or more neutron openvswitch agents are not available for more than 5 minutes' summary: 'One or more neutron openvswitch agents are not available' - alert: os_neutron_dhcp_agent_availability expr: openstack_services_neutron_dhcp_agent_down_total > 0 for: 5m labels: severity: page annotations: description: 'One or more neutron dhcp agents are not available for more than 5 minutes' summary: 'One or more neutron dhcp agents are not available' - alert: os_neutron_l3_agent_availability expr: openstack_services_neutron_l3_agent_down_total > 0 for: 5m labels: severity: page annotations: description: 'One or more neutron L3 agents are not available for more than 5 minutes' summary: 'One or more neutron L3 agents are not available' - alert: os_swift_api_availability expr: openstack_check_swift_api != 1 for: 5m labels: severity: page annotations: description: 'Swift API is not available at {{$labels.url}} for more than 5 minutes' summary: 'Swift API is not available at {{$labels.url}}' - alert: os_cinder_api_availability expr: openstack_check_cinder_api != 1 for: 5m labels: severity: page annotations: description: 'Cinder API is not available at {{$labels.url}} for more than 5 minutes' summary: 'Cinder API is not available at {{$labels.url}}' - alert: os_cinder_scheduler_availability expr: openstack_services_cinder_cinder_scheduler != 1 for: 5m labels: severity: page annotations: description: 'Cinder scheduler is not available for more than 5 minutes' summary: 'Cinder scheduler is not available' - alert: os_heat_api_availability expr: openstack_check_heat_api != 1 for: 5m labels: severity: page annotations: description: 'Heat API is not available at {{$labels.url}} for more than 5 minutes' summary: 'Heat API is not available at {{$labels.url}}' - alert: os_nova_compute_disabled expr: openstack_services_nova_compute_disabled_total > 0 for: 5m labels: severity: page annotations: description: 'nova-compute is disabled on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-compute is disabled on some hosts' - alert: os_nova_conductor_disabled expr: openstack_services_nova_conductor_disabled_total > 0 for: 5m labels: severity: page annotations: description: 'nova-conductor is disabled on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-conductor is disabled on some hosts' - alert: os_nova_consoleauth_disabled expr: openstack_services_nova_consoleauth_disabled_total > 0 for: 5m labels: severity: page annotations: description: 'nova-consoleauth is disabled on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-consoleauth is disabled on some hosts' - alert: os_nova_scheduler_disabled expr: openstack_services_nova_scheduler_disabled_total > 0 for: 5m labels: severity: page annotations: description: 'nova-scheduler is disabled on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-scheduler is disabled on some hosts' - alert: os_nova_compute_down expr: openstack_services_nova_compute_down_total > 0 for: 5m labels: severity: page annotations: description: 'nova-compute is down on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-compute is down on some hosts' - alert: os_nova_conductor_down expr: openstack_services_nova_conductor_down_total > 0 for: 5m labels: severity: page annotations: description: 'nova-conductor is down on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-conductor is down on some hosts' - alert: os_nova_consoleauth_down expr: openstack_services_nova_consoleauth_down_total > 0 for: 5m labels: severity: page annotations: description: 'nova-consoleauth is down on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-consoleauth is down on some hosts' - alert: os_nova_scheduler_down expr: openstack_services_nova_scheduler_down_total > 0 for: 5m labels: severity: page annotations: description: 'nova-scheduler is down on certain hosts for more than 5 minutes' summary: 'Openstack compute service nova-scheduler is down on some hosts' - alert: os_vm_vcpu_usage_high expr: openstack_total_used_vcpus * 100/(openstack_total_used_vcpus + openstack_total_free_vcpus) > 80 for: 5m labels: severity: page annotations: description: 'Openstack VM vcpu usage is hight at {{$value}} percent' summary: 'Openstack VM vcpu usage is high' - alert: os_vm_ram_usage_high expr: openstack_total_used_ram_MB * 100/(openstack_total_used_ram_MB + openstack_total_free_ram_MB) > 80 for: 5m labels: severity: page annotations: description: 'Openstack VM RAM usage is hight at {{$value}} percent' summary: 'Openstack VM RAM usage is high' - alert: os_vm_disk_usage_high expr: openstack_total_used_disk_GB * 100/ ( openstack_total_used_disk_GB + openstack_total_free_disk_GB ) > 80 for: 5m labels: severity: page annotations: description: 'Openstack VM Disk usage is hight at {{$value}} percent' summary: 'Openstack VM Disk usage is high' - name: rabbitmq.rules rules: - alert: rabbitmq_network_pratitions_detected expr: min(partitions) by(instance) > 0 for: 10m labels: severity: warning annotations: description: 'RabbitMQ at {{ $labels.instance }} has {{ $value }} partitions' summary: 'RabbitMQ Network partitions detected' - alert: rabbitmq_down expr: min(rabbitmq_up) by(instance) != 1 for: 10m labels: severity: page annotations: description: 'RabbitMQ Server instance {{ $labels.instance }} is down' summary: 'The RabbitMQ Server instance at {{ $labels.instance }} has been down the last 10 mins' - alert: rabbitmq_file_descriptor_usage_high expr: fd_used * 100 /fd_total > 80 for: 10m labels: severity: warning annotations: description: 'RabbitMQ Server instance {{ $labels.instance }} has high file descriptor usage of {{ $value }} percent.' summary: 'RabbitMQ file descriptors usage is high for last 10 mins' - alert: rabbitmq_node_disk_free_alarm expr: node_disk_free_alarm > 0 for: 10m labels: severity: warning annotations: description: 'RabbitMQ Server instance {{ $labels.instance }} has low disk free space available.' summary: 'RabbitMQ disk space usage is high' - alert: rabbitmq_node_memory_alarm expr: node_mem_alarm > 0 for: 10m labels: severity: warning annotations: description: 'RabbitMQ Server instance {{ $labels.instance }} has low free memory.' summary: 'RabbitMQ memory usage is high' - alert: rabbitmq_less_than_3_nodes expr: running < 3 for: 10m labels: severity: warning annotations: description: 'RabbitMQ Server has less than 3 nodes running.' summary: 'RabbitMQ server is at risk of loosing data' - alert: rabbitmq_queue_messages_returned_high expr: queue_messages_returned_total/queue_messages_published_total * 100 > 50 for: 5m labels: severity: warning annotations: description: 'RabbitMQ Server is returing more than 50 percent of messages received.' summary: 'RabbitMQ server is returning more than 50 percent of messages received.' - alert: rabbitmq_consumers_low_utilization expr: queue_consumer_utilisation < .4 for: 5m labels: severity: warning annotations: description: 'RabbitMQ consumers message consumption speed is low' summary: 'RabbitMQ consumers message consumption speed is low' - alert: rabbitmq_high_message_load expr: queue_messages_total > 17000 or increase(queue_messages_total[5m]) > 4000 for: 5m labels: severity: warning annotations: description: 'RabbitMQ has high message load. Total Queue depth > 17000 or growth more than 4000 messages.' summary: 'RabbitMQ has high message load' ... ================================================ FILE: values_overrides/prometheus/postgresql.yaml ================================================ --- conf: prometheus: rules: postgresql: groups: - name: postgresql.rules rules: - alert: prom_exporter_postgresql_unavailable expr: avg_over_time(up{job="postgresql-exporter"}[5m]) == 0 for: 5m labels: severity: warning annotations: description: postgresql exporter is not collecting metrics or is not available for past 10 minutes title: postgresql exporter is not collecting metrics or is not available - alert: pg_replication_fallen_behind expr: (pg_replication_lag > 120) and ON(instance) (pg_replication_is_replica == 1) for: 5m labels: severity: warning annotations: description: Replication lag on server {{$labels.instance}} is currently {{$value | humanizeDuration }} title: Postgres Replication lag is over 2 minutes - alert: pg_connections_too_high expr: sum(pg_stat_activity_count) BY (environment, fqdn) > ON(fqdn) pg_settings_max_connections * 0.95 for: 5m labels: severity: warn channel: database annotations: title: Postgresql has {{$value}} connections on {{$labels.fqdn}} which is close to the maximum - alert: pg_deadlocks_detected expr: sum by(datname) (rate(pg_stat_database_deadlocks[1m])) > 0 for: 5m labels: severity: warn annotations: description: postgresql at {{$labels.instance}} is showing {{$value}} rate of deadlocks for database {{$labels.datname}} title: Postgres server is experiencing deadlocks ... ================================================ FILE: values_overrides/prometheus/tls.yaml ================================================ --- endpoints: monitoring: host_fqdn_override: default: tls: secretName: prometheus-tls-api issuerRef: name: ca-issuer kind: ClusterIssuer scheme: default: "https" port: http: default: 443 network: prometheus: ingress: annotations: nginx.ingress.kubernetes.io/backend-protocol: https conf: httpd: | ServerRoot "/usr/local/apache2" Listen 443 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule ldap_module modules/mod_ldap.so LoadModule authnz_ldap_module modules/mod_authnz_ldap.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule proxy_html_module modules/mod_proxy_html.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule slotmem_shm_module modules/mod_slotmem_shm.so LoadModule slotmem_plain_module modules/mod_slotmem_plain.so LoadModule unixd_module modules/mod_unixd.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule ssl_module modules/mod_ssl.so User daemon Group daemon AllowOverride none Require all denied Require all denied ErrorLog /dev/stderr LogLevel warn LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded CustomLog /dev/stdout common CustomLog /dev/stdout combined CustomLog /dev/stdout proxy env=forwarded AllowOverride None Options None Require all granted RequestHeader unset Proxy early Include conf/extra/proxy-html.conf # Expose metrics to all users, as this is not sensitive information and # circumvents the inability of Prometheus to interpolate environment vars # in its configuration file ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics Satisfy Any Allow from all # Expose the /federate endpoint to all users, as this is also not # sensitive information and circumvents the inability of Prometheus to # interpolate environment vars in its configuration file ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/metrics Satisfy Any Allow from all # Restrict general user (LDAP) access to the /graph endpoint, as general trusted # users should only be able to query Prometheus for metrics and not have access # to information like targets, configuration, flags or build info for Prometheus ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/ AuthName "Prometheus" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/graph ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/graph AuthName "Prometheus" AuthType Basic AuthBasicProvider file ldap AuthUserFile /usr/local/apache2/conf/.htpasswd AuthLDAPBindDN {{ .Values.endpoints.ldap.auth.admin.bind }} AuthLDAPBindPassword {{ .Values.endpoints.ldap.auth.admin.password }} AuthLDAPURL {{ tuple "ldap" "default" "ldap" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | quote }} Require valid-user # Restrict access to the /config (dashboard) and /api/v1/status/config (http) endpoints # to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/config ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/config AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/config ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/config AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /flags (dashboard) and /api/v1/status/flags (http) endpoints # to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/flags ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/flags AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/flags ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/status/flags AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /status (dashboard) endpoint to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/status ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/status AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /rules (dashboard) endpoint to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/rules ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/rules AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /targets (dashboard) and /api/v1/targets (http) endpoints # to the admin user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/targets ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/targets AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/targets ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/targets AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user # Restrict access to the /api/v1/admin/tsdb/ endpoints (http) to the admin user. # These endpoints are disabled by default, but are included here to ensure only # an admin user has access to these endpoints when enabled ProxyPass http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/admin/tsdb/ ProxyPassReverse http://localhost:{{ tuple "monitoring" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}/api/v1/admin/tsdb/ AuthName "Prometheus" AuthType Basic AuthBasicProvider file AuthUserFile /usr/local/apache2/conf/.htpasswd Require valid-user SSLEngine On SSLProxyEngine on SSLCertificateFile /etc/prometheus/certs/tls.crt SSLCertificateKeyFile /etc/prometheus/certs/tls.key SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 SSLHonorCipherOrder on manifests: certificates: true ... ================================================ FILE: values_overrides/prometheus-alertmanager/apparmor.yaml ================================================ --- pod: security_context: server: container: prometheus_alertmanager: appArmorProfile: type: RuntimeDefault prometheus_alertmanager_perms: appArmorProfile: type: RuntimeDefault apache_proxy: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/prometheus-alertmanager/gateway.yaml ================================================ # Gateway API overrides for Prometheus Alertmanager. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: alertmanager: host_fqdn_override: public: host: alertmanager.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: alertmanager-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.alertmanager.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: alerts-engine port: 9093 ... ================================================ FILE: values_overrides/prometheus-blackbox-exporter/apparmor.yaml ================================================ --- pod: security_context: prometheus_blackbox_exporter: container: blackbox_exporter: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/prometheus-kube-state-metrics/apparmor.yaml ================================================ --- pod: security_context: exporter: container: kube_state_metrics: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/apparmor.yaml ================================================ --- pod: security_context: prometheus_mysql_exporter: container: exporter: appArmorProfile: type: RuntimeDefault prometheus_create_mysql_user: container: main: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_mysql_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/prometheus.yaml ================================================ --- monitoring: prometheus: enabled: true manifests: monitoring: prometheus: configmap_bin: true deployment_exporter: true job_user_create: true secret_etc: true service_exporter: true network_policy_exporter: true ... ================================================ FILE: values_overrides/prometheus-mysql-exporter/tls.yaml ================================================ --- endpoints: oslo_db: host_fqdn_override: default: tls: secretName: mariadb-tls-direct issuerRef: name: ca-issuer kind: ClusterIssuer manifests: certificates: true ... ================================================ FILE: values_overrides/prometheus-node-exporter/apparmor.yaml ================================================ --- pod: security_context: metrics: container: node_exporter: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/prometheus-openstack-exporter/apparmor.yaml ================================================ --- pod: security_context: exporter: container: openstack_metrics_exporter: appArmorProfile: type: RuntimeDefault ks_user: container: prometheus_openstack_exporter_ks_user: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/prometheus-openstack-exporter/netpol.yaml ================================================ --- manifests: network_policy: true ... ================================================ FILE: values_overrides/prometheus-openstack-exporter/tls.yaml ================================================ --- manifests: certificates: true ... ================================================ FILE: values_overrides/prometheus-process-exporter/apparmor.yaml ================================================ --- pod: security_context: metrics: container: process_exporter: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/rabbitmq/2024.2-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_rabbitmq_exporter_helm_tests: quay.io/airshipit/heat:2024.2-ubuntu_jammy rabbitmq_init: quay.io/airshipit/heat:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/rabbitmq/2025.1-ubuntu_jammy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_rabbitmq_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy rabbitmq_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/rabbitmq/2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_rabbitmq_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbitmq_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/rabbitmq/2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_rabbitmq_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble rabbitmq_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/rabbitmq/apparmor.yaml ================================================ --- pod: security_context: cluster_wait: container: rabbitmq_cluster_wait: appArmorProfile: type: RuntimeDefault rabbitmq_cookie: appArmorProfile: type: RuntimeDefault server: container: rabbitmq: appArmorProfile: type: RuntimeDefault rabbitmq_perms: appArmorProfile: type: RuntimeDefault rabbitmq_cookie: appArmorProfile: type: RuntimeDefault rabbitmq_password: appArmorProfile: type: RuntimeDefault exporter: container: rabbitmq_exporter: appArmorProfile: type: RuntimeDefault test: container: rabbitmq_test: appArmorProfile: type: RuntimeDefault kubernetes_entrypoint: container: kubernetes_entrypoint: appArmorProfile: type: RuntimeDefault ... ================================================ FILE: values_overrides/rabbitmq/builtin-metrics.yaml ================================================ --- # This enable Rabbitmq built-in prometheus plugin conf: enabled_plugins: - rabbitmq_management - rabbitmq_peer_discovery_k8s - rabbitmq_prometheus manifests: monitoring: prometheus: configmap_bin: false deployment_exporter: false service_exporter: false network_policy_exporter: false ... ================================================ FILE: values_overrides/rabbitmq/gateway.yaml ================================================ # Gateway API overrides for RabbitMQ. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: oslo_messaging: host_fqdn_override: public: host: rabbitmq.openstack-helm.org manifests: ingress_management: false service_ingress_management: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: rabbitmq-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.oslo_messaging.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: rabbitmq port: 15672 ... ================================================ FILE: values_overrides/rabbitmq/loci-2025.1-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_rabbitmq_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci rabbitmq_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/rabbitmq/loci-2025.2-ubuntu_noble.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- images: tags: prometheus_rabbitmq_exporter_helm_tests: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci rabbitmq_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/rabbitmq/netpol.yaml ================================================ --- network_policy: rabbitmq: ingress: - from: - podSelector: matchLabels: application: keystone - podSelector: matchLabels: application: heat - podSelector: matchLabels: application: glance - podSelector: matchLabels: application: cinder - podSelector: matchLabels: application: aodh - podSelector: matchLabels: application: barbican - podSelector: matchLabels: application: ceilometer - podSelector: matchLabels: application: designate - podSelector: matchLabels: application: ironic - podSelector: matchLabels: application: magnum - podSelector: matchLabels: application: mistral - podSelector: matchLabels: application: nova - podSelector: matchLabels: application: neutron - podSelector: matchLabels: application: senlin - podSelector: matchLabels: application: placement - podSelector: matchLabels: application: rabbitmq - podSelector: matchLabels: application: prometheus_rabbitmq_exporter ports: # AMQP port - protocol: TCP port: 5672 # HTTP API ports - protocol: TCP port: 15672 - protocol: TCP port: 80 - from: - podSelector: matchLabels: application: rabbitmq ports: # Clustering port AMQP + 20000 - protocol: TCP port: 25672 # Erlang Port Mapper Daemon (epmd) - protocol: TCP port: 4369 egress: - to: - podSelector: matchLabels: application: rabbitmq ports: # Erlang port mapper daemon (epmd) - protocol: TCP port: 4369 # Rabbit clustering port AMQP + 20000 - protocol: TCP port: 25672 # NOTE(lamt): Set by inet_dist_listen_{min/max}. Firewalls must # permit traffic in this range to pass between clustered nodes. # - protocol: TCP # port: 35197 - to: - ipBlock: cidr: %%%REPLACE_API_ADDR%%%/32 ports: - protocol: TCP port: %%%REPLACE_API_PORT%%% manifests: monitoring: prometheus: network_policy_exporter: true network_policy: true ... ================================================ FILE: values_overrides/rabbitmq/rabbitmq-exporter.yaml ================================================ --- # This enable external pod for rabbitmq-exporter manifests: monitoring: prometheus: configmap_bin: true deployment_exporter: true service_exporter: true network_policy_exporter: false ... ================================================ FILE: values_overrides/rabbitmq/tls.yaml ================================================ --- conf: rabbitmq: ssl_options: cacertfile: "/etc/rabbitmq/certs/ca.crt" certfile: "/etc/rabbitmq/certs/tls.crt" keyfile: "/etc/rabbitmq/certs/tls.key" verify: verify_peer fail_if_no_peer_cert: false management: ssl: cacertfile: "/etc/rabbitmq/certs/ca.crt" certfile: "/etc/rabbitmq/certs/tls.crt" keyfile: "/etc/rabbitmq/certs/tls.key" endpoints: oslo_messaging: host_fqdn_override: default: tls: secretName: rabbitmq-tls-direct issuerRef: name: ca-issuer kind: ClusterIssuer port: https: default: 15680 public: 443 manifests: certificates: true ... ================================================ FILE: values_overrides/rally/annotations.yaml ================================================ --- annotations: secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: rally: custom.tld/key: "value" ... ================================================ FILE: values_overrides/rally/mariadb-operator.yaml ================================================ --- conf: rally: database: connection: null manifests: job_db_init: false etcSources: rally_api: - rally-db-conn rally_db_sync: - rally-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: rally namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: rally namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: rally-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: rally-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "rally" table: "*" username: rally grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: rally-db-conn spec: mariaDbRef: name: mariadb username: rally passwordSecretKeyRef: name: rally-db-password key: password database: rally secretName: rally-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/rally/tls-offloading.yaml ================================================ --- endpoints: identity: auth: admin: cacert: /etc/ssl/certs/openstack-helm.crt rally: cacert: /etc/ssl/certs/openstack-helm.crt test: cacert: /etc/ssl/certs/openstack-helm.crt tls: identity: true ... ================================================ FILE: values_overrides/skyline/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: skyline_db_sync: quay.io/airshipit/skyline:2025.1-ubuntu_jammy skyline: quay.io/airshipit/skyline:2025.1-ubuntu_jammy skyline_nginx: quay.io/airshipit/skyline:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/skyline/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: skyline_db_sync: quay.io/airshipit/skyline:2025.2-ubuntu_noble skyline: quay.io/airshipit/skyline:2025.2-ubuntu_noble skyline_nginx: quay.io/airshipit/skyline:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/skyline/gateway.yaml ================================================ # Gateway API overrides for Skyline. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: skyline: host_fqdn_override: public: host: skyline.openstack-helm.org manifests: ingress: false service_ingress: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: skyline-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.skyline.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: skyline-api port: 9999 ... ================================================ FILE: values_overrides/skyline/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: skyline_db_sync: quay.io/airshipit/skyline:2025.2-ubuntu_noble_loci skyline: quay.io/airshipit/skyline:2025.2-ubuntu_noble_loci skyline_nginx: quay.io/airshipit/skyline:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci dep_check: 'quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy' ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/swift/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/swift:2025.2-ubuntu_noble test: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_proxy: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_account: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_container: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_object: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_storage: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_storage_init: quay.io/airshipit/swift:2025.2-ubuntu_noble swift_ring_builder: quay.io/airshipit/swift:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/swift/gateway.yaml ================================================ # Gateway API overrides for Swift. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: object_store: host_fqdn_override: public: host: swift.openstack-helm.org manifests: ingress_proxy: false service_ingress_proxy: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: swift-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.object_store.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: swift-proxy port: 8080 ... ================================================ FILE: values_overrides/tacker/2024.2-ubuntu_jammy.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: tacker_server: quay.io/airshipit/tacker:2024.2-ubuntu_jammy tacker_conductor: quay.io/airshipit/tacker:2024.2-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy tacker_db_sync: quay.io/airshipit/tacker:2024.2-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/tacker/2025.1-ubuntu_jammy.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: tacker_server: quay.io/airshipit/tacker:2025.1-ubuntu_jammy tacker_conductor: quay.io/airshipit/tacker:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy tacker_db_sync: quay.io/airshipit/tacker:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/tacker/2025.1-ubuntu_noble.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: tacker_server: quay.io/airshipit/tacker:2025.1-ubuntu_noble tacker_conductor: quay.io/airshipit/tacker:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble tacker_db_sync: quay.io/airshipit/tacker:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/tacker/2025.2-ubuntu_noble.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: tacker_server: quay.io/airshipit/tacker:2025.2-ubuntu_noble tacker_conductor: quay.io/airshipit/tacker:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble tacker_db_sync: quay.io/airshipit/tacker:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/tacker/annotations.yaml ================================================ --- annotations: secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: tacker: custom.tld/key: "value" tls: nfv_orchestration_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/tacker/gateway.yaml ================================================ # Gateway API overrides for Tacker. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: nfv_orchestration: host_fqdn_override: public: host: tacker.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: tacker-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.nfv_orchestration.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: tacker-api port: 9890 ... ================================================ FILE: values_overrides/tacker/loci-2025.1-ubuntu_noble.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: tacker_server: quay.io/airshipit/tacker:2025.1-ubuntu_noble_loci tacker_conductor: quay.io/airshipit/tacker:2025.1-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci tacker_db_sync: quay.io/airshipit/tacker:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/tacker/loci-2025.2-ubuntu_noble.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: tacker_server: quay.io/airshipit/tacker:2025.2-ubuntu_noble_loci tacker_conductor: quay.io/airshipit/tacker:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci tacker_db_sync: quay.io/airshipit/tacker:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/tacker/mariadb-operator.yaml ================================================ --- conf: tacker: database: connection: null manifests: job_db_init: false etcSources: tacker_api: - tacker-db-conn tacker_db_sync: - tacker-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: tacker namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: tacker namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: tacker-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: tacker-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "tacker" table: "*" username: tacker grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: tacker-db-conn spec: mariaDbRef: name: mariadb username: tacker passwordSecretKeyRef: name: tacker-db-password key: password database: tacker secretName: tacker-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/tempest/annotations.yaml ================================================ --- annotations: secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: tempest: custom.tld/key: "value" ... ================================================ FILE: values_overrides/trove/2024.2-ubuntu_jammy.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 db_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy trove_db_sync: quay.io/airshipit/trove:2024.2-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy trove_api: quay.io/airshipit/trove:2024.2-ubuntu_jammy trove_conductor: quay.io/airshipit/trove:2024.2-ubuntu_jammy trove_taskmanager: quay.io/airshipit/trove:2024.2-ubuntu_jammy trove_db_purge: quay.io/airshipit/trove:2024.2-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 ... ================================================ FILE: values_overrides/trove/2025.1-ubuntu_jammy.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy trove_db_sync: quay.io/airshipit/trove:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy trove_api: quay.io/airshipit/trove:2025.1-ubuntu_jammy trove_conductor: quay.io/airshipit/trove:2025.1-ubuntu_jammy trove_taskmanager: quay.io/airshipit/trove:2025.1-ubuntu_jammy trove_db_purge: quay.io/airshipit/trove:2025.1-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 ... ================================================ FILE: values_overrides/trove/2025.1-ubuntu_noble.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble trove_db_sync: quay.io/airshipit/trove:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble trove_api: quay.io/airshipit/trove:2025.1-ubuntu_noble trove_conductor: quay.io/airshipit/trove:2025.1-ubuntu_noble trove_taskmanager: quay.io/airshipit/trove:2025.1-ubuntu_noble trove_db_purge: quay.io/airshipit/trove:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 ... ================================================ FILE: values_overrides/trove/2025.2-ubuntu_noble.yaml ================================================ # Default values for tacker. # This is a YAML-formatted file. # Declare variables to be passed into your templates. --- images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble trove_db_sync: quay.io/airshipit/trove:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble trove_api: quay.io/airshipit/trove:2025.2-ubuntu_noble trove_conductor: quay.io/airshipit/trove:2025.2-ubuntu_noble trove_taskmanager: quay.io/airshipit/trove:2025.2-ubuntu_noble trove_db_purge: quay.io/airshipit/trove:2025.2-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 ... ================================================ FILE: values_overrides/trove/annotations.yaml ================================================ --- annotations: secret: default: custom.tld/key: "value" custom.tld/key2: "value2" identity: admin: another.tld/foo: "bar" oci_image_registry: trove: custom.tld/key: "value" tls: nfv_orchestration_api_public: custom.tld/key: "value" ... ================================================ FILE: values_overrides/trove/gateway.yaml ================================================ # Gateway API overrides for Trove. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: database: host_fqdn_override: public: host: trove.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: trove-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.database.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: trove-api port: 8779 ... ================================================ FILE: values_overrides/trove/mariadb-operator.yaml ================================================ --- conf: trove: database: connection: null manifests: job_db_init: false etcSources: trove_api: - trove-db-conn trove_db_sync: - trove-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: trove namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: trove namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: trove-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: trove-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "trove" table: "*" username: trove grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: trove-db-conn spec: mariaDbRef: name: mariadb username: trove passwordSecretKeyRef: name: trove-db-password key: password database: trove secretName: trove-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/watcher/2024.2-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2024.2-ubuntu_jammy watcher_api: quay.io/airshipit/watcher:2024.2-ubuntu_jammy watcher_decision_engine: quay.io/airshipit/watcher:2024.2-ubuntu_jammy watcher_applier: quay.io/airshipit/watcher:2024.2-ubuntu_jammy watcher_db_sync: quay.io/airshipit/watcher:2024.2-ubuntu_jammy ... ================================================ FILE: values_overrides/watcher/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy watcher_api: quay.io/airshipit/watcher:2025.1-ubuntu_jammy watcher_decision_engine: quay.io/airshipit/watcher:2025.1-ubuntu_jammy watcher_applier: quay.io/airshipit/watcher:2025.1-ubuntu_jammy watcher_db_sync: quay.io/airshipit/watcher:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/watcher/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble watcher_api: quay.io/airshipit/watcher:2025.1-ubuntu_noble watcher_decision_engine: quay.io/airshipit/watcher:2025.1-ubuntu_noble watcher_applier: quay.io/airshipit/watcher:2025.1-ubuntu_noble watcher_db_sync: quay.io/airshipit/watcher:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/watcher/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble watcher_api: quay.io/airshipit/watcher:2025.2-ubuntu_noble watcher_decision_engine: quay.io/airshipit/watcher:2025.2-ubuntu_noble watcher_applier: quay.io/airshipit/watcher:2025.2-ubuntu_noble watcher_db_sync: quay.io/airshipit/watcher:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/watcher/gateway.yaml ================================================ # Gateway API overrides for Watcher. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: infra_optim: host_fqdn_override: public: host: watcher.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: watcher-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.infra_optim.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: watcher-api port: 9322 ... ================================================ FILE: values_overrides/watcher/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci watcher_api: quay.io/airshipit/watcher:2025.1-ubuntu_noble_loci watcher_decision_engine: quay.io/airshipit/watcher:2025.1-ubuntu_noble_loci watcher_applier: quay.io/airshipit/watcher:2025.1-ubuntu_noble_loci watcher_db_sync: quay.io/airshipit/watcher:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/watcher/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci watcher_api: quay.io/airshipit/watcher:2025.2-ubuntu_noble_loci watcher_decision_engine: quay.io/airshipit/watcher:2025.2-ubuntu_noble_loci watcher_applier: quay.io/airshipit/watcher:2025.2-ubuntu_noble_loci watcher_db_sync: quay.io/airshipit/watcher:2025.2-ubuntu_noble_loci ... ================================================ FILE: values_overrides/watcher/mariadb-operator.yaml ================================================ --- conf: watcher: database: connection: null manifests: job_db_init: false etcSources: watcher_api: - watcher-db-conn watcher_db_sync: - watcher-db-conn extraObjects: - apiVersion: k8s.mariadb.com/v1alpha1 kind: Database metadata: name: watcher namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true characterSet: utf8 collate: utf8_general_ci retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: User metadata: name: watcher namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true passwordSecretKeyRef: name: watcher-db-password key: password # This field is immutable and defaults to 10, 0 means unlimited. maxUserConnections: 0 host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Grant metadata: name: watcher-grant namespace: openstack spec: mariaDbRef: name: mariadb # name of the MariaDB kind waitForIt: true privileges: - "ALL" database: "watcher" table: "*" username: watcher grantOption: false host: "%" retryInterval: 5s - apiVersion: k8s.mariadb.com/v1alpha1 kind: Connection metadata: name: watcher-db-conn spec: mariaDbRef: name: mariadb username: watcher passwordSecretKeyRef: name: watcher-db-password key: password database: watcher secretName: watcher-db-conn secretTemplate: key: db_conn.conf format: | [database] connection = mysql+pymysql://{{ .Username }}:{{ .Password }}@{{ .Host }}:{{ .Port }}/{{ .Database }}{{ .Params }} healthCheck: interval: 30s retryInterval: 3s serviceName: mariadb ... ================================================ FILE: values_overrides/zaqar/2025.1-ubuntu_jammy.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy zaqar_api: quay.io/airshipit/zaqar:2025.1-ubuntu_jammy zaqar_db_sync: quay.io/airshipit/zaqar:2025.1-ubuntu_jammy ... ================================================ FILE: values_overrides/zaqar/2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble zaqar_api: quay.io/airshipit/zaqar:2025.1-ubuntu_noble zaqar_db_sync: quay.io/airshipit/zaqar:2025.1-ubuntu_noble ... ================================================ FILE: values_overrides/zaqar/2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble zaqar_api: quay.io/airshipit/zaqar:2025.2-ubuntu_noble zaqar_db_sync: quay.io/airshipit/zaqar:2025.2-ubuntu_noble ... ================================================ FILE: values_overrides/zaqar/gateway.yaml ================================================ # Gateway API overrides for Zaqar. # # Public endpoints use *.openstack-helm.org FQDNs which are resolved by # dnsmasq to the MetalLB Gateway VIP. In-cluster pods reach the Gateway # through this DNS path so no ExternalName services are needed. --- endpoints: messaging: host_fqdn_override: public: host: zaqar.openstack-helm.org manifests: ingress_api: false service_ingress_api: false extraObjects: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: zaqar-route namespace: openstack spec: hostnames: - "{{ .Values.endpoints.messaging.host_fqdn_override.public.host }}" parentRefs: - name: gateway-default namespace: envoy-gateway-system rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: zaqar-api port: 8888 ... ================================================ FILE: values_overrides/zaqar/loci-2025.1-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble_loci zaqar_api: quay.io/airshipit/zaqar:2025.1-ubuntu_noble_loci zaqar_db_sync: quay.io/airshipit/zaqar:2025.1-ubuntu_noble_loci ... ================================================ FILE: values_overrides/zaqar/loci-2025.2-ubuntu_noble.yaml ================================================ --- images: tags: bootstrap: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_init: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci db_drop: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_user: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_service: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci ks_endpoints: quay.io/airshipit/openstack-client:2025.2-ubuntu_noble_loci zaqar_api: quay.io/airshipit/zaqar:2025.2-ubuntu_noble_loci zaqar_db_sync: quay.io/airshipit/zaqar:2025.2-ubuntu_noble_loci ... ================================================ FILE: watcher/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack-Helm Watcher name: watcher version: 2025.2.0 home: https://docs.openstack.org/watcher/latest/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Watcher/OpenStack_Project_Watcher_vertical.png sources: - https://opendev.org/openstack/watcher - https://opendev.org/openstack/openstack-helm maintainers: - name: OpenStack-Helm Authors dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: watcher/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: watcher/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex watcher-db-manage --config-file /etc/watcher/watcher.conf upgrade ================================================ FILE: watcher/templates/bin/_watcher-api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec watcher-api \ --config-file /etc/watcher/watcher.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: watcher/templates/bin/_watcher-applier.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec watcher-applier \ --config-file /etc/watcher/watcher.conf ================================================ FILE: watcher/templates/bin/_watcher-decision-engine.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex exec watcher-decision-engine \ --config-file /etc/watcher/watcher.conf ================================================ FILE: watcher/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: watcher-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} {{- if .Values.bootstrap.enabled }} bootstrap.sh: | {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} {{- end }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} watcher-api.sh: | {{ tuple "bin/_watcher-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} watcher-decision-engine.sh: | {{ tuple "bin/_watcher-decision-engine.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} watcher-applier.sh: | {{ tuple "bin/_watcher-applier.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} {{- end }} ================================================ FILE: watcher/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.watcher.keystone_authtoken.auth_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.watcher.keystone_authtoken "auth_uri" -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.auth_url -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.watcher.keystone_authtoken "auth_url" -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.region_name -}} {{- $_ := set .Values.conf.watcher.keystone_authtoken "region_name" .Values.endpoints.identity.auth.watcher.region_name -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.project_name -}} {{- $_ := set .Values.conf.watcher.keystone_authtoken "project_name" .Values.endpoints.identity.auth.watcher.project_name -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.project_domain_name -}} {{- $_ := set .Values.conf.watcher.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.watcher.project_domain_name -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.user_domain_name -}} {{- $_ := set .Values.conf.watcher.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.watcher.user_domain_name -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.username -}} {{- $_ := set .Values.conf.watcher.keystone_authtoken "username" .Values.endpoints.identity.auth.watcher.username -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.password -}} {{- $_ := set .Values.conf.watcher.keystone_authtoken "password" .Values.endpoints.identity.auth.watcher.password -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.watcher.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.watcher.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.watcher.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if and (not (kindIs "invalid" .Values.conf.watcher.database.connection)) (empty .Values.conf.watcher.database.connection) -}} {{- $_ := tuple "oslo_db" "internal" "watcher" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set .Values.conf.watcher.database "connection" -}} {{- end -}} {{- if empty .Values.conf.watcher.DEFAULT.transport_url -}} {{- $_ := tuple "oslo_messaging" "internal" "watcher" "amqp" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set .Values.conf.watcher.DEFAULT "transport_url" -}} {{- end -}} {{- if empty .Values.conf.watcher.api.port -}} {{- $_ := tuple "infra-optim" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set .Values.conf.watcher.api "port" -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: watcher-etc type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} watcher.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.watcher | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} {{ printf "test_template_%d" $key }}: {{ $value.template | b64enc }} {{- end }} {{- end }} ================================================ FILE: watcher/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_watcher_api := .Values.pod.mounts.watcher_api.watcher_api }} {{- $mounts_watcher_api_init := .Values.pod.mounts.watcher_api.init_container }} {{- $serviceAccountName := "watcher-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: watcher-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "watcher" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "watcher" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "watcher" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "watcher" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_watcher_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: watcher-api {{ tuple $envAll "watcher_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: {{ .Values.pod.user.watcher.uid }} command: - /tmp/watcher-api.sh - start lifecycle: preStop: exec: command: - /tmp/watcher-api.sh - stop ports: - name: w-api containerPort: {{ tuple "infra-optim" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: scheme: {{ tuple "infra-optim" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "infra-optim" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.watcher.oslo_concurrency.lock_path }} - name: pod-etc-watcher mountPath: /etc/watcher - name: watcher-bin mountPath: /tmp/watcher-api.sh subPath: watcher-api.sh readOnly: true - name: watcher-etc mountPath: /etc/watcher/watcher.conf subPath: watcher.conf readOnly: true - name: watcher-etc mountPath: {{ .Values.conf.watcher.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.watcher.DEFAULT.log_config_append }} readOnly: true - name: watcher-etc mountPath: /etc/watcher/policy.yaml subPath: policy.yaml readOnly: true {{ if $mounts_watcher_api.volumeMounts }}{{ toYaml $mounts_watcher_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-watcher emptyDir: {} - name: watcher-bin configMap: name: watcher-bin defaultMode: 0555 - name: watcher-etc secret: secretName: watcher-etc defaultMode: 0444 {{ if $mounts_watcher_api.volumes }}{{ toYaml $mounts_watcher_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: watcher/templates/deployment-applier.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.deployment_applier }} {{- $envAll := . }} {{- $mounts_watcher_applier := .Values.pod.mounts.watcher_applier.watcher_applier }} {{- $mounts_watcher_applier_init := .Values.pod.mounts.watcher_applier.init_container }} {{- $serviceAccountName := "watcher-applier" }} {{ tuple $envAll "applier" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: watcher-applier annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "watcher" "applier" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.applier }} selector: matchLabels: {{ tuple $envAll "watcher" "applier" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "watcher" "applier" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "watcher" "applier" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.applier.node_selector_key }}: {{ .Values.labels.applier.node_selector_value }} initContainers: {{ tuple $envAll "applier" $mounts_watcher_applier_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: watcher-applier {{ tuple $envAll "watcher_applier" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.applier | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: {{ .Values.pod.user.watcher.uid }} command: - /tmp/watcher-applier.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.watcher.oslo_concurrency.lock_path }} - name: pod-etc-watcher mountPath: /etc/watcher - name: watcher-bin mountPath: /tmp/watcher-applier.sh subPath: watcher-applier.sh readOnly: true - name: watcher-etc mountPath: /etc/watcher/watcher.conf subPath: watcher.conf readOnly: true - name: watcher-etc mountPath: {{ .Values.conf.watcher.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.watcher.DEFAULT.log_config_append }} readOnly: true {{ if $mounts_watcher_applier.volumeMounts }}{{ toYaml $mounts_watcher_applier.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-watcher emptyDir: {} - name: watcher-bin configMap: name: watcher-bin defaultMode: 0555 - name: watcher-etc secret: secretName: watcher-etc defaultMode: 0444 {{ if $mounts_watcher_applier.volumes }}{{ toYaml $mounts_watcher_applier.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: watcher/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: watcher/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $ingressOpts := dict "envAll" . "backendServiceType" "infra-optim" "backendPort" "w-api" -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: watcher/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "watcher" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.watcher.DEFAULT.log_config_append -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: watcher/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "watcher" -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: watcher/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_init }} {{- $dbInitJob := dict "envAll" . "serviceName" "watcher" -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: watcher/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "watcher" -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: watcher/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "watcher" -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: watcher/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "watcher" "serviceTypes" ( tuple "infra-optim" ) -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: watcher/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "watcher" "serviceTypes" ( tuple "infra-optim" ) -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: watcher/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "watcher" -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: watcher/templates/job-rabbit-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_rabbit_init }} {{- $rmqUserJob := dict "envAll" . "serviceName" "watcher" -}} {{ $rmqUserJob | include "helm-toolkit.manifests.job_rabbit_init" }} {{- end }} ================================================ FILE: watcher/templates/network_policy.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "watcher" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: watcher/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: watcher-api spec: minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} selector: matchLabels: {{ tuple $envAll "watcher" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: watcher/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_rally_test }} {{- $envAll := . }} {{- $mounts_tests := .Values.pod.mounts.watcher_tests.watcher_tests }} {{- $mounts_tests_init := .Values.pod.mounts.watcher_tests.init_container }} {{- $serviceAccountName := print $envAll.Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: {{ print $envAll.Release.Name "-test" }} labels: {{ tuple $envAll "watcher" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} spec: nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} restartPolicy: Never serviceAccountName: {{ $serviceAccountName }} initContainers: {{ tuple $envAll "tests" $mounts_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: {{ .Release.Name }}-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: watcher-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: {{ .Release.Name }}-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: RALLY_ENV_NAME value: {{.Release.Name}} command: - /tmp/rally-test.sh volumeMounts: - name: watcher-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: watcher-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true - name: rally-db mountPath: /var/lib/rally {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} - name: watcher-etc mountPath: {{ $value.name }} subPath: {{ printf "test_template_%d" $key }} readOnly: true {{- end }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: watcher-etc secret: secretName: watcher-etc defaultMode: 0444 - name: watcher-bin configMap: name: watcher-bin defaultMode: 0555 - name: rally-db emptyDir: {} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: watcher/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "watcher" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: DB_CONNECTION: {{ tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc -}} {{- end }} {{- end }} ================================================ FILE: watcher/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "watcher" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: watcher/templates/secret-rabbitmq.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_rabbitmq }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "watcher" }} {{- $secretName := index $envAll.Values.secrets.oslo_messaging $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} type: Opaque data: RABBITMQ_CONNECTION: {{ tuple "oslo_messaging" "internal" $userClass "http" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | b64enc }} {{- end }} {{- end }} ================================================ FILE: watcher/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: watcher/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "infra-optim" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: w-api port: {{ tuple "infra-optim" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{ end }} selector: {{ tuple $envAll "watcher" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{ if .Values.network.api.node_port.enabled }} type: NodePort {{ end }} {{- end }} ================================================ FILE: watcher/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "infra-optim" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: watcher/templates/statefulset-decision-engine.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.statefulset_decision_engine }} {{- $envAll := . }} {{- $mounts_watcher_decision_engine := .Values.pod.mounts.watcher_decision_engine.watcher_decision_engine }} {{- $mounts_watcher_decision_engine_init := .Values.pod.mounts.watcher_decision_engine.init_container }} {{- $serviceAccountName := "watcher-decision-engine" }} {{ tuple $envAll "decision_engine" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: StatefulSet metadata: name: watcher-decision-engine annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "watcher" "decision-engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: serviceName: watcher-decision-engine replicas: {{ .Values.pod.replicas.engine }} selector: matchLabels: {{ tuple $envAll "watcher" "decision-engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} template: metadata: labels: {{ tuple $envAll "watcher" "decision-engine" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} spec: serviceAccountName: {{ $serviceAccountName }} affinity: {{ tuple $envAll "watcher" "decision-engine" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.decision_engine.node_selector_key }}: {{ .Values.labels.decision_engine.node_selector_value }} initContainers: {{ tuple $envAll "decision-engine" $mounts_watcher_decision_engine_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: watcher-decision-engine {{ tuple $envAll "watcher_decision_engine" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.decision_engine | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: runAsUser: {{ .Values.pod.user.watcher.uid }} command: - /tmp/watcher-decision-engine.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.watcher.oslo_concurrency.lock_path }} - name: pod-etc-watcher mountPath: /etc/watcher - name: watcher-bin mountPath: /tmp/watcher-decision-engine.sh subPath: watcher-decision-engine.sh readOnly: true - name: watcher-etc mountPath: /etc/watcher/watcher.conf subPath: watcher.conf readOnly: true - name: watcher-etc mountPath: {{ .Values.conf.watcher.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.watcher.DEFAULT.log_config_append }} readOnly: true {{ if $mounts_watcher_decision_engine.volumeMounts }}{{ toYaml $mounts_watcher_decision_engine.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-watcher emptyDir: {} - name: watcher-bin configMap: name: watcher-bin defaultMode: 0555 - name: watcher-etc secret: secretName: watcher-etc defaultMode: 0444 {{ if $mounts_watcher_decision_engine.volumes }}{{ toYaml $mounts_watcher_decision_engine.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: watcher/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Default values for watcher # This is a YAML-formatted file. # Declare name/value pairs to be passed into your templates. # name: value --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled decision_engine: node_selector_key: openstack-control-plane node_selector_value: enabled applier: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble watcher_db_sync: quay.io/airshipit/watcher:2025.1-ubuntu_noble db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble rabbit_init: docker.io/rabbitmq:3.13-management ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_noble watcher_api: quay.io/airshipit/watcher:2025.1-ubuntu_noble watcher_decision_engine: quay.io/airshipit/watcher:2025.1-ubuntu_noble watcher_applier: quay.io/airshipit/watcher:2025.1-ubuntu_noble image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / node_port: enabled: false port: 31233 bootstrap: enabled: false ks_user: watcher script: | openstack token issue dependencies: dynamic: common: local_image_registry: jobs: - watcher-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - watcher-db-sync - watcher-ks-user - watcher-ks-endpoints - watcher-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity db_drop: services: - endpoint: internal service: oslo_db db_init: services: - endpoint: internal service: oslo_db db_sync: jobs: - watcher-db-init services: - endpoint: internal service: oslo_db decision_engine: jobs: - watcher-db-sync - watcher-ks-user - watcher-ks-endpoints - watcher-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity applier: jobs: - watcher-db-sync - watcher-ks-user - watcher-ks-endpoints - watcher-rabbit-init services: - endpoint: internal service: oslo_db - endpoint: internal service: identity ks_endpoints: jobs: - watcher-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity rabbit_init: services: - service: oslo_messaging endpoint: internal tests: services: - endpoint: internal service: identity - endpoint: internal service: infra-optim image_repo_sync: services: - endpoint: internal service: local_image_registry # Names of secrets used by bootstrap and environmental checks secrets: identity: admin: watcher-keystone-admin watcher: watcher-keystone-user test: watcher-keystone-test oslo_db: admin: watcher-db-admin watcher: watcher-db-user oslo_messaging: admin: watcher-rabbitmq-admin watcher: watcher-rabbitmq-user oci_image_registry: watcher: watcher-oci-image-registry # typically overridden by environmental # values, but should include all endpoints # required by this chart endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 oci_image_registry: name: oci-image-registry namespace: oci-image-registry auth: enabled: false watcher: username: watcher password: password hosts: default: localhost host_fqdn_override: default: null port: registry: default: null identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default watcher: role: admin region_name: RegionOne username: watcher password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 infra_optim: name: watcher hosts: default: watcher-api public: watcher host_fqdn_override: default: null path: default: / scheme: default: 'http' port: api: default: 9322 public: 80 oslo_db: auth: admin: username: root password: password watcher: username: watcher password: password hosts: default: mariadb host_fqdn_override: default: null path: /watcher scheme: mysql+pymysql port: mysql: default: 3306 oslo_messaging: auth: admin: username: rabbitmq password: password watcher: username: watcher password: password hosts: default: rabbitmq host_fqdn_override: default: null path: /watcher scheme: rabbit port: amqp: default: 5672 http: default: 15672 oslo_cache: auth: # NOTE(portdirect): this is used to define the value for keystone # authtoken cache encryption key, if not set it will be populated # automatically with a random value, but to take advantage of # this feature all services should be set to use the same key, # and memcache service. memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: 'http' port: service: default: 24224 metrics: default: 24220 conf: rally_tests: run_tempest: false tests: {} templates: [] policy: {} watcher: DEFAULT: log_config_append: /etc/watcher/logging.conf transport_url: null api: host: '0.0.0.0' database: max_retries: -1 # -- Database connection URI. When empty the URI is auto-generated ## from endpoints.oslo_db. Set to null to disable auto-generation, ## e.g. when using an operator such as mariadb-operator that supplies ## the connection string via a mounted configuration snippet. connection: "" keystone_authtoken: auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT watcher_clients_auth: cafile: null certfile: null keyfile: null insecure: false oslo_concurrency: lock_path: /var/lock logging: loggers: keys: - root - watcher handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: 'null' logger_watcher: level: INFO handlers: - stdout qualname: watcher logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" pod: user: watcher: uid: 1000 affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname mounts: watcher_api: init_container: null watcher_api: volumeMounts: volumes: watcher_decision_engine: init_container: null watcher_decision_engine: volumeMounts: volumes: watcher_applier: init_container: null watcher_applier: volumeMounts: volumes: watcher_tests: init_container: null watcher_tests: volumeMounts: volumes: replicas: api: 1 decision_engine: 1 applier: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" decision_engine: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" applier: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" rabbit_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" network_policy: watcher: ingress: - from: - podSelector: matchLabels: application: watcher - podSelector: matchLabels: application: horizon - podSelector: matchLabels: application: ingress - podSelector: matchLabels: application: heat ports: - protocol: TCP port: 80 - protocol: TCP port: 9322 manifests: configmap_bin: true configmap_etc: true deployment_api: true deployment_applier: true ingress_api: true job_bootstrap: true job_db_init: true job_db_sync: true job_db_drop: false job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true job_rabbit_init: true pdb_api: true pod_rally_test: true network_policy: false secret_db: true secret_keystone: true secret_rabbitmq: true secret_registry: true service_ingress_api: true service_api: true statefulset_decision_engine: true # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: yamllint-templates.conf ================================================ --- yaml-files: - '*.yaml' - '*.yml' - '.yamllint' rules: braces: enable brackets: enable colons: enable commas: enable comments: enable comments-indentation: enable document-end: disable document-start: enable empty-lines: disable empty-values: disable hyphens: enable indentation: spaces: 2 indent-sequences: whatever key-duplicates: enable key-ordering: disable line-length: disable new-line-at-end-of-file: disable new-lines: disable octal-values: disable quoted-strings: disable trailing-spaces: disable truthy: disable ... ================================================ FILE: yamllint.conf ================================================ --- yaml-files: - '*.yaml' - '*.yml' - '.yamllint' rules: braces: enable brackets: enable colons: enable commas: enable comments: enable comments-indentation: disable document-end: enable document-start: enable empty-lines: enable empty-values: disable hyphens: ignore: .yamllint/zuul.d/jobs.yaml indentation: spaces: 2 indent-sequences: whatever key-duplicates: enable key-ordering: disable line-length: disable new-line-at-end-of-file: enable new-lines: enable octal-values: disable quoted-strings: disable trailing-spaces: enable truthy: disable ... ================================================ FILE: zaqar/Chart.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- apiVersion: v2 appVersion: v1.0.0 description: OpenStack Messaging Service (Zaqar) name: zaqar type: application version: 2025.2.0 home: https://docs.openstack.org/zaqar/ icon: https://www.openstack.org/themes/openstack/images/project-mascots/Zaqar/OpenStack_Project_Zaqar_vertical.png sources: - https://opendev.org/openstack/zaqar keywords: - openstack - messaging - queue - helm maintainers: - name: OpenStack-Helm Team email: openstack-helm@lists.openstack.org dependencies: - name: helm-toolkit repository: file://../helm-toolkit version: ">= 0.1.0" ... ================================================ FILE: zaqar/templates/bin/_bootstrap.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex {{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} ================================================ FILE: zaqar/templates/bin/_db-sync.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex zaqar-sql-db-manage \ --config-file /etc/zaqar/zaqar.conf \ upgrade head ================================================ FILE: zaqar/templates/bin/_zaqar-test.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */}} set -ex export HOME=/tmp echo "Test: list queues" openstack queue list QUEUE_NAME="test-queue-$(uuidgen | cut -d'-' -f1)" echo "Test: create queue" openstack queue create ${QUEUE_NAME} echo "Test: post messages" openstack message post ${QUEUE_NAME} --message '{"body":"Hello World 1"}' openstack message post ${QUEUE_NAME} --message '{"body":"Hello World 2"}' echo "Test: list messages" openstack message list ${QUEUE_NAME} echo "Test: get a single message" MESSAGE_ID=$(openstack message list ${QUEUE_NAME} -f value -c id | head -1) openstack message get ${QUEUE_NAME} ${MESSAGE_ID} echo "Test: claim messages" CLAIM_ID=$(openstack claim create ${QUEUE_NAME} --ttl 30 --grace 30 -f value -c id) openstack claim get ${QUEUE_NAME} ${CLAIM_ID} echo "Test: delete messages" openstack message delete ${QUEUE_NAME} ${MESSAGE_ID} echo "Test: delete queue" openstack queue delete ${QUEUE_NAME} exit 0 ================================================ FILE: zaqar/templates/bin/_zaqar_api.sh.tpl ================================================ #!/bin/bash {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} set -ex COMMAND="${@:-start}" function start () { exec zaqar-server \ --config-file /etc/zaqar/zaqar.conf } function stop () { kill -TERM 1 } $COMMAND ================================================ FILE: zaqar/templates/configmap-bin.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_bin }} {{- $envAll := . }} {{- $rallyTests := .Values.conf.rally_tests }} --- apiVersion: v1 kind: ConfigMap metadata: name: zaqar-bin data: {{- if .Values.images.local_registry.active }} image-repo-sync.sh: | {{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} {{- end }} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | {{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} db-drop.py: | {{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} zaqar-api.sh: | {{ tuple "bin/_zaqar_api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} ks-service.sh: | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} ks-endpoints.sh: | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} rally-test.sh: | {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} {{- end }} ================================================ FILE: zaqar/templates/configmap-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.configmap_etc }} {{- $envAll := . }} {{- if empty .Values.conf.zaqar.keystone_authtoken.identity_uri -}} {{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.zaqar.keystone_authtoken "identity_uri" -}} {{- end -}} {{- if empty .Values.conf.zaqar.keystone_authtoken.memcached_servers -}} {{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set .Values.conf.zaqar.keystone_authtoken "memcached_servers" -}} {{- end -}} {{- if empty .Values.conf.zaqar.keystone_authtoken.memcache_secret_key -}} {{- $_ := set .Values.conf.zaqar.keystone_authtoken "memcache_secret_key" ( default ( randAlphaNum 64 ) .Values.endpoints.oslo_cache.auth.memcache_secret_key ) -}} {{- end -}} {{- if empty (index .Values.conf.zaqar "drivers:management_store:sqlalchemy").uri -}} {{- $_ := tuple "oslo_db" "internal" "zaqar" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup"| set (index .Values.conf.zaqar "drivers:management_store:sqlalchemy") "uri" -}} {{- end -}} {{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} {{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} {{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} {{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} {{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} {{- end -}} {{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} {{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} {{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} {{- end -}} --- apiVersion: v1 kind: Secret metadata: name: zaqar-etc type: Opaque data: rally_tests.yaml: {{ toYaml .Values.conf.rally_tests.tests | b64enc }} zaqar.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.zaqar | b64enc }} logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.api_paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} {{- end }} ================================================ FILE: zaqar/templates/deployment-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "zaqarApiLivenessProbeTemplate" }} tcpSocket: port: {{ tuple "messaging" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- define "zaqarApiReadinessProbeTemplate" }} tcpSocket: port: {{ tuple "messaging" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} {{- if .Values.manifests.deployment_api }} {{- $envAll := . }} {{- $mounts_zaqar_api := .Values.pod.mounts.zaqar_api.zaqar_api }} {{- $mounts_zaqar_api_init := .Values.pod.mounts.zaqar_api.init_container }} {{- $serviceAccountName := "zaqar-api" }} {{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: apps/v1 kind: Deployment metadata: name: zaqar-api annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} labels: {{ tuple $envAll "zaqar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: replicas: {{ .Values.pod.replicas.api }} selector: matchLabels: {{ tuple $envAll "zaqar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} template: metadata: labels: {{ tuple $envAll "zaqar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} annotations: {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} {{ tuple "zaqar_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} {{ dict "envAll" $envAll "podName" "zaqar-api" "containerNames" (list "zaqar-api" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} spec: {{ tuple "zaqar_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} {{ tuple "zaqar_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "zaqar" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} affinity: {{ tuple $envAll "zaqar" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} nodeSelector: {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} {{ if $envAll.Values.pod.tolerations.zaqar.enabled }} {{ tuple $envAll "zaqar" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} {{ end }} terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} initContainers: {{ tuple $envAll "api" $mounts_zaqar_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: - name: zaqar-api {{ tuple $envAll "zaqar_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} {{ dict "envAll" $envAll "application" "zaqar" "container" "zaqar_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} {{- if or .Values.manifests.certificates .Values.tls.identity }} env: - name: REQUESTS_CA_BUNDLE value: "/etc/zaqar/certs/ca.crt" {{- end }} command: - /tmp/zaqar-api.sh - start lifecycle: preStop: exec: command: - /tmp/zaqar-api.sh - stop ports: - name: z-api containerPort: {{ tuple "messaging" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{ dict "envAll" $envAll "component" "api" "container" "default" "type" "liveness" "probeTemplate" (include "zaqarApiLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "api" "container" "default" "type" "readiness" "probeTemplate" (include "zaqarApiReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} volumeMounts: - name: pod-tmp mountPath: /tmp - name: oslo-lock-path mountPath: {{ .Values.conf.zaqar.oslo_concurrency.lock_path }} - name: pod-etc-zaqar mountPath: /etc/zaqar - name: zaqar-bin mountPath: /tmp/zaqar-api.sh subPath: zaqar-api.sh readOnly: true - name: zaqar-etc mountPath: /etc/zaqar/zaqar.conf subPath: zaqar.conf readOnly: true - name: zaqar-etc-snippets mountPath: /etc/zaqar/zaqar.conf.d/ readOnly: true {{- if .Values.conf.zaqar.DEFAULT.log_config_append }} - name: zaqar-etc mountPath: {{ .Values.conf.zaqar.DEFAULT.log_config_append }} subPath: {{ base .Values.conf.zaqar.DEFAULT.log_config_append }} readOnly: true {{- end }} - name: zaqar-etc mountPath: /etc/zaqar/api-paste.ini subPath: api-paste.ini readOnly: true - name: zaqar-etc mountPath: /etc/zaqar/policy.yaml subPath: policy.yaml readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.messaging.api.internal "path" "/etc/zaqar/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_zaqar_api.volumeMounts }}{{ toYaml $mounts_zaqar_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: oslo-lock-path emptyDir: {} - name: pod-etc-zaqar emptyDir: {} - name: zaqar-bin configMap: name: zaqar-bin defaultMode: 0555 - name: zaqar-etc secret: secretName: zaqar-etc defaultMode: 0444 - name: zaqar-etc-snippets projected: sources: - secret: name: zaqar-ks-etc {{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.messaging.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_zaqar_api.volumes }}{{ toYaml $mounts_zaqar_api.volumes | indent 8 }}{{ end }} {{- end }} ================================================ FILE: zaqar/templates/extra-manifests.yaml ================================================ {{ range .Values.extraObjects }} --- {{ if typeIs "string" . }} {{- tpl . $ }} {{- else }} {{- tpl (toYaml .) $ }} {{- end }} {{ end }} ================================================ FILE: zaqar/templates/ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} {{- $envAll := . }} {{- $ingressOpts := dict "envAll" $envAll "backendService" "api" "backendServiceType" "messaging" "backendPort" "z-api" -}} {{- $secretName := index $envAll.Values.secrets.tls.messaging.api ($envAll.Values.network.api.ingress.classes.namespace | replace "-" "_") -}} {{- if $envAll.Values.tls.identity -}} {{- $_ := set $ingressOpts "certIssuer" $envAll.Values.endpoints.identity.auth.zaqar.tls.ca -}} {{- end -}} {{- if hasKey $envAll.Values.secrets.tls.messaging.api $envAll.Values.network.api.ingress.classes.namespace -}} {{- $_ := set $ingressOpts "tlsSecret" $secretName -}} {{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} ================================================ FILE: zaqar/templates/job-bootstrap.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "zaqar" "keystoneUser" .Values.bootstrap.ks_user -}} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} {{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} ================================================ FILE: zaqar/templates/job-db-drop.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.job_db_drop }} {{- $dbDropJob := dict "envAll" . "serviceName" "zaqar" -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $dbDropJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} {{- end }} ================================================ FILE: zaqar/templates/job-db-init.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_init" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-5" {{- end }} {{- if .Values.manifests.job_db_init }} {{- $dbToInit := dict "adminSecret" .Values.secrets.oslo_db.admin "configFile" "/etc/zaqar/zaqar.conf" "logConfigFile" "/etc/zaqar/logging.conf" "configDbSection" "drivers:management_store:sqlalchemy" "configDbKey" "uri" -}} {{- $dbInitJob := dict "envAll" . "serviceName" "zaqar" "dbToInit" $dbToInit -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $dbInitJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} {{- end }} ================================================ FILE: zaqar/templates/job-db-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.db_sync" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-4" {{- end }} {{- if .Values.manifests.job_db_sync }} {{- $dbSyncJob := dict "envAll" . "serviceName" "zaqar" "podVolMounts" .Values.pod.mounts.zaqar_db_sync.zaqar_db_sync.valumeMounts "podVols" .Values.pod.mounts.zaqar_db_sync.zaqar_db_sync.volumes "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) -}} {{- if .Values.manifests.certificates -}} {{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} {{- end -}} {{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} {{- end }} ================================================ FILE: zaqar/templates/job-image-repo-sync.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.repo_sync" }} helm.sh/hook: post-install,post-upgrade {{- end }} {{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} {{- $imageRepoSyncJob := dict "envAll" . "serviceName" "zaqar" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} {{- end -}} {{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} {{- end }} ================================================ FILE: zaqar/templates/job-ks-endpoints.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_endpoints" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-2" {{- end }} {{- if .Values.manifests.job_ks_endpoints }} {{- $ksEndpointsJob := dict "envAll" . "serviceName" "zaqar" "serviceTypes" ( tuple "messaging" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksEndpointsJob "tlsSecret" .Values.secrets.tls.messaging.api.internal -}} {{- end -}} {{- $_ := set $ksEndpointsJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $ksEndpointsJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksEndpointsJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} ================================================ FILE: zaqar/templates/job-ks-service.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_service" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-3" {{- end }} {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "zaqar" "serviceTypes" ( tuple "messaging" ) -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.messaging.api.internal -}} {{- end -}} {{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} {{- end }} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} ================================================ FILE: zaqar/templates/job-ks-user.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- define "metadata.annotations.job.ks_user" }} helm.sh/hook: post-install,post-upgrade helm.sh/hook-weight: "-1" {{- end }} {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "zaqar" -}} {{- if or .Values.manifests.certificates .Values.tls.identity -}} {{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.messaging.api.internal -}} {{- end -}} {{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} {{- if .Values.pod.tolerations.zaqar.enabled -}} {{- $_ := set $ksUserJob "tolerationsEnabled" true -}} {{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} ================================================ FILE: zaqar/templates/network_policy.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. {{- if .Values.manifests.network_policy -}} {{- $netpol_opts := dict "envAll" . "name" "application" "label" "zaqar" -}} {{ $netpol_opts | include "helm-toolkit.manifests.kubernetes_network_policy" }} {{- end -}} ================================================ FILE: zaqar/templates/pdb-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pdb_api }} {{- $envAll := . }} --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: zaqar-api labels: {{ tuple $envAll "zaqar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} spec: {{- if .Values.pod.lifecycle.disruption_budget.api.min_available }} minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} {{- else }} maxUnavailable: {{ .Values.pod.lifecycle.disruption_budget.api.max_unavailable | default 1 }} {{- end }} selector: matchLabels: {{ tuple $envAll "zaqar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} {{- end }} ================================================ FILE: zaqar/templates/pod-rally-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $dependencies := .Values.dependencies.static.tests }} {{- $mounts_zaqar_tests := .Values.pod.mounts.zaqar_tests.zaqar_tests }} {{- $mounts_zaqar_tests_init := .Values.pod.mounts.zaqar_tests.init_container }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{ .Release.Name }}-test" labels: {{ tuple $envAll "zaqar" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "zaqar-test" "containerNames" (list "init" "zaqar-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ tuple "zaqar_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "zaqar_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.zaqar.enabled }} {{ tuple $envAll "zaqar" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" $mounts_zaqar_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} - name: zaqar-test-ks-user {{ tuple $envAll "ks_user" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.ks_user | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} command: - /tmp/ks-user.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: zaqar-bin mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true {{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME value: "test" {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_ROLE value: {{ .Values.endpoints.identity.auth.test.role | quote }} containers: - name: zaqar-test {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "zaqar_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} command: - /tmp/rally-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: zaqar-etc mountPath: /etc/rally/rally_tests.yaml subPath: rally_tests.yaml readOnly: true - name: zaqar-bin mountPath: /tmp/rally-test.sh subPath: rally-test.sh readOnly: true {{ if $mounts_zaqar_tests.volumeMounts }}{{ toYaml $mounts_zaqar_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: zaqar-etc secret: secretName: zaqar-etc defaultMode: 0444 - name: zaqar-bin configMap: name: zaqar-bin defaultMode: 0555 {{ if $mounts_zaqar_tests.volumes }}{{ toYaml $mounts_zaqar_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: zaqar/templates/pod-test.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.pod_test }} {{- $envAll := . }} {{- $dependencies := .Values.dependencies.static.tests }} {{- $mounts_zaqar_tests := .Values.pod.mounts.zaqar_tests.zaqar_tests }} {{- $mounts_zaqar_tests_init := .Values.pod.mounts.zaqar_tests.init_container }} {{- $serviceAccountName := print .Release.Name "-test" }} {{ tuple $envAll "tests" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} --- apiVersion: v1 kind: Pod metadata: name: "{{ .Release.Name }}-test" labels: {{ tuple $envAll "zaqar" "test" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} annotations: "helm.sh/hook": test-success {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} {{ dict "envAll" $envAll "podName" "zaqar-test" "containerNames" (list "init" "zaqar-test") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 4 }} spec: {{ tuple "zaqar_tests" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 2 }} {{ tuple "zaqar_tests" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 2 }} serviceAccountName: {{ $serviceAccountName }} {{ dict "envAll" $envAll "application" "test" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 2 }} nodeSelector: {{ .Values.labels.test.node_selector_key }}: {{ .Values.labels.test.node_selector_value }} {{ if $envAll.Values.pod.tolerations.zaqar.enabled }} {{ tuple $envAll "zaqar" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 2 }} {{ end }} restartPolicy: Never initContainers: {{ tuple $envAll "tests" $mounts_zaqar_tests_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 4 }} containers: - name: zaqar-test {{ tuple $envAll "scripted_test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ dict "envAll" $envAll "application" "test" "container" "zaqar_test" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 6 }} env: {{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} command: - /tmp/zaqar-test.sh volumeMounts: - name: pod-tmp mountPath: /tmp - name: zaqar-bin mountPath: /tmp/zaqar-test.sh subPath: zaqar-test.sh readOnly: true {{ if $mounts_zaqar_tests.volumeMounts }}{{ toYaml $mounts_zaqar_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: zaqar-bin configMap: name: zaqar-bin defaultMode: 0555 {{ if $mounts_zaqar_tests.volumes }}{{ toYaml $mounts_zaqar_tests.volumes | indent 4 }}{{ end }} {{- end }} ================================================ FILE: zaqar/templates/secret-db.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_db }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "zaqar" }} {{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} {{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- if $envAll.Values.manifests.certificates }} DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} {{- else }} DB_CONNECTION: {{ $connection | b64enc -}} {{- end }} {{- end }} {{- end }} ================================================ FILE: zaqar/templates/secret-ingress-tls.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ingress_tls }} {{- include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendServiceType" "messaging" ) }} {{- end }} ================================================ FILE: zaqar/templates/secret-keystone.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_keystone }} {{- $envAll := . }} {{- range $key1, $userClass := tuple "admin" "zaqar" "test" }} {{- $secretName := index $envAll.Values.secrets.identity $userClass }} --- apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} annotations: {{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} type: Opaque data: {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} {{- end }} {{- end }} ================================================ FILE: zaqar/templates/secret-ks-etc.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.secret_ks_etc }} {{- $envAll := . -}} {{/* The endpoints.identity.auth sections with the oslo config sections they get rendered to */}} {{- $ksUsers := dict "zaqar" "keystone_authtoken" -}} {{ dict "envAll" $envAll "serviceName" "zaqar" "serviceUserSections" $ksUsers | include "helm-toolkit.manifests.secret_ks_etc" }} {{- end }} ================================================ FILE: zaqar/templates/secret-registry.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.secret_registry .Values.endpoints.oci_image_registry.auth.enabled }} {{ include "helm-toolkit.manifests.secret_registry" ( dict "envAll" . "registryUser" .Chart.Name ) }} {{- end }} ================================================ FILE: zaqar/templates/service-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if .Values.manifests.service_api }} {{- $envAll := . }} --- apiVersion: v1 kind: Service metadata: name: {{ tuple "messaging" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} spec: ports: - name: z-api port: {{ tuple "messaging" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- if .Values.network.api.node_port.enabled }} nodePort: {{ .Values.network.api.node_port.port }} {{- end }} selector: {{ tuple $envAll "zaqar" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} {{- if .Values.network.api.node_port.enabled }} type: NodePort {{- if .Values.network.api.external_policy_local }} externalTrafficPolicy: Local {{- end }} {{- end }} {{- end }} ================================================ FILE: zaqar/templates/service-ingress-api.yaml ================================================ {{/* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}} {{- if and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} {{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "messaging" -}} {{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} {{- end }} ================================================ FILE: zaqar/values.yaml ================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- labels: api: node_selector_key: openstack-control-plane node_selector_value: enabled job: node_selector_key: openstack-control-plane node_selector_value: enabled test: node_selector_key: openstack-control-plane node_selector_value: enabled release_group: null images: tags: test: docker.io/xrally/xrally-openstack:2.0.0 bootstrap: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_init: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy db_drop: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_user: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_service: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy ks_endpoints: quay.io/airshipit/openstack-client:2025.1-ubuntu_jammy zaqar_db_sync: quay.io/airshipit/zaqar:2025.1-ubuntu_jammy zaqar_api: quay.io/airshipit/zaqar:2025.1-ubuntu_jammy dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy image_repo_sync: docker.io/docker:17.07.0 pull_policy: "IfNotPresent" local_registry: active: false exclude: - dep_check - image_repo_sync network: api: ingress: public: true classes: namespace: "ingress-openstack" cluster: "ingress-cluster" annotations: nginx.ingress.kubernetes.io/rewrite-target: / haproxy.org/path-rewrite: / external_policy_local: false node_port: enabled: false port: 30780 dependencies: dynamic: common: local_image_registry: jobs: - zaqar-image-repo-sync services: - endpoint: node service: local_image_registry static: api: jobs: - zaqar-db-sync - zaqar-ks-user - zaqar-ks-endpoints services: - endpoint: internal service: oslo_cache - endpoint: internal service: oslo_db - endpoint: internal service: identity bootstrap: services: - endpoint: internal service: identity - endpoint: internal service: messaging db_init: services: - endpoint: internal service: oslo_db db_drop: services: - endpoint: internal service: oslo_db db_sync: jobs: - zaqar-db-init services: - endpoint: internal service: oslo_db ks_endpoints: jobs: - zaqar-ks-service services: - endpoint: internal service: identity ks_service: services: - endpoint: internal service: identity ks_user: services: - endpoint: internal service: identity secrets: identity: admin: zaqar-keystone-admin zaqar: zaqar-keystone-user service: zaqar-keystone-service test: zaqar-keystone-test oslo_db: admin: zaqar-db-admin zaqar: zaqar-db-user tls: messaging: api: admin: zaqar-tls-admin public: zaqar-tls-public internal: zaqar-tls-internal nginx: zaqar-tls-nginx nginx_cluster: zaqar-tls-nginx-cluster endpoints: cluster_domain_suffix: cluster.local local_image_registry: name: docker-registry namespace: docker-registry hosts: default: localhost internal: docker-registry node: localhost host_fqdn_override: default: null port: registry: node: 5000 identity: name: keystone auth: admin: region_name: RegionOne username: admin password: password project_name: admin user_domain_name: default project_domain_name: default zaqar: role: admin,service region_name: RegionOne username: zaqar password: password project_name: service user_domain_name: service project_domain_name: service test: role: admin region_name: RegionOne username: zaqar-test password: password project_name: test user_domain_name: service project_domain_name: service hosts: default: keystone internal: keystone-api host_fqdn_override: default: null path: default: /v3 scheme: default: http port: api: default: 80 internal: 5000 messaging: name: zaqar hosts: default: zaqar-api public: zaqar host_fqdn_override: default: null path: default: / scheme: default: "http" service: "http" port: api: default: 8888 public: 80 service: 8888 oslo_db: auth: admin: username: root password: password secret: tls: internal: mariadb-tls-direct zaqar: username: zaqar password: password hosts: default: mariadb host_fqdn_override: default: null path: /zaqar scheme: mysql+pymysql port: mysql: default: 3306 oslo_cache: auth: memcache_secret_key: null hosts: default: memcached host_fqdn_override: default: null port: memcache: default: 11211 fluentd: namespace: null name: fluentd hosts: default: fluentd-logging host_fqdn_override: default: null path: default: null scheme: "http" port: service: default: 24224 metrics: default: 24220 kube_dns: namespace: kube-system name: kubernetes-dns hosts: default: kube-dns host_fqdn_override: default: null path: default: null scheme: http port: dns: default: 53 protocol: UDP ingress: namespace: null name: ingress hosts: default: ingress port: ingress: default: 80 pod: probes: rpc_timeout: 60 rpc_retries: 2 api: default: liveness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 readiness: enabled: true params: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 security_context: zaqar: pod: runAsUser: 42424 container: zaqar_api: runAsUser: 0 test: pod: runAsUser: 42424 container: zaqar_test_ks_user: readOnlyRootFilesystem: true allowPrivilegeEscalation: false zaqar_test: runAsUser: 65500 readOnlyRootFilesystem: true allowPrivilegeEscalation: false affinity: anti: type: default: preferredDuringSchedulingIgnoredDuringExecution topologyKey: default: kubernetes.io/hostname weight: default: 10 tolerations: zaqar: enabled: false tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule mounts: zaqar_api: init_container: null zaqar_api: volumeMounts: volumes: zaqar_bootstrap: init_container: null zaqar_bootstrap: volumeMounts: volumes: zaqar_db_sync: zaqar_db_sync: volumeMounts: volumes: zaqar_tests: init_container: null zaqar_tests: volumeMounts: volumes: replicas: api: 1 lifecycle: upgrades: deployments: revision_history: 3 pod_replacement_strategy: RollingUpdate rolling_update: max_unavailable: 1 max_surge: 3 disruption_budget: api: min_available: 0 termination_grace_period: api: timeout: 30 resources: enabled: false api: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_init: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" db_drop: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_endpoints: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_service: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" ks_user: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" tests: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" image_repo_sync: requests: memory: "128Mi" cpu: "100m" limits: memory: "1024Mi" cpu: "2000m" jobs: bootstrap: backoffLimit: 5 activeDeadlineSeconds: 600 db_init: backoffLimit: 5 activeDeadlineSeconds: 600 db_drop: backoffLimit: 5 activeDeadlineSeconds: 600 db_sync: backoffLimit: 5 activeDeadlineSeconds: 600 ks_endpoints: backoffLimit: 5 activeDeadlineSeconds: 600 ks_service: backoffLimit: 5 activeDeadlineSeconds: 600 ks_user: backoffLimit: 5 activeDeadlineSeconds: 600 tests: backoffLimit: 5 activeDeadlineSeconds: 600 image_repo_sync: backoffLimit: 5 activeDeadlineSeconds: 600 conf: zaqar: DEFAULT: log_config_append: /etc/zaqar/logging.conf drivers: transport: wsgi message_store: redis management_store: sqlalchemy keystone_authtoken: service_token_roles: service service_token_roles_required: true auth_type: password auth_version: v3 memcache_security_strategy: ENCRYPT service_type: messaging cache: backend: dogpile.cache.memory drivers:management_store:sqlalchemy: uri: drivers:message_store:redis: uri: redis://redis:6379 drivers:transport:wsgi: bind: 0.0.0.0 port: 8888 signed_url: secret_key: SOMELONGSECRETKEY oslo_concurrency: lock_path: /var/lock logging: loggers: keys: - root - zaqar handlers: keys: - stdout - stderr - "null" formatters: keys: - context - default logger_root: level: WARNING handlers: "null" logger_zaqar: level: INFO handlers: - stdout qualname: zaqar logger_amqp: level: WARNING handlers: stderr qualname: amqp logger_amqplib: level: WARNING handlers: stderr qualname: amqplib logger_eventletwsgi: level: WARNING handlers: stderr qualname: eventlet.wsgi.server logger_sqlalchemy: level: WARNING handlers: stderr qualname: sqlalchemy logger_boto: level: WARNING handlers: stderr qualname: boto handler_null: class: logging.NullHandler formatter: default args: () handler_stdout: class: StreamHandler args: (sys.stdout,) formatter: context handler_stderr: class: StreamHandler args: (sys.stderr,) formatter: context formatter_context: class: oslo_log.formatters.ContextFormatter datefmt: "%Y-%m-%d %H:%M:%S" formatter_default: format: "%(message)s" datefmt: "%Y-%m-%d %H:%M:%S" api_paste: composite:messaging: use: "egg:Paste#urlmap" "/": zaqarversions "/v1": zaqarapi_v1 composite:zaqarapi_v1: use: "call:zaqar.transport.wsgi:pipeline_factory" noauth: "request_id faultwrap sizelimit noauth zaqarapi_v1" keystone: "request_id faultwrap sizelimit authtoken keystonecontext zaqarapi_v1" app:zaqarversions: paste.app_factory: "zaqar.api.versions:Versions.factory" app:zaqarapi_v1: paste.app_factory: "zaqar.api.v1.app:make_app" filter:request_id: paste.filter_factory: "oslo_middleware:RequestId.factory" filter:faultwrap: paste.filter_factory: "zaqar.api.middleware:FaultWrapper.factory" filter:noauth: paste.filter_factory: "zaqar.api.middleware:NoAuthMiddleware.factory" filter:sizelimit: paste.filter_factory: "oslo_middleware:RequestBodySizeLimiter.factory" filter:authtoken: paste.filter_factory: "keystonemiddleware.auth_token:filter_factory" filter:keystonecontext: paste.filter_factory: "zaqar.api.middleware:KeystoneContextMiddleware.factory" policy: {} rally_tests: run_tempest: false clean_up: "" tests: Zaqar.queues: - args: queue_name: "test-queue" messages: - "message1" - "message2" - "message3" ttl: 3600 runner: type: "constant" times: 10 concurrency: 3 sla: failure_rate: max: 0 Zaqar.publish: - args: queue_name: "publish-queue" messages: - "hello" - "world" runner: type: "constant" times: 15 concurrency: 4 sla: failure_rate: max: 0 Zaqar.consume: - args: queue_name: "publish-queue" max_messages: 5 runner: type: "constant" times: 10 concurrency: 2 sla: failure_rate: max: 0 bootstrap: enabled: false ks_user: zaqar script: | openstack token issue # create a test queue in Zaqar openstack queue create test-queue || echo "Queue already exists" manifests: certificates: false configmap_bin: true configmap_etc: true deployment_api: true ingress_api: true job_bootstrap: true job_db_init: true job_db_drop: false job_db_sync: true job_image_repo_sync: true job_ks_endpoints: true job_ks_service: true job_ks_user: true pdb_api: true pod_rally_test: true secret_db: true secret_keystone: true secret_ks_etc: true service_api: true service_ingress_api: true network_policy: zaqar: ingress: - {} egress: - {} tls: identity: false oslo_db: false messaging: api: public: false # -- Array of extra K8s manifests to deploy ## Note: Supports use of custom Helm templates extraObjects: [] # - apiVersion: secrets-store.csi.x-k8s.io/v1 # kind: SecretProviderClass # metadata: # name: osh-secrets-store # spec: # provider: aws # parameters: # objects: | # - objectName: "osh" # objectType: "secretsmanager" # jmesPath: # - path: "client_id" # objectAlias: "client_id" # - path: "client_secret" # objectAlias: "client_secret" # secretObjects: # - data: # - key: client_id # objectName: client_id # - key: client_secret # objectName: client_secret # secretName: osh-secrets-store # type: Opaque # labels: # app.kubernetes.io/part-of: osh ... ================================================ FILE: zuul.d/2024.2.yaml ================================================ --- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - job: name: openstack-helm-cinder-2024-2-ubuntu_jammy parent: openstack-helm-cinder-rook vars: osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-trove-2024-2-ubuntu_jammy parent: openstack-helm-trove nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-2024-2-ubuntu_jammy parent: openstack-helm-compute-kit nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-cilium-2024-2-ubuntu_jammy parent: openstack-helm-compute-kit nodeset: openstack-helm-1node-3nodes-ubuntu_jammy vars: calico_setup: false cilium_setup: true osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-flannel-2024-2-ubuntu_jammy parent: openstack-helm-compute-kit nodeset: openstack-helm-1node-3nodes-ubuntu_jammy vars: calico_setup: false flannel_setup: true osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-helm-repo-public-2024-2-ubuntu_jammy parent: openstack-helm-compute-kit-helm-repo-public nodeset: openstack-helm-1node-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-ovn-2024-2-ubuntu_jammy parent: openstack-helm-compute-kit-ovn nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: ovn,gateway - job: name: openstack-helm-tacker-2024-2-ubuntu_jammy parent: openstack-helm-tacker nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2024.2" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway ... ================================================ FILE: zuul.d/2025.1.yaml ================================================ --- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - job: name: openstack-helm-cinder-2025-1-ubuntu_jammy parent: openstack-helm-cinder-rook nodeset: openstack-helm-5nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-trove-2025-1-ubuntu_jammy parent: openstack-helm-trove nodeset: openstack-helm-5nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-2025-1-ubuntu_jammy parent: openstack-helm-compute-kit nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-ovn-2025-1-ubuntu_jammy parent: openstack-helm-compute-kit-ovn nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: ovn,gateway - job: name: openstack-helm-skyline-2025-1-ubuntu_jammy parent: openstack-helm-skyline nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-cinder-2025-1-ubuntu_noble parent: openstack-helm-cinder-rook nodeset: openstack-helm-5nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-cinder-2025-1-ubuntu_noble_loci parent: openstack-helm-cinder-rook nodeset: openstack-helm-5nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: noble feature_gates: loci,gateway - job: name: openstack-helm-trove-2025-1-ubuntu_noble parent: openstack-helm-trove nodeset: openstack-helm-5nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-compute-kit-2025-1-ubuntu_noble parent: openstack-helm-compute-kit nodeset: openstack-helm-3nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-compute-kit-2025-1-ubuntu_noble_loci parent: openstack-helm-compute-kit nodeset: openstack-helm-3nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: noble feature_gates: loci,gateway - job: name: openstack-helm-octavia-2025-1-ubuntu_jammy parent: openstack-helm-octavia nodeset: openstack-helm-4nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-watcher-2025-1-ubuntu_jammy parent: openstack-helm-watcher nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-blazar-2025-1-ubuntu_jammy parent: openstack-helm-blazar nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-cloudkitty-2025-1-ubuntu_jammy parent: openstack-helm-cloudkitty nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-freezer-2025-1-ubuntu_jammy parent: openstack-helm-freezer nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-zaqar-2025-1-ubuntu_jammy parent: openstack-helm-zaqar nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-dpdk-2025-1-ubuntu_jammy description: | Run the openstack-helm compute-kit job with DPDK enabled. We use single node environment to run this job which means that the job only tests that QEMU and OVS-DPDK are working together. The job does not assume having specific DPDK hardware. parent: openstack-helm-compute-kit pre-run: - playbooks/enable-hugepages.yaml - playbooks/prepare-hosts.yaml nodeset: openstack-helm-1node-32GB-ubuntu_jammy vars: hugepages: enabled: true size: "2M" number: 2048 osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: dpdk,gateway files: - ^roles/.* - ^openvswitch/.* - ^nova/.* - ^neutron/.* - job: name: openstack-helm-horizon-2025-1-ubuntu_jammy parent: openstack-helm-horizon nodeset: openstack-helm-1node-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: logo,gateway - job: name: openstack-helm-compute-kit-cilium-2025-1-ubuntu_jammy parent: openstack-helm-compute-kit nodeset: openstack-helm-1node-3nodes-ubuntu_jammy vars: calico_setup: false cilium_setup: true osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-compute-kit-helm-repo-public-2025-1-ubuntu_jammy parent: openstack-helm-compute-kit-helm-repo-public nodeset: openstack-helm-1node-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway - job: name: openstack-helm-tacker-2025-1-ubuntu_jammy parent: openstack-helm-tacker nodeset: openstack-helm-3nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway ... ================================================ FILE: zuul.d/2025.2-ubuntu_noble.yaml ================================================ --- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - job: name: openstack-helm-cinder-2025-2-ubuntu_noble parent: openstack-helm-cinder-rook nodeset: openstack-helm-5nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-cinder-2025-2-ubuntu_noble_loci parent: openstack-helm-cinder-rook nodeset: openstack-helm-5nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: loci,gateway - job: name: openstack-helm-trove-2025-2-ubuntu_noble parent: openstack-helm-trove nodeset: openstack-helm-5nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-compute-kit-2025-2-ubuntu_noble parent: openstack-helm-compute-kit nodeset: openstack-helm-3nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-compute-kit-2025-2-ubuntu_noble_loci parent: openstack-helm-compute-kit nodeset: openstack-helm-3nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: loci,gateway - job: name: openstack-helm-compute-kit-ovn-2025-2-ubuntu_noble parent: openstack-helm-compute-kit-ovn nodeset: openstack-helm-3nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: ovn,gateway - job: name: openstack-helm-octavia-2025-2-ubuntu_noble parent: openstack-helm-octavia nodeset: openstack-helm-4nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-skyline-2025-2-ubuntu_noble parent: openstack-helm-skyline nodeset: openstack-helm-3nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway - job: name: openstack-helm-swift-2025-2-ubuntu_noble parent: openstack-helm-swift nodeset: openstack-helm-3nodes-ubuntu_noble vars: osh_params: openstack_release: "2025.2" container_distro_name: ubuntu container_distro_version: noble feature_gates: gateway ... ================================================ FILE: zuul.d/base.yaml ================================================ --- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - job: name: openstack-helm-linter run: playbooks/lint.yaml nodeset: openstack-helm-1node-ubuntu_noble required-projects: - openstack/openstack-helm irrelevant-files: - ^.*\.rst$ - ^releasenotes/.*$ pre-run: - playbooks/inject-keys.yaml - job: name: openstack-helm-pre-commit parent: tox-linters - job: name: openstack-helm-bandit nodeset: openstack-helm-1node-ubuntu_noble roles: - zuul: openstack/openstack-helm - zuul: zuul/zuul-jobs required-projects: - openstack/openstack-helm files: - ^.*\.py\.tpl$ - ^.*\.py$ - ^playbooks/osh-bandit.yaml$ pre-run: playbooks/prepare-hosts.yaml post-run: playbooks/collect-logs.yaml run: playbooks/osh-bandit.yaml vars: bandit_version: "1.7.1" - job: name: openstack-helm-publish-charts parent: publish-openstack-artifacts run: playbooks/build-chart.yaml required-projects: - openstack/openstack-helm post-run: playbooks/publish/post.yaml vars: base_version: "2025.2.0" - job: name: openstack-helm-deploy abstract: true roles: - zuul: openstack/openstack-helm - zuul: zuul/zuul-jobs required-projects: - openstack/openstack-helm - openstack/openstack-helm-plugin irrelevant-files: - ^.*\.rst$ - ^.*\.rst.gotmpl$ - ^doc/.*$ - ^releasenotes/.*$ timeout: 10800 pre-run: - playbooks/prepare-hosts.yaml - playbooks/mount-volumes.yaml - playbooks/inject-keys.yaml post-run: playbooks/collect-logs.yaml run: - playbooks/deploy-env.yaml - playbooks/run-scripts.yaml vars: osh_params: container_distro_name: ubuntu container_distro_version: jammy osh_values_overrides_path: "../openstack-helm/values_overrides" gate_scripts_relative_path: "../openstack-helm" overlay_network_setup: true extra_volume: size: 80G type: Linux mount_point: /opt/ext_vol docker: root_path: "/opt/ext_vol/docker" containerd: root_path: "/opt/ext_vol/containerd" kubeadm: pod_network_cidr: "10.244.0.0/16" service_cidr: "10.96.0.0/16" osh_plugin_repo: "{{ zuul.project.src_dir }}/../openstack-helm-plugin" loopback_setup: true loopback_device: /dev/loop100 loopback_image: "/opt/ext_vol/openstack-helm/ceph-loop.img" ceph_osd_data_device: /dev/loop100 kube_version_repo: "v1.35" kube_version: "1.35.0-1.1" calico_setup: true calico_version: "v3.31.3" cilium_setup: false cilium_version: "1.17.4" flannel_setup: false flannel_version: v0.26.7 metallb_setup: true metallb_version: "0.15.3" coredns_resolver_setup: false ingress_setup: false ingress_implementation: "haproxy" gatewayapi_setup: true gatewayapi_implementation: "envoy" gatewayapi_envoy_version: "v1.7.0" crictl_version: "v1.35.0" run_helm_tests: "no" floating_network_setup: true - job: name: openstack-helm-deploy-kubespray parent: openstack-helm-deploy abstract: true # NOTE(kozhukalov): Temporarily disable voting for this job # due to image pull rate limits on Docker Hub. voting: false run: - playbooks/deploy-env-kubespray.yaml - playbooks/run-scripts.yaml vars: kube_version_kubespray: "v1.29.5" - job: name: openstack-helm-compute-kit parent: openstack-helm-deploy abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - >- export OSH_EXTRA_HELM_ARGS="--values ../openstack-helm/values_overrides/memcached/exporter.yaml"; ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - >- export OSH_EXTRA_HELM_ARGS="--values ../openstack-helm/values_overrides/openvswitch/exporter.yaml"; ./tools/deployment/component/compute-kit/openvswitch.sh - >- export OSH_EXTRA_HELM_ARGS="--values ../openstack-helm/values_overrides/libvirt/inovex_exporter.yaml"; ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - export OSH_TEST_TIMEOUT=1200; ./tools/deployment/common/run-helm-tests.sh neutron - ./tools/deployment/common/run-helm-tests.sh nova - ./tools/deployment/common/run-helm-tests.sh glance - ./tools/deployment/common/run-helm-tests.sh keystone - ./tools/deployment/common/use-it.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-compute-kit-kubespray parent: openstack-helm-deploy-kubespray abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - export OSH_TEST_TIMEOUT=1200;./tools/deployment/common/run-helm-tests.sh neutron - ./tools/deployment/common/run-helm-tests.sh nova - ./tools/deployment/common/run-helm-tests.sh glance - ./tools/deployment/common/run-helm-tests.sh keystone - ./tools/deployment/common/use-it.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-compute-kit-rook parent: openstack-helm-deploy nodeset: openstack-helm-5nodes-ubuntu_jammy abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/ceph/ceph-rook.sh - ./tools/deployment/ceph/ceph-adapter-rook.sh - export VOLUME_HELM_ARGS=" "; ./tools/deployment/component/common/rabbitmq.sh - export VOLUME_HELM_ARGS=" "; ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/cinder/cinder.sh - ./tools/deployment/component/heat/heat.sh - ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - ./tools/deployment/common/use-it.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-compute-kit-helm-repo-local parent: openstack-helm-deploy abstract: true vars: osh_helm_repo: openstack-helm gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/prepare-helm-repos-local.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - export OSH_TEST_TIMEOUT=1200;./tools/deployment/common/run-helm-tests.sh neutron - ./tools/deployment/common/run-helm-tests.sh nova - ./tools/deployment/common/run-helm-tests.sh glance - ./tools/deployment/common/run-helm-tests.sh keystone - ./tools/deployment/common/use-it.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-compute-kit-helm-repo-public parent: openstack-helm-deploy abstract: true vars: osh_helm_repo: openstack-helm download_overrides: "-d" gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/prepare-helm-repos-public.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - export OSH_TEST_TIMEOUT=1200;./tools/deployment/common/run-helm-tests.sh neutron - ./tools/deployment/common/run-helm-tests.sh nova - ./tools/deployment/common/run-helm-tests.sh glance - ./tools/deployment/common/run-helm-tests.sh keystone - ./tools/deployment/common/use-it.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-compute-kit-ovn parent: openstack-helm-deploy abstract: true files: - ^ovn/.*$ - ^openvswitch/.*$ - ^neutron/.*$ - ^zuul\.d/.*$ - ^tools/deployment/component/ovn/.*$ vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/ovn/ovn.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - export OSH_TEST_TIMEOUT=1200;./tools/deployment/common/run-helm-tests.sh neutron - ./tools/deployment/common/run-helm-tests.sh nova - ./tools/deployment/common/run-helm-tests.sh glance - ./tools/deployment/common/run-helm-tests.sh keystone - ./tools/deployment/common/use-it.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-keystone-ldap parent: openstack-helm-deploy abstract: true files: - ^keystone/.*$ - ^zuul\.d/.*$ vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/common/cert-manager.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/component/common/ldap.sh - ./tools/deployment/component/keystone/keystone.sh - job: name: openstack-helm-cinder parent: openstack-helm-deploy abstract: true files: - ^cinder/.*$ - ^zuul\.d/.*$ - ^tools/deployment/component/cinder/.*$ vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/ceph/ceph.sh - ./tools/deployment/ceph/ceph-ns-activate.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/cinder/cinder.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-cinder-rook parent: openstack-helm-deploy nodeset: openstack-helm-5nodes-ubuntu_jammy abstract: true files: - ^cinder/.*$ - ^zuul\.d/.*$ - ^tools/deployment/component/cinder/.*$ - ^tools/deployment/ceph/.*$ vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/ceph/ceph-rook.sh - ./tools/deployment/ceph/ceph-adapter-rook.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/cinder/cinder.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-trove parent: openstack-helm-deploy abstract: true nodeset: openstack-helm-5nodes-ubuntu_noble files: - ^trove/.*$ - ^zuul\.d/.*$ - ^tools/deployment/component/trove/.*$ vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/ceph/ceph-rook.sh - ./tools/deployment/ceph/ceph-adapter-rook.sh - export VOLUME_HELM_ARGS=" "; ./tools/deployment/component/common/rabbitmq.sh - export VOLUME_HELM_ARGS=" "; ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/cinder/cinder.sh - ./tools/deployment/component/heat/heat.sh - ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - ./tools/deployment/component/trove/trove.sh - job: name: openstack-helm-horizon parent: openstack-helm-deploy abstract: true files: - ^horizon/.*$ - ^zuul\.d/.*$ - ^tools/deployment/component/horizon/.*$ vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/horizon/horizon.sh - job: name: openstack-helm-tls parent: openstack-helm-deploy nodeset: openstack-helm-5nodes-ubuntu_jammy abstract: true # NOTE(kozhukalov): The job is quite unstable now. Let's # temporarily disable voting for this job to unblock the gate. voting: false vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/common/cert-manager.sh - ./tools/deployment/ceph/ceph-rook.sh - ./tools/deployment/ceph/ceph-adapter-rook.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/cinder/cinder.sh - ./tools/deployment/component/heat/heat.sh - ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - export OSH_TEST_TIMEOUT=1200; ./tools/deployment/common/run-helm-tests.sh neutron - ./tools/deployment/common/run-helm-tests.sh nova - ./tools/deployment/common/run-helm-tests.sh glance - ./tools/deployment/common/run-helm-tests.sh keystone - ./tools/deployment/common/run-helm-tests.sh cinder - ./tools/deployment/common/use-it.sh - ./tools/deployment/common/force-cronjob-run.sh - job: name: openstack-helm-tacker parent: openstack-helm-deploy files: - tacker/.* abstract: true timeout: 7200 vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/component/barbican/barbican.sh - ./tools/deployment/monitoring/openstack-exporter.sh - ./tools/deployment/component/nfs-provisioner/nfs-provisioner.sh - ./tools/deployment/component/tacker/tacker.sh - ./tools/deployment/common/run-helm-tests.sh tacker - job: name: openstack-helm-skyline parent: openstack-helm-deploy timeout: 10800 files: - skyline/.* vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - ./tools/deployment/component/skyline/skyline.sh - ./tools/gate/selenium/skyline-selenium.sh - job: name: openstack-helm-octavia parent: openstack-helm-deploy timeout: 10800 vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - ./tools/deployment/component/barbican/barbican.sh - ./tools/deployment/component/octavia/octavia_resources.sh - ./tools/deployment/component/octavia/octavia_certs.sh - ./tools/deployment/component/octavia/octavia.sh - ./tools/deployment/component/octavia/octavia_test.sh - job: name: openstack-helm-watcher parent: openstack-helm-deploy timeout: 10800 files: - watcher/.* abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - ./tools/deployment/component/watcher/watcher.sh - job: name: openstack-helm-blazar parent: openstack-helm-deploy timeout: 7200 files: - blazar/.* abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/monitoring/openstack-exporter.sh - ./tools/deployment/component/blazar/blazar.sh - ./tools/deployment/component/blazar/blazar_smoke_test.sh - ./tools/deployment/common/run-helm-tests.sh blazar - job: name: openstack-helm-cloudkitty parent: openstack-helm-deploy timeout: 7200 files: - cloudkitty/.* abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/heat/heat.sh - export GLANCE_BACKEND=local; ./tools/deployment/component/glance/glance.sh - ./tools/deployment/component/compute-kit/openvswitch.sh - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/component/cloudkitty/cloudkitty.sh - ./tools/deployment/monitoring/openstack-exporter.sh - job: name: openstack-helm-freezer parent: openstack-helm-deploy timeout: 10800 files: - freezer/.* abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/freezer/freezer.sh - ./tools/deployment/component/freezer/freezer_smoke_test.sh - job: name: openstack-helm-zaqar parent: openstack-helm-deploy timeout: 10800 files: - zaqar/.* abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/redis/redis.sh - ./tools/deployment/component/zaqar/zaqar.sh - ./tools/deployment/component/zaqar/zaqar_smoke_test.sh - job: name: openstack-helm-swift parent: openstack-helm-deploy timeout: 10800 files: - swift/.* abstract: true vars: loopback_format: true loopback_format_fs_type: ext4 loopback_mount: true loopback_mount_path: /srv/node/loop100 loopback_image: "/opt/ext_vol/openstack-helm/swift-loop.img" gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/component/nfs-provisioner/nfs-provisioner.sh - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/db/mariadb.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/component/keystone/keystone.sh - ./tools/deployment/component/swift/swift.sh ... ================================================ FILE: zuul.d/infra_jobs.yaml ================================================ --- # Copyright 2018 SUSE LINUX GmbH. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - job: name: openstack-helm-logging parent: openstack-helm-deploy nodeset: openstack-helm-5nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway gate_scripts: - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/ceph/ceph-rook.sh - ./tools/deployment/ceph/ceph-adapter-rook.sh - export NAMESPACE=osh-infra; ./tools/deployment/component/common/ldap.sh - ./tools/deployment/logging/elasticsearch.sh - ./tools/deployment/logging/fluentd.sh - ./tools/deployment/logging/kibana.sh - ./tools/gate/selenium/kibana-selenium.sh || true - job: name: openstack-helm-monitoring parent: openstack-helm-deploy nodeset: openstack-helm-1node-ubuntu_jammy timeout: 10800 vars: ingress_osh_infra_setup: true osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway gate_scripts: - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/deploy-docker-registry.sh - export NAMESPACE=osh-infra; ./tools/deployment/component/common/ldap.sh - export NAMESPACE=osh-infra; ./tools/deployment/db/mariadb.sh - export NAMESPACE=osh-infra; ./tools/deployment/db/postgresql.sh - ./tools/deployment/monitoring/prometheus.sh - ./tools/deployment/monitoring/alertmanager.sh - ./tools/deployment/monitoring/kube-state-metrics.sh - ./tools/deployment/monitoring/node-problem-detector.sh - ./tools/deployment/monitoring/node-exporter.sh - ./tools/deployment/monitoring/process-exporter.sh - ./tools/deployment/monitoring/blackbox-exporter.sh - ./tools/deployment/monitoring/grafana.sh - ./tools/deployment/monitoring/nagios.sh - ./tools/gate/selenium/grafana-selenium.sh || true - ./tools/gate/selenium/prometheus-selenium.sh || true - ./tools/gate/selenium/nagios-selenium.sh || true - job: name: openstack-helm-mariadb-operator-2025-1-ubuntu_jammy parent: openstack-helm-deploy nodeset: openstack-helm-5nodes-ubuntu_jammy vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: "ldap,prometheus,backups,gateway" gate_scripts: - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh - ./tools/deployment/common/setup-client.sh - ./tools/deployment/common/namespace-config.sh - ./tools/deployment/ceph/ceph-rook.sh - ./tools/deployment/ceph/ceph-adapter-rook.sh - ./tools/deployment/component/common/rabbitmq.sh - ./tools/deployment/component/common/memcached.sh - ./tools/deployment/db/mariadb-operator-cluster.sh - ./tools/deployment/component/common/ldap.sh - | export OSH_EXTRA_HELM_ARGS="--set endpoints.oslo_db.hosts.default=mariadb-server-primary ${OSH_EXTRA_HELM_ARGS}" ./tools/deployment/openstack/keystone.sh - ./tools/deployment/db/mariadb-backup.sh - ./tools/deployment/monitoring/mysql-exporter.sh files: - ^roles/.* - ^mariadb-cluster/.* - ^tools/.* - job: name: openstack-helm-mariadb-ingress-2025-1-ubuntu_jammy parent: openstack-helm-compute-kit-2025-1-ubuntu_jammy vars: osh_params: feature_gates: "ingress-service,gateway" files: - ^helm-toolkit/.* - ^roles/.* - ^rabbitmq/.* - ^mariadb/.* - ^memcached/.* - ^libvrit/.* - ^openvswitch/.* - job: name: openstack-helm-ceph-migrate description: | This job is for testing the migration procedure from a Ceph cluster managed by legacy OSH ceph* charts to a Ceph cluster managed by Rook-Ceph operator. parent: openstack-helm-deploy nodeset: openstack-helm-5nodes-ubuntu_jammy timeout: 10800 pre-run: - playbooks/prepare-hosts.yaml - playbooks/mount-volumes.yaml - playbooks/inject-keys.yaml files: - ^helm-toolkit/.* - ^roles/.* - ^ceph.* - ^tools/deployment/ceph/.* vars: osh_params: openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy feature_gates: gateway gate_scripts: - ./tools/deployment/common/prepare-k8s.sh - ./tools/deployment/common/prepare-charts.sh # Deploy Ceph cluster using legacy OSH charts - ./tools/deployment/ceph/ceph_legacy.sh # Deploy stateful applications - | export NAMESPACE=openstack export MONITORING_HELM_ARGS=" " export RUN_HELM_TESTS=no export VOLUME_HELM_ARGS=" " ./tools/deployment/db/mariadb.sh - | export NAMESPACE=openstack export VOLUME_HELM_ARGS=" " ./tools/deployment/component/common/rabbitmq.sh # Migrate legacy Ceph to Rook - ./tools/deployment/ceph/migrate-before.sh - ./tools/deployment/ceph/migrate-values.sh - ./tools/deployment/ceph/migrate-to-rook-ceph.sh - ./tools/deployment/ceph/migrate-after.sh ... ================================================ FILE: zuul.d/nodesets.yaml ================================================ --- # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - nodeset: name: openstack-helm-1node-ubuntu_jammy nodes: - name: primary label: ubuntu-jammy groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - primary - name: k8s_control_plane nodes: - primary - nodeset: name: openstack-helm-3nodes-ubuntu_jammy nodes: - name: primary label: ubuntu-jammy - name: node-1 label: ubuntu-jammy - name: node-2 label: ubuntu-jammy groups: - name: primary nodes: - primary - name: nodes nodes: - node-1 - node-2 - name: k8s_cluster nodes: - primary - node-1 - node-2 - name: k8s_control_plane nodes: - primary - name: k8s_nodes nodes: - node-1 - node-2 - nodeset: name: openstack-helm-1node-2nodes-ubuntu_jammy nodes: - name: primary label: ubuntu-jammy - name: node-1 label: ubuntu-jammy - name: node-2 label: ubuntu-jammy groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - node-1 - node-2 - name: k8s_control_plane nodes: - node-1 - name: k8s_nodes nodes: - node-2 - nodeset: name: openstack-helm-1node-3nodes-ubuntu_jammy nodes: - name: primary label: ubuntu-jammy - name: node-1 label: ubuntu-jammy - name: node-2 label: ubuntu-jammy - name: node-3 label: ubuntu-jammy groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - node-1 - node-2 - node-3 - name: k8s_control_plane nodes: - node-1 - name: k8s_nodes nodes: - node-2 - node-3 - nodeset: name: openstack-helm-1node-32GB-ubuntu_jammy nodes: - name: primary # This label is available in vexxhost ca-ymq-1 region # The flavor v3-standard-8 in this particular region has # 32GB nodes. The number of such nodes is extremely limited. label: ubuntu-jammy-32GB groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - primary - name: k8s_control_plane nodes: - primary - nodeset: name: openstack-helm-4nodes-ubuntu_jammy nodes: - name: primary label: ubuntu-jammy - name: node-1 label: ubuntu-jammy - name: node-2 label: ubuntu-jammy - name: node-3 label: ubuntu-jammy groups: - name: primary nodes: - primary - name: nodes nodes: - node-1 - node-2 - node-3 - name: k8s_cluster nodes: - primary - node-1 - node-2 - node-3 - name: k8s_control_plane nodes: - primary - name: k8s_nodes nodes: - node-1 - node-2 - node-3 - nodeset: name: openstack-helm-5nodes-ubuntu_jammy nodes: - name: primary label: ubuntu-jammy - name: node-1 label: ubuntu-jammy - name: node-2 label: ubuntu-jammy - name: node-3 label: ubuntu-jammy - name: node-4 label: ubuntu-jammy groups: - name: primary nodes: - primary - name: nodes nodes: - node-1 - node-2 - node-3 - node-4 - name: k8s_cluster nodes: - primary - node-1 - node-2 - node-3 - node-4 - name: k8s_control_plane nodes: - primary - name: k8s_nodes nodes: - node-1 - node-2 - node-3 - node-4 - nodeset: name: openstack-helm-1node-ubuntu_noble nodes: - name: primary label: ubuntu-noble groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - primary - name: k8s_control_plane nodes: - primary - nodeset: name: openstack-helm-3nodes-ubuntu_noble nodes: - name: primary label: ubuntu-noble - name: node-1 label: ubuntu-noble - name: node-2 label: ubuntu-noble groups: - name: primary nodes: - primary - name: nodes nodes: - node-1 - node-2 - name: k8s_cluster nodes: - primary - node-1 - node-2 - name: k8s_control_plane nodes: - primary - name: k8s_nodes nodes: - node-1 - node-2 - nodeset: name: openstack-helm-1node-2nodes-ubuntu_noble nodes: - name: primary label: ubuntu-noble - name: node-1 label: ubuntu-noble - name: node-2 label: ubuntu-noble groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - node-1 - node-2 - name: k8s_control_plane nodes: - node-1 - name: k8s_nodes nodes: - node-2 - nodeset: name: openstack-helm-1node-3nodes-ubuntu_noble nodes: - name: primary label: ubuntu-noble - name: node-1 label: ubuntu-noble - name: node-2 label: ubuntu-noble - name: node-3 label: ubuntu-noble groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - node-1 - node-2 - node-3 - name: k8s_control_plane nodes: - node-1 - name: k8s_nodes nodes: - node-2 - node-3 - nodeset: name: openstack-helm-1node-32GB-ubuntu_noble nodes: - name: primary # This label is available in vexxhost ca-ymq-1 region # The flavor v3-standard-8 in this particular region has # 32GB nodes. The number of such nodes is extremely limited. label: ubuntu-noble-32GB groups: - name: primary nodes: - primary - name: k8s_cluster nodes: - primary - name: k8s_control_plane nodes: - primary - nodeset: name: openstack-helm-4nodes-ubuntu_noble nodes: - name: primary label: ubuntu-noble - name: node-1 label: ubuntu-noble - name: node-2 label: ubuntu-noble - name: node-3 label: ubuntu-noble groups: - name: primary nodes: - primary - name: nodes nodes: - node-1 - node-2 - node-3 - name: k8s_cluster nodes: - primary - node-1 - node-2 - node-3 - name: k8s_control_plane nodes: - primary - name: k8s_nodes nodes: - node-1 - node-2 - node-3 - nodeset: name: openstack-helm-5nodes-ubuntu_noble nodes: - name: primary label: ubuntu-noble - name: node-1 label: ubuntu-noble - name: node-2 label: ubuntu-noble - name: node-3 label: ubuntu-noble - name: node-4 label: ubuntu-noble groups: - name: primary nodes: - primary - name: nodes nodes: - node-1 - node-2 - node-3 - node-4 - name: k8s_cluster nodes: - primary - node-1 - node-2 - node-3 - node-4 - name: k8s_control_plane nodes: - primary - name: k8s_nodes nodes: - node-1 - node-2 - node-3 - node-4 ... ================================================ FILE: zuul.d/project.yaml ================================================ --- # Copyright 2018, SUSE LINUX GmbH. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - project: vars: # shared across all jobs helm_version: "4.1.1" chart_testing_version: "3.11.0" virtualenv: "{{ ansible_user_dir }}/venv" base_version: "2025.2.0" templates: - publish-openstack-docs-pti - release-notes-jobs-python3 check: jobs: - openstack-helm-linter - openstack-helm-pre-commit - openstack-helm-bandit # 2024.2 - openstack-helm-cinder-2024-2-ubuntu_jammy # 3 nodes rook - openstack-helm-compute-kit-2024-2-ubuntu_jammy # 1 node + 3 nodes # 2025.1 Ubuntu Jammy - openstack-helm-cinder-2025-1-ubuntu_jammy # 3 nodes rook - openstack-helm-compute-kit-2025-1-ubuntu_jammy # 1 node + 3 nodes - openstack-helm-octavia-2025-1-ubuntu_jammy # 4 nodes - openstack-helm-blazar-2025-1-ubuntu_jammy # 3 nodes; run only if blazar changed - openstack-helm-cloudkitty-2025-1-ubuntu_jammy # 3 nodes; run only if cloudkitty changed - openstack-helm-freezer-2025-1-ubuntu_jammy # 3 nodes; run only if freezer changed - openstack-helm-zaqar-2025-1-ubuntu_jammy # 3 nodes; run only if zaqar changed # TODO: Configure Cilium not to setup it's own overlay and # use existing VXLAN overlay interface for internal K8s communication # - openstack-helm-compute-kit-cilium-2025-1-ubuntu_jammy # 1 node + 3 nodes - openstack-helm-horizon-2025-1-ubuntu_jammy # 1 node - openstack-helm-compute-kit-dpdk-2025-1-ubuntu_jammy # 32GB node # 2025.1 Ubuntu Noble - openstack-helm-cinder-2025-1-ubuntu_noble # 5 nodes rook - openstack-helm-compute-kit-2025-1-ubuntu_noble # 1 node + 3 nodes # 2025.2 Ubuntu Noble - openstack-helm-cinder-2025-2-ubuntu_noble # 5 nodes rook - openstack-helm-compute-kit-2025-2-ubuntu_noble # 1 node + 3 nodes - openstack-helm-compute-kit-ovn-2025-2-ubuntu_noble # 1 node + 3 nodes - openstack-helm-skyline-2025-2-ubuntu_noble # 3 nodes - openstack-helm-trove-2025-2-ubuntu_noble # 5 nodes rook - openstack-helm-swift-2025-2-ubuntu_noble # 3 nodes # Infra jobs - openstack-helm-logging - openstack-helm-monitoring gate: jobs: - openstack-helm-linter - openstack-helm-cinder-2025-1-ubuntu_jammy - openstack-helm-compute-kit-2025-1-ubuntu_jammy # - openstack-helm-logging # - openstack-helm-monitoring post: jobs: - openstack-helm-publish-charts periodic: jobs: - openstack-helm-compute-kit-helm-repo-public-2025-1-ubuntu_jammy # 1 node + 3 nodes - openstack-helm-watcher-2025-1-ubuntu_jammy # 3 nodes - openstack-helm-blazar-2025-1-ubuntu_jammy # 3 nodes - openstack-helm-cloudkitty-2025-1-ubuntu_jammy # 3 nodes - openstack-helm-freezer-2025-1-ubuntu_jammy # 3 nodes - openstack-helm-tacker-2025-1-ubuntu_jammy # 3 nodes ...