nuvolaris/operator_util.py (75 lines of code) (raw):

# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT 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 nuvolaris.openwhisk as openwhisk import nuvolaris.kube as kube import nuvolaris.userdb_util as userdb import nuvolaris.config as cfg import nuvolaris.util as ut import nuvolaris.whisk_actions_deployer as system import nuvolaris.redis as redis from nuvolaris.nuvolaris_metadata import NuvolarisMetadata def annotate_operator_components_version(): """ This functions scans for pod matching the annotations whisks.nuvolaris.org/annotate-version: "true" and uses pod metadata.labels.name and spec.containers.image to annotate the global config map cm/config """ try: logging.info("**** annotating nuvolaris operator component versions") pods = kube.kubectl("get","pods",jsonpath=r"{.items[?(@.metadata.annotations.whisks\.nuvolaris\.org\/annotate-version)]}",debugresult=False) for pod in pods: if(pod['metadata'].get('labels') and pod['metadata']['labels'].get('name')): pod_name = pod['metadata']['labels']['name'] pod_image = pod['spec']['containers'][0]['image'] if(pod_name): openwhisk.annotate(f"{pod_name}_version={pod_image}") else: logging.warn("**** found a pod with whisks.nuvolaris.org/annotate-version without metadata.labels.name attribute") logging.warn(pod) logging.info("**** completed annotation of nuvolaris operator component versions") except Exception as e: logging.error(e) def update_nuvolaris_metadata(): try: logging.info("**** persisting nuvolaris metadata") nuv_metadata = NuvolarisMetadata() nuv_metadata.dump() userdb.save_nuvolaris_metadata(nuv_metadata) logging.info("**** nuvolaris metadata successfully persisted") except Exception as e: logging.error(e) def whisk_post_create(name): """ Executes a set of common operations after the operator terminated the deployment process. - persists nuvolaris metadata into the internal couchdb - annotate operator deployed components version - deploys system actions """ logging.info(f"*** whisk_post_create {name}") update_nuvolaris_metadata() annotate_operator_components_version() if system.deploy_whisk_system_action(): openwhisk.annotate("system_action_status=created") return True openwhisk.annotate("system_action_status=failed") return False def whisk_post_resume(name): """ Executes a set of common operations after the operator resumes, which is also the scenario triggered by a nuv update operator - restore redis nuvolaris namespace if redis is active - annotate operator deployed components version - redeploys system actions """ logging.info(f"*** whisk_post_resume {name}") if cfg.get("components.redis"): redis.restore_nuvolaris_db_user() annotate_operator_components_version() sysres = system.deploy_whisk_system_action() if sysres: openwhisk.annotate(f"system_action_status=created") logging.info("system action redeployed after operator restart") else: openwhisk.annotate(f"system_action_status=failed") logging.warn("system action deploy issues after operator restart. Checl logs for further details") def config_from_spec(spec, handler_type = "on_create"): """ Initialize the global configuration from the given spec. :param spec :param on_resume boolean flag telling if this method is called from the on_resume handler """ cfg.clean() cfg.configure(spec) cfg.detect() if "on_create" in handler_type: cfg.put("config.apihost", "https://pending") logging.debug("**** dumping initial configuration") if "on_update" in handler_type: logging.debug("**** dumping updated configuration") if "on_resume" in handler_type: apihost = ut.get_apihost_from_config_map() cfg.put("config.apihost", apihost) logging.debug("**** dumping resumed configuration") cfg.dump_config() def patch_operator_status(status,component, status_code): """ Patch the operator status in the safiest way: """ try: logging.debug(f"patching component {component} with code = {status_code} from event handler {status}") status['whisk_create'][component]=status_code except Exception as e: logging.error('*** failed to patch_operator_status: %s' % e)