blob: 7b2422d6025f364cce19d0cb5b76cc06ab058648 [file]
# 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.
#
# Provides extra kopf handlers to manage openserverless users
import logging
from datetime import datetime
import kopf
import openserverless.config as cfg
import openserverless.couchdb as cdb
import openserverless.endpoint as endpoint
import openserverless.ferretdb as mdb
import openserverless.kube as kube
import openserverless.milvus_standalone as milvus
import openserverless.minio_deploy as minio_deploy
import openserverless.postgres_operator as postgres
import openserverless.redis as redis
import openserverless.storage_static as static
import openserverless.user_patcher as user_patcher
import openserverless.userdb_util as userdb
import openserverless.seaweedfs_deploy as seaweedfs
from openserverless.quota_checker import REDIS_DB_QUOTA_ANNOTATION
from openserverless.user_config import UserConfig
from openserverless.user_metadata import UserMetadata
def get_ucfg(spec):
ucfg = UserConfig(spec)
ucfg.dump_config()
return ucfg
@kopf.on.create('openserverless.org', 'v1', 'whisksusers')
def whisk_user_create(spec, name, patch, **kwargs):
logging.info(f"*** whisk_user_create {name}")
conditions = []
state = {
}
conditions.append({
"lastTransitionTime": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"status": "True",
"type": "Initialized"})
ucfg = get_ucfg(spec)
user_metadata = UserMetadata(ucfg)
owner = kube.get(f"wsku/{name}")
if(ucfg.get("namespace") and ucfg.get("auth")):
res = cdb.create_ow_user(ucfg,user_metadata)
logging.info(f"OpenWhisk subject {ucfg.get('namespace')} added = {res}")
state['couchdb']= res
res = endpoint.create_ow_api_endpoint(ucfg,user_metadata)
logging.info(f"OpenWhisk api endpoints {ucfg.get('namespace')} added = {res}")
state['api']= res
if(cfg.get('components.minio') and (ucfg.get('object-storage.data.enabled') or ucfg.get('object-storage.route.enabled'))):
minio_deploy.create_ow_storage(state, ucfg, user_metadata, owner)
if(cfg.get('components.seaweedfs') and (ucfg.get('object-storage.data.enabled') or ucfg.get('object-storage.route.enabled'))):
seaweedfs.create_ow_storage(state, ucfg, user_metadata, owner)
if((cfg.get('components.minio') or cfg.get('components.seaweedfs')) and ucfg.get('object-storage.route.enabled') and cfg.get('components.static')):
res = static.create_ow_static_endpoint(ucfg,user_metadata, owner)
logging.info("OpenWhisk static endpoint for %s added = %s", ucfg.get('namespace'), res)
state['static']= res
if(cfg.get('components.mongodb') and ucfg.get('mongodb.enabled')):
res = mdb.create_db_user(ucfg,user_metadata)
logging.info(f"Mongodb setup for {ucfg.get('namespace')} added = {res}")
state['mongodb']= res
if(cfg.get('components.redis') and ucfg.get('redis.enabled')):
res = redis.create_db_user(ucfg, user_metadata)
logging.info(f"Redis setup for {ucfg.get('namespace')} added = {res}")
state['redis']= res
if(cfg.get('components.postgres') and ucfg.get('postgres.enabled')):
res = postgres.create_db_user(ucfg, user_metadata)
logging.info(f"Postgres setup for {ucfg.get('namespace')} added = {res}")
state['postgres']= res
if(cfg.get('components.milvus') and ucfg.get('milvus.enabled')):
res = milvus.create_ow_milvus(ucfg, user_metadata)
logging.info(f"Milvus setup for {ucfg.get('namespace')} added = {res}")
state['milvus']= res
# finally persists user metadata into the internal couchdb database
user_metadata.dump()
res = userdb.save_user_metadata(user_metadata)
state['user_metadata']= res
conditions.append({
"lastTransitionTime": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"status": "True",
"type": "Ready"})
patch.status['conditions']=conditions
return state
@kopf.on.delete('openserverless.org', 'v1', 'whisksusers')
def whisk_user_delete(spec, name, **kwargs):
logging.info(f"*** whisk_user_delete {name}")
ucfg = get_ucfg(spec)
if(ucfg.get("namespace")):
res = endpoint.delete_ow_api_endpoint(ucfg)
logging.info(f"OpenWhisk subject {ucfg.get('namespace')} api removed = {res}")
res = cdb.delete_ow_user(ucfg.get("namespace"))
logging.info(f"OpenWhisk subject {ucfg.get('namespace')} removed = {res}")
if(cfg.get('components.minio') and (ucfg.get('object-storage.data.enabled') or ucfg.get('object-storage.route.enabled'))):
res = minio_deploy.delete_ow_storage(ucfg)
logging.info(f"OpenWhisk namespace {ucfg.get('namespace')} MINIO storage removed = {res}")
if(cfg.get('components.seaweedfs') and (ucfg.get('object-storage.data.enabled') or ucfg.get('object-storage.route.enabled'))):
res = seaweedfs.delete_ow_storage(ucfg)
logging.info(f"OpenWhisk namespace {ucfg.get('namespace')} SEAWEEDFS storage removed = {res}")
if((cfg.get('components.minio') or cfg.get('components.seaweedfs')) and ucfg.get('object-storage.route.enabled') and cfg.get('components.static')):
res = static.delete_ow_static_endpoint(ucfg)
logging.info(f"OpenWhisk static endpoint for {ucfg.get('namespace')} removed = {res}")
if(cfg.get('components.mongodb') and ucfg.get('mongodb.enabled')):
res = mdb.delete_db_user(ucfg.get('namespace'),ucfg.get('mongodb.database'))
logging.info(f"Mongodb setup for {ucfg.get('namespace')} removed = {res}")
if(cfg.get('components.redis') and ucfg.get('redis.enabled')):
res = redis.delete_db_user(ucfg.get('namespace'))
logging.info(f"Redis setup for {ucfg.get('namespace')} removed = {res}")
if(cfg.get('components.postgres') and ucfg.get('postgres.enabled')):
res = postgres.delete_db_user(ucfg.get('namespace'),ucfg.get('postgres.database'))
logging.info(f"Postgres setup for {ucfg.get('namespace')} removed = {res}")
if(cfg.get('components.milvus') and ucfg.get('milvus.enabled')):
res = milvus.delete_ow_milvus(ucfg)
logging.info(f"Milvus setup for {ucfg.get('namespace')} removed = {res}")
res = userdb.delete_user_metadata(ucfg.get('namespace'))
@kopf.on.update('openserverless.org', 'v1', 'whisksusers')
def whisk_user_update(spec, status, namespace, diff, name, **kwargs):
logging.info(f"*** detected an update of wsku/{name} under namespace {namespace}")
owner = kube.get(f"wsku/{name}")
ucfg = get_ucfg(spec)
user_metadata = UserMetadata(ucfg)
user_patcher.patch(ucfg,user_metadata,diff, status, owner, name)
@kopf.on.resume('openserverless.org', 'v1', 'whisksusers')
def whisk_user_resume(spec, name, namespace,annotations, **kwargs):
logging.info(f"*** detected an update of wsku/{name} under namespace {namespace}")
ucfg = get_ucfg(spec)
user_metadata = UserMetadata(ucfg)
state = {}
if(cfg.get('components.redis') and ucfg.get('redis.enabled')):
read_only_mode = False
if annotations and REDIS_DB_QUOTA_ANNOTATION in annotations:
read_only_mode = annotations[REDIS_DB_QUOTA_ANNOTATION] in ["true"]
res = redis.create_db_user(ucfg,user_metadata,read_only_mode)
logging.info(f"Redis setup for {ucfg.get('namespace')} resumed = {res}")
state['redis']= res
if(cfg.get('components.minio') and ucfg.get('object-storage.route.enabled') and cfg.get('components.static')):
state['static']= True
if(cfg.get('components.mongodb') and ucfg.get('mongodb.enabled')):
state['mongodb']= True
if(cfg.get('components.milvus') and ucfg.get('milvus.enabled')):
state['milvus']= True
if(cfg.get('components.postgres') and ucfg.get('postgres.enabled')):
state['postgres']= True