diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 00000000..233c1c2e --- /dev/null +++ b/.pylintrc @@ -0,0 +1,2 @@ +[SIMILARITIES] +ignore-imports=yes diff --git a/devstack/lib/heat b/devstack/lib/heat index df9eac91..bed5dac6 100644 --- a/devstack/lib/heat +++ b/devstack/lib/heat @@ -250,10 +250,6 @@ function start_heat { proxy_pass_to_kubernetes /heat-api heat-api heat-wsgi-api proxy_pass_to_kubernetes /heat-api-cfn heat-api-cfn heat-wsgi-api-cfn - - # (re)start memcached to make sure we have a clean memcache. - kubectl rollout restart statefulset/memcached-heat - sleep 10 } # stop_heat() - Stop running processes diff --git a/devstack/lib/horizon b/devstack/lib/horizon index 3170679e..69a76345 100644 --- a/devstack/lib/horizon +++ b/devstack/lib/horizon @@ -42,8 +42,7 @@ function install_horizon { # start_horizon() - Start running processes function start_horizon { - kubectl rollout restart statefulset/memcached-horizon - sleep 10 + echo noop } # stop_horizon() - Stop running processes diff --git a/devstack/lib/keystone b/devstack/lib/keystone index 1b351302..7c7834ec 100644 --- a/devstack/lib/keystone +++ b/devstack/lib/keystone @@ -59,10 +59,6 @@ function start_keystone { if ! wait_for_service $SERVICE_TIMEOUT $service_uri; then die $LINENO "keystone did not start" fi - - # (re)start memcached to make sure we have a clean memcache. - kubectl rollout restart statefulset/memcached-keystone - sleep 10 } export -f start_keystone diff --git a/openstack_operator/glance.py b/openstack_operator/glance.py index fbe0a600..bb004c07 100644 --- a/openstack_operator/glance.py +++ b/openstack_operator/glance.py @@ -23,6 +23,8 @@ from openstack_operator import database from openstack_operator import identity from openstack_operator import utils +MEMCACHED = True + def create_or_resume(name, spec, **_): """Create and re-sync a glance instance @@ -37,9 +39,6 @@ def create_or_resume(name, spec, **_): else: database.ensure_mysql_cluster("glance", spec["mysql"]) - # deploy memcached - utils.create_or_update('glance/memcached.yml.j2', spec=spec) - # deploy glance api utils.create_or_update('glance/daemonset.yml.j2', name=name, spec=spec) diff --git a/openstack_operator/heat.py b/openstack_operator/heat.py index a63ddebe..5b32faaa 100644 --- a/openstack_operator/heat.py +++ b/openstack_operator/heat.py @@ -24,6 +24,8 @@ from openstack_operator import database from openstack_operator import identity from openstack_operator import utils +MEMCACHED = True + def create_or_resume(name, spec, **_): """Create and re-sync any Heat instances @@ -34,9 +36,6 @@ def create_or_resume(name, spec, **_): else: database.ensure_mysql_cluster("heat", spec["mysql"]) - # deploy memcached - utils.create_or_update('heat/memcached.yml.j2', spec=spec) - # deploy rabbitmq if not utils.ensure_secret("openstack", "heat-rabbitmq"): utils.create_or_update('heat/secret-rabbitmq.yml.j2', diff --git a/openstack_operator/horizon.py b/openstack_operator/horizon.py index 62245822..5546efdd 100644 --- a/openstack_operator/horizon.py +++ b/openstack_operator/horizon.py @@ -21,6 +21,8 @@ the appropriate deployments, Mcrouter, pod monitors and Prometheus rules. from openstack_operator import utils +MEMCACHED = True + def create_secret(): """Create a new horizon secret for secretKey""" @@ -49,8 +51,6 @@ def create_or_resume(name, spec, **_): spec=spec) utils.create_or_update('horizon/service.yml.j2', name=name, spec=spec) - utils.create_or_update('horizon/memcached.yml.j2', - name=name, spec=spec) if "ingress" in spec: utils.create_or_update('horizon/ingress.yml.j2', name=name, spec=spec) diff --git a/openstack_operator/keystone.py b/openstack_operator/keystone.py index dae4f2d2..7c6bbcc2 100644 --- a/openstack_operator/keystone.py +++ b/openstack_operator/keystone.py @@ -27,6 +27,8 @@ from openstack_operator import database from openstack_operator import filters from openstack_operator import utils +MEMCACHED = True + TOKEN_EXPIRATION = 86400 FERNET_ROTATION_INTERVAL = 3600 ACTIVE_KEYS = int(TOKEN_EXPIRATION / FERNET_ROTATION_INTERVAL) @@ -113,7 +115,6 @@ def create_or_resume(name, spec, **_): db_config = database.ensure_mysql_cluster("keystone", spec["mysql"]) # deploy memcached - utils.create_or_update('keystone/memcached.yml.j2', spec=spec) # keystone config utils.create_or_update('keystone/secret-config.yml.j2', diff --git a/openstack_operator/magnum.py b/openstack_operator/magnum.py index 1006429c..5c82ef77 100644 --- a/openstack_operator/magnum.py +++ b/openstack_operator/magnum.py @@ -23,6 +23,8 @@ from openstack_operator import database from openstack_operator import identity from openstack_operator import utils +MEMCACHED = True + def create_or_resume(name, spec, **_): """Create and re-sync any Magnum instances @@ -35,9 +37,6 @@ def create_or_resume(name, spec, **_): spec["mysql"] = {} database.ensure_mysql_cluster("magnum", spec["mysql"]) - # deploy memcached - utils.create_or_update('magnum/memcached.yml.j2', spec=spec) - # deploy rabbitmq if not utils.ensure_secret("openstack", "magnum-rabbitmq"): utils.create_or_update('magnum/secret-rabbitmq.yml.j2', diff --git a/openstack_operator/operator.py b/openstack_operator/operator.py index 8a7f4013..fec90720 100644 --- a/openstack_operator/operator.py +++ b/openstack_operator/operator.py @@ -19,6 +19,7 @@ the appropriate deployments, an instance of Keystone, Heat and Horizon for the installation. """ +import functools import os import pkg_resources @@ -51,7 +52,42 @@ def operator_configmap(namespace, name, **_): """Filter on the operator's ConfigMap.""" return namespace == os.getenv('OPERATOR_NAMESPACE', 'default') \ - and name == OPERATOR_CONFIGMAP + and name == "operator-config" + + +async def deploy_memcached(item, **_): + """ + Deploy a generic instance of Memcached + + This function deploys a generic instance of Memcached with sane defaults, + it's meant to be here to be consumed/called by the function below. + """ + utils.create_or_update('operator/memcached.yml.j2', name=item, adopt=True) + + +@kopf.on.resume('', 'v1', 'configmaps', when=operator_configmap) +@kopf.on.create('', 'v1', 'configmaps', when=operator_configmap) +@kopf.on.update('', 'v1', 'configmaps', when=operator_configmap) +async def deploy_memcacheds(body, **_): + """ + Deploy multiple Memcached instances for OpenStack services + + This function makes sure that Memcached is deployed for all services which + use it when when the operator sees any changes to the configuration. + """ + fns = {} + services = utils.to_dict(body['data']['operator-config.yaml']).keys() + + for entry_point in pkg_resources.iter_entry_points('operators'): + if entry_point.name not in services: + continue + + module = entry_point.load() + if hasattr(module, 'MEMCACHED') and module.MEMCACHED: + fns[entry_point.name] = \ + functools.partial(deploy_memcached, item=entry_point.name) + + await kopf.execute(fns=fns) @kopf.on.resume('', 'v1', 'configmaps', when=operator_configmap) diff --git a/openstack_operator/templates/glance/memcached.yml.j2 b/openstack_operator/templates/glance/memcached.yml.j2 deleted file mode 100644 index aeb30255..00000000 --- a/openstack_operator/templates/glance/memcached.yml.j2 +++ /dev/null @@ -1,32 +0,0 @@ ---- -# 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. - -apiVersion: infrastructure.vexxhost.cloud/v1alpha1 -kind: Memcached -metadata: - name: glance - namespace: openstack - labels: - {{ labels("glance") | indent(4) }} -spec: - megabytes: 128 -{% if 'nodeSelector' in spec %} - nodeSelector: - {{ spec.nodeSelector | to_yaml | indent(4) }} -{% endif %} -{% if 'tolerations' in spec %} - tolerations: - {{ spec.tolerations | to_yaml | indent(4) }} -{% endif %} diff --git a/openstack_operator/templates/horizon/memcached.yml.j2 b/openstack_operator/templates/horizon/memcached.yml.j2 deleted file mode 100644 index cb5d86fb..00000000 --- a/openstack_operator/templates/horizon/memcached.yml.j2 +++ /dev/null @@ -1,32 +0,0 @@ ---- -# 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. - -apiVersion: infrastructure.vexxhost.cloud/v1alpha1 -kind: Memcached -metadata: - name: horizon - namespace: openstack - labels: - {{ labels("horizon", name) | indent(4) }} -spec: - megabytes: 128 -{% if 'nodeSelector' in spec %} - nodeSelector: - {{ spec.nodeSelector | to_yaml | indent(4) }} -{% endif %} -{% if 'tolerations' in spec %} - tolerations: - {{ spec.tolerations | to_yaml | indent(4) }} -{% endif %} diff --git a/openstack_operator/templates/keystone/memcached.yml.j2 b/openstack_operator/templates/keystone/memcached.yml.j2 deleted file mode 100644 index b3302f4c..00000000 --- a/openstack_operator/templates/keystone/memcached.yml.j2 +++ /dev/null @@ -1,32 +0,0 @@ ---- -# 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. - -apiVersion: infrastructure.vexxhost.cloud/v1alpha1 -kind: Memcached -metadata: - name: keystone - namespace: openstack - labels: - {{ labels("keystone") | indent(4) }} -spec: - megabytes: 128 -{% if 'nodeSelector' in spec %} - nodeSelector: - {{ spec.nodeSelector | to_yaml | indent(4) }} -{% endif %} -{% if 'tolerations' in spec %} - tolerations: - {{ spec.tolerations | to_yaml | indent(4) }} -{% endif %} diff --git a/openstack_operator/templates/magnum/memcached.yml.j2 b/openstack_operator/templates/magnum/memcached.yml.j2 deleted file mode 100644 index 1415b975..00000000 --- a/openstack_operator/templates/magnum/memcached.yml.j2 +++ /dev/null @@ -1,32 +0,0 @@ ---- -# 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. - -apiVersion: infrastructure.vexxhost.cloud/v1alpha1 -kind: Memcached -metadata: - name: magnum - namespace: openstack - labels: - {{ labels("magnum") | indent(4) }} -spec: - megabytes: 128 -{% if 'nodeSelector' in spec %} - nodeSelector: - {{ spec.nodeSelector | to_yaml | indent(4) }} -{% endif %} -{% if 'tolerations' in spec %} - tolerations: - {{ spec.tolerations | to_yaml | indent(4) }} -{% endif %} diff --git a/openstack_operator/templates/heat/memcached.yml.j2 b/openstack_operator/templates/operator/memcached.yml.j2 similarity index 75% rename from openstack_operator/templates/heat/memcached.yml.j2 rename to openstack_operator/templates/operator/memcached.yml.j2 index cebc8e7e..91586602 100644 --- a/openstack_operator/templates/heat/memcached.yml.j2 +++ b/openstack_operator/templates/operator/memcached.yml.j2 @@ -16,17 +16,14 @@ apiVersion: infrastructure.vexxhost.cloud/v1alpha1 kind: Memcached metadata: - name: heat + name: {{ name }} namespace: openstack labels: - {{ labels("heat") | indent(4) }} + {{ labels(name) | indent(4) }} spec: megabytes: 128 -{% if 'nodeSelector' in spec %} nodeSelector: - {{ spec.nodeSelector | to_yaml | indent(4) }} -{% endif %} -{% if 'tolerations' in spec %} + node-role.kubernetes.io/master: "" tolerations: - {{ spec.tolerations | to_yaml | indent(4) }} -{% endif %} + - key: node-role.kubernetes.io/master + effect: NoSchedule diff --git a/setup.cfg b/setup.cfg index 0b449645..f971d09e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,14 @@ [metadata] name = openstack-operator +[entry_points] +operators = + glance = openstack_operator.glance + heat = openstack_operator.heat + horizon = openstack_operator.horizon + keystone = openstack_operator.keystone + magnum = openstack_operator.magnum + [files] packages = openstack_operator