UNPKG

k2hr3-api

Version:

K2HR3 REST API is K2hdkc based Resource and Roles and policy Rules

1,114 lines (1,113 loc) 608 kB
"use strict"; /* * K2HR3 REST API * * Copyright 2017 Yahoo Japan Corporation. * * K2HR3 is K2hdkc based Resource and Roles and policy Rules, gathers * common management information for the cloud. * K2HR3 can dynamically manage information as "who", "what", "operate". * These are stored as roles, resources, policies in K2hdkc, and the * client system can dynamically read and modify these information. * * For the full copyright and license information, please view * the license file that was distributed with this source code. * * AUTHOR: Takeshi Nakatani * CREATE: Wed Jun 8 2017 * REVISION: * */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.k2hr3 = void 0; //------------------------------------------------------------------- // [TODO][NOTE]{IMPORTANT] //------------------------------------------------------------------- // Do fix this line after changing k2hdkc nodejs addon. // const k2hdkc_1 = __importDefault(require("k2hdkc")); const k2hr3apiutil_1 = __importDefault(require("./k2hr3apiutil")); const k2hr3tokens_1 = __importDefault(require("./k2hr3tokens")); const k2hr3acrutil_1 = __importDefault(require("./k2hr3acrutil")); const dbglogging_1 = __importDefault(require("./dbglogging")); const k2hr3config_1 = require("./k2hr3config"); const apiConf = new k2hr3config_1.r3ApiConfig(); const k2hr3template_1 = __importStar(require("./k2hr3template")); const k2hr3keys_1 = require("./k2hr3keys"); // // Type chekcer // const rawIsDkcTypeTenantInfo = (val) => { if (!k2hr3apiutil_1.default.isPlainObject(val)) { return false; } if (k2hr3apiutil_1.default.isString(val.name) && k2hr3apiutil_1.default.isString(val.id) && (null === val.desc || k2hr3apiutil_1.default.isString(val.desc)) && (null === val.display || k2hr3apiutil_1.default.isString(val.display)) && (undefined === val.users || k2hr3apiutil_1.default.isStringArray(val.users))) { return true; } return false; }; const rawIsDkcTypeTenantInfoList = (arr) => { return (Array.isArray(arr) && arr.every((element) => rawIsDkcTypeTenantInfo(element))); }; const rawIsDkcTypeServiceRawValue = (val) => { if (!k2hr3apiutil_1.default.isPlainObject(val)) { return false; } if (k2hr3apiutil_1.default.isString(val.name) && k2hr3apiutil_1.default.isString(val.owner) && k2hr3apiutil_1.default.isValTypeAll(val.verify) && (null === val.tenant || k2hr3apiutil_1.default.isStringArray(val.tenant))) { return true; } return false; }; // [NOTE] // This type checker is not used now. /* const rawIsDkcTypeHostRawValue = (val: unknown): val is dkcTypeHostRawValue => { if(!apiutil.isPlainObject(val)){ return false; } if( apiutil.isSafeNumber(val.port) && (null === val.cuk || apiutil.isString(val.cuk) ) && (null === val.extra || apiutil.isString(val.extra) ) && (null === val.tag || apiutil.isString(val.tag) ) && (null === val.inboundip || apiutil.isString(val.inboundip) ) && (null === val.outboundip|| apiutil.isString(val.outboundip) ) ) { return true; } return false; }; */ const rawIsDkcTypeOneRoleHostBaseValue = (val) => { if (!k2hr3apiutil_1.default.isPlainObject(val)) { return false; } if (undefined === val.host || null === val.host || k2hr3apiutil_1.default.isString(val.host)) { return true; } return false; }; const rawIsDkcTypeOneRoleHostDetailValue = (val) => { if (!k2hr3apiutil_1.default.isPlainObject(val)) { return false; } if ((undefined === val.k8s_namespace || k2hr3apiutil_1.default.isString(val.k8s_namespace)) && (undefined === val.k8s_service_account || k2hr3apiutil_1.default.isString(val.k8s_service_account)) && (undefined === val.k8s_node_name || k2hr3apiutil_1.default.isString(val.k8s_node_name)) && (undefined === val.k8s_node_ip || k2hr3apiutil_1.default.isString(val.k8s_node_ip)) && (undefined === val.k8s_pod_name || k2hr3apiutil_1.default.isString(val.k8s_pod_name)) && (undefined === val.k8s_pod_id || k2hr3apiutil_1.default.isString(val.k8s_pod_id)) && (undefined === val.k8s_pod_ip || k2hr3apiutil_1.default.isString(val.k8s_pod_ip)) && (undefined === val.k8s_container_id || k2hr3apiutil_1.default.isString(val.k8s_container_id)) && (undefined === val.k8s_k2hr3_rand || k2hr3apiutil_1.default.isString(val.k8s_k2hr3_rand)) && rawIsDkcTypeOneRoleHostBaseValue(val)) { return true; } return false; }; const rawIsDkcTypeResourceRawKeysValue = (val) => { if (!k2hr3apiutil_1.default.isPlainObject(val)) { return false; } for (const [, value] of Object.entries(val)) { if (undefined !== value && null !== value && !k2hr3apiutil_1.default.isSafeEntity(value)) { // This means "any" return false; } } return true; }; const rawMergeDkcTypeResourceRawKeysValue = (obj1, obj2) => { const localSafeKey = (key) => { return ('__proto__' !== key && 'constructor' !== key && 'prototype' !== key); }; const _obj1 = rawIsDkcTypeResourceRawKeysValue(obj1) ? obj1 : {}; const _obj2 = rawIsDkcTypeResourceRawKeysValue(obj2) ? obj2 : {}; const resobj = {}; for (const key of Object.keys(_obj1)) { if (localSafeKey(key)) { resobj[key] = _obj1[key]; } } for (const key of Object.keys(_obj2)) { if (localSafeKey(key)) { resobj[key] = _obj2[key]; } } return resobj; }; const cvtToDkcTypeResourceRawDataValue = (val) => { const result = {}; if (!k2hr3apiutil_1.default.isSafeEntity(val)) { return result; } for (const key of Object.keys(val)) { const oneval = val[key]; if (k2hr3apiutil_1.default.isPlainObject(oneval) && k2hr3apiutil_1.default.isSafeNumber(oneval.port) && (null === oneval.cuk || k2hr3apiutil_1.default.isString(oneval.cuk)) && (null === oneval.extra || k2hr3apiutil_1.default.isString(oneval.extra)) && (null === oneval.tag || k2hr3apiutil_1.default.isString(oneval.tag)) && (null === oneval.inboundip || k2hr3apiutil_1.default.isString(oneval.inboundip)) && (null === oneval.outboundip || k2hr3apiutil_1.default.isString(oneval.outboundip)) && (null === oneval.host || k2hr3apiutil_1.default.isString(oneval.host))) { result[key] = oneval; } else { result[key] = null; } } return result; }; const rawIsDkcTypeChildrenTree = (val) => { if (!k2hr3apiutil_1.default.isPlainObject(val)) { return false; } if (!k2hr3apiutil_1.default.isString(val.name) || (undefined !== val.owner && !k2hr3apiutil_1.default.isBoolean(val.owner)) || !k2hr3apiutil_1.default.isArray(val.children) || !val.children.every((element) => rawIsDkcTypeChildrenTree(element))) { return false; } return true; }; const rawIsResTypeChildrenTree = (val) => { if (!k2hr3apiutil_1.default.isPlainObject(val)) { return false; } if (!k2hr3apiutil_1.default.isBoolean(val.result) || (null !== val.message && !k2hr3apiutil_1.default.isString(val.message)) || (undefined !== val.status && !k2hr3apiutil_1.default.isSafeNumber(val.status)) || (undefined !== val.children && !k2hr3apiutil_1.default.isArray(val.children)) || (k2hr3apiutil_1.default.isArray(val.children) && !val.children.every((element) => rawIsDkcTypeChildrenTree(element)))) { return false; } return true; }; //--------------------------------------------------------- // Configuration and port number from Environment //--------------------------------------------------------- let dkcconf = null; let dkcport = null; let dkccuk = null; (() => { if (!k2hr3apiutil_1.default.isSafeEntity(dkcconf)) { let tmpdkcconf = apiConf.getK2hdkcConfig(); if (!k2hr3apiutil_1.default.checkFileExist(tmpdkcconf)) { dbglogging_1.default.elog('k2hdkc slave configuration file(' + tmpdkcconf + ') specified in config json does not exist, then try to check K2HDKC_SLAVE_CONF environemnt.'); tmpdkcconf = k2hr3apiutil_1.default.getSafeString(process.env.K2HDKC_SLAVE_CONF); if (!k2hr3apiutil_1.default.checkFileExist(tmpdkcconf)) { dbglogging_1.default.elog('k2hdkc slave configuration file(' + tmpdkcconf + ') specified by K2HDKC_SLAVE_CONF environemnt does not exist, then use default path(/etc/k2hdkc/slave.ini).'); tmpdkcconf = '/etc/k2hdkc/slave.ini'; } } dkcconf = tmpdkcconf; } if (!k2hr3apiutil_1.default.isSafeEntity(dkcport)) { let tmpdkcport = apiConf.getK2hdkcPort(); if (!k2hr3apiutil_1.default.isSafeNumeric(tmpdkcport)) { dbglogging_1.default.elog('k2hdkc slave port number(' + JSON.stringify(tmpdkcport) + ') specified in config json is something wrong, then try to check K2HDKC_SLAVE_PORT environemnt.'); tmpdkcport = k2hr3apiutil_1.default.getSafeString(process.env.K2HDKC_SLAVE_PORT); } if (k2hr3apiutil_1.default.isSafeNumeric(tmpdkcport)) { const tmpPort = k2hr3apiutil_1.default.cvtToNumber(tmpdkcport); if (k2hr3apiutil_1.default.isSafeNumber(tmpPort)) { dkcport = tmpPort; } else { dbglogging_1.default.elog('k2hdkc slave port number(' + JSON.stringify(tmpdkcport) + ') specified by K2HDKC_SLAVE_PORT environment is something wrong, then use default port number(8031).'); dkcport = 8031; } } else { dbglogging_1.default.elog('k2hdkc slave port number(' + JSON.stringify(tmpdkcport) + ') specified by K2HDKC_SLAVE_PORT environment is something wrong, then use default port number(8031).'); dkcport = 8031; } } if (!k2hr3apiutil_1.default.isSafeEntity(dkccuk)) { let tmpdkccuk = apiConf.getK2hdkcCuk(); if (null === tmpdkccuk) { dbglogging_1.default.mlog('k2hdkc slave cuk is not specified. then try to check K2HDKC_SLAVE_CUK environemnt.'); tmpdkccuk = k2hr3apiutil_1.default.getSafeString(process.env.K2HDKC_SLAVE_CUK); if (!k2hr3apiutil_1.default.isSafeString(tmpdkccuk)) { dbglogging_1.default.mlog('k2hdkc slave cuk is not specified by K2HDKC_SLAVE_CUK environment is something wrong, then not use cuk(null).'); tmpdkccuk = null; } } dkccuk = tmpdkccuk; } })(); //--------------------------------------------------------- // Configuration for confirmation level of Service Tenant //--------------------------------------------------------- const is_allow_dummy_tenant = !(apiConf.isConfirmTenantForService()); //--------------------------------------------------------- // Normalization host information //--------------------------------------------------------- // // input_info : input is allow following // (1) string = ip address or hostname // (2) dkcTypeHostRawValueSet = { // ip: ip address string(or null/undefined) // hostname: hostname string(or null/undefined) // port: port number(or null/undefined) // cuk: container unique key(or null/undefined) // extra: string(or null/undefined) // tag: string(or null/undefined) // inboundip: ip address string(or null/undefined) // outboundip: ip address string(or null/undefined) // (key: undefined) // (id: undefined) // (alive: undefined) // } // (3) array = dkcTypeHostRawValueSet[] // // result : result is following, this array can be specified by rawCreateRole() // dkcTypeHostRawValueSet[] = [ // dkcTypeHostRawValueSet = { // hostname: "x.y.x.yahoo.co.jp" (or null) // ip: "172.1.1.1" (or null) // port: 8000 (if not specify, the value is 0="any") // cuk: "any string" (if not specify, the value is null or undefined) // extra: "explain, etc" (if not specify, the value is null or undefined) // tag: "tag string" (if not specify, the value is null or undefined) // inboundip: "192.168.1.1" (if not specify, the value is null or undefined) // outboundip: "192.168.1.1" (if not specify, the value is null or undefined) // (key: undefined) // (id: undefined) // (alive: undefined) // }, // .... // ] // // [NOTE] // If both ip address and hostname are specified, the result is array[2]. // It is an array with two elements divided into a hostname and an ip address. // const getSafeHosts = (input_info) => { let result = []; if (!k2hr3apiutil_1.default.isSafeEntity(input_info)) { return result; } if (k2hr3apiutil_1.default.isArray(input_info)) { // a case of dkcTypeHostRawValueSet[] for (let cnt = 0; cnt < input_info.length; ++cnt) { // reentrant const tmp = getSafeHosts(input_info[cnt]); result = result.concat(tmp); } } else if (k2hr3apiutil_1.default.isString(input_info)) { // a case of string let ipaddr = null; let hostname = null; if (k2hr3apiutil_1.default.isIpAddressString(input_info)) { ipaddr = input_info; } else { hostname = input_info; } const host_info = { hostname: hostname, ip: ipaddr, port: 0, cuk: null, extra: null, tag: null, inboundip: null, outboundip: null }; result.push(host_info); } else { // a case of dkcTypeHostRawValueSet const host_info = { hostname: null, ip: null, port: 0, cuk: null, extra: null, tag: null, inboundip: null, outboundip: null }; // A case of object if (k2hr3apiutil_1.default.isSafeString(input_info.ip) && k2hr3apiutil_1.default.isIpAddressString(input_info.ip)) { host_info.ip = input_info.ip; } if (k2hr3apiutil_1.default.isSafeString(input_info.hostname)) { host_info.hostname = input_info.hostname; } if (k2hr3apiutil_1.default.isSafeNumber(input_info.port)) { host_info.port = input_info.port; } if (k2hr3apiutil_1.default.isSafeString(input_info.cuk)) { host_info.cuk = input_info.cuk; } if (k2hr3apiutil_1.default.isSafeString(input_info.extra)) { host_info.extra = input_info.extra; } if (k2hr3apiutil_1.default.isSafeString(input_info.tag)) { host_info.tag = input_info.tag; } // optional keys if (k2hr3apiutil_1.default.isSafeString(input_info.inboundip) && k2hr3apiutil_1.default.isIpAddressString(input_info.inboundip)) { host_info.inboundip = input_info.inboundip; } if (k2hr3apiutil_1.default.isSafeString(input_info.outboundip) && k2hr3apiutil_1.default.isIpAddressString(input_info.outboundip)) { host_info.outboundip = input_info.outboundip; } if (k2hr3apiutil_1.default.isSafeString(host_info.ip) && k2hr3apiutil_1.default.isSafeString(host_info.hostname)) { const hostname_bup = host_info.hostname; host_info.hostname = null; // add ip address object result.push(host_info); // set up for hostanme host_info.hostname = hostname_bup; host_info.ip = null; } result.push(host_info); } return result; }; //--------------------------------------------------------- // increment/decrement reference count raw function //--------------------------------------------------------- // fullyrn : full yrn for main key(example: "yrn:yahoo:<service>::<tenant>:policy:<policy>") // increment : increment(true) or decrement(false) // const rawIncDecReferenceCount = (dkcobj_permanent, fullyrn, increment) => { const resobj = { result: true, message: null }; if (!k2hr3apiutil_1.default.isPlainObject(dkcobj_permanent) || !dkcobj_permanent.isPermanent()) { resobj.result = false; resobj.message = 'parameter dkcobj_permanent is not object or not permanent'; dbglogging_1.default.elog(resobj.message); return resobj; } if (!k2hr3apiutil_1.default.isSafeString(fullyrn)) { resobj.result = false; resobj.message = 'some parameters aree wrong : fullyrn=' + JSON.stringify(fullyrn) + ', increment=' + JSON.stringify(increment); dbglogging_1.default.elog(resobj.message); return resobj; } if (!k2hr3apiutil_1.default.isBoolean(increment)) { resobj.result = false; resobj.message = 'some parameters aree wrong : fullyrn=' + JSON.stringify(fullyrn) + ', increment=' + JSON.stringify(increment); dbglogging_1.default.elog(resobj.message); return resobj; } // // keys // const keys = (0, k2hr3keys_1.getK2hr3Keys)(); const reference_key = fullyrn + '/' + keys.REFERENCE_KW; // check fullyrn key const subkeylist = dkcobj_permanent.getSubkeys(fullyrn, true); if (!k2hr3apiutil_1.default.findStringInArray(subkeylist, reference_key)) { // [NOTE] // In case of decrement, it is warning rather than error. // if (increment) { resobj.result = false; resobj.message = 'Could not find fullyrn key(' + fullyrn + ') or reference key for increment'; dbglogging_1.default.elog(resobj.message); } else { dbglogging_1.default.wlog('Could not find fullyrn key(' + fullyrn + ') or reference key for decrement'); } return resobj; } // increment/decrement reference count if (!dkcobj_permanent.casIncDec(reference_key, increment)) { resobj.result = false; resobj.message = 'Could not increment/decrement reference in fullyrn key(' + fullyrn + ')'; dbglogging_1.default.elog(resobj.message); return resobj; } return resobj; }; //--------------------------------------------------------- // create simple key tree //--------------------------------------------------------- // keys string or array // string: one or more keys with '/' separator(ex. "foo", "foo/bar/...") // array: array has elements which is one or more keys with '/' separator // ex. ["foo", "bar"], ["foo", "foo/bar/..."] // const rawCreateKeyTree = (dkcobj_permanent, parent_key, keys, allow_empty_key) => { if (!k2hr3apiutil_1.default.isPlainObject(dkcobj_permanent) || !dkcobj_permanent.isPermanent()) { dbglogging_1.default.elog('parameter dkcobj_permanent is not object or not permanent'); return false; } if (!k2hr3apiutil_1.default.isSafeString(parent_key)) { dbglogging_1.default.elog('parameters are wrong : parent_key=' + JSON.stringify(parent_key)); return false; } // build hierarchy array const hierarchy = k2hr3apiutil_1.default.expandHierarchy(parent_key, keys, '/', allow_empty_key); if (null === hierarchy) { dbglogging_1.default.elog('could not expand hierarchy array for parent and children.'); return false; } // loop for creating subkey in parent for (const parent in hierarchy) { if (!k2hr3apiutil_1.default.isNotEmptyArray(hierarchy[parent])) { dbglogging_1.default.wlog('parent key(' + parent + ') does not have new subkeys'); continue; } // get parent's subkeys let subkeylist = dkcobj_permanent.getSubkeys(parent, true); if (!k2hr3apiutil_1.default.isNotEmptyArray(subkeylist)) { subkeylist = new Array(0); } // check new subkey let is_cahnged = false; for (let cnt = 0; cnt < hierarchy[parent].length; ++cnt) { if (!k2hr3apiutil_1.default.findStringInArray(subkeylist, hierarchy[parent][cnt])) { subkeylist.push(hierarchy[parent][cnt]); is_cahnged = true; } } if (is_cahnged) { // over write(add) subkey to parent if (!dkcobj_permanent.setSubkeys(parent, subkeylist)) { // add subkey to parent dbglogging_1.default.elog('could not add ' + JSON.stringify(subkeylist) + ' under ' + parent + ' key'); return false; } } } return true; }; //--------------------------------------------------------- // Small utility for tenant name //--------------------------------------------------------- const rawGetKeysFromResourceKey = (user, resource_key) => { const keys = (0, k2hr3keys_1.getK2hr3Keys)(user); // make resource name from resource yrn path const nameptn = new RegExp('^' + keys.MATCH_ANY_TENANT_RESOURCE); // regex = /^yrn:yahoo:(.*)::(.*):resource:(.*)/ const namematches = resource_key.match(nameptn); if (!k2hr3apiutil_1.default.isNotEmptyArray(namematches) || null === namematches || namematches.length < 4 || !k2hr3apiutil_1.default.isSafeString(namematches[2])) { // res_yrn is not full yrn to resource return keys; } let service = namematches[1]; if (!k2hr3apiutil_1.default.isSafeString(service)) { service = null; } return (0, k2hr3keys_1.getK2hr3Keys)(user, namematches[2], service); }; //--------------------------------------------------------- // initialize k2hdkc data //--------------------------------------------------------- // // global flag for all keys up in k2hdkc // let is_init_key_hierarchy = false; const rawInitKeyHierarchy = (dkcobj_permanent) => { if (is_init_key_hierarchy) { return true; } let dkcobj = dkcobj_permanent; let need_clean = false; if (!k2hr3apiutil_1.default.isPlainObject(dkcobj_permanent) || !dkcobj_permanent.isPermanent()) { if (null === dkcconf || null === dkcport) { dbglogging_1.default.elog('Configuration is not set.'); return false; } need_clean = true; dkcobj = (0, k2hdkc_1.default)(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean) } const keys = (0, k2hr3keys_1.getK2hr3Keys)(); // // Check top key "yrn" exists. // let subkeylist = dkcobj.getSubkeys(keys.YRN_KEY, true); if (k2hr3apiutil_1.default.isNotEmptyArray(subkeylist) && 0 < subkeylist.length && keys.DOMAIN_KEY == subkeylist[0]) { is_init_key_hierarchy = true; if (need_clean) { dkcobj.clean(); } return true; } // // Build key hierarchy // subkeylist = [keys.DOMAIN_KEY]; if (!dkcobj.setSubkeys(keys.YRN_KEY, subkeylist)) { // set subkey yrn:yahoo -> yrn dbglogging_1.default.elog('could not set ' + keys.DOMAIN_KEY + ' subkey under ' + keys.YRN_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } subkeylist = [keys.NO_SERVICE_KEY]; if (!dkcobj.setSubkeys(keys.DOMAIN_KEY, subkeylist)) { // set subkey yrn:yahoo:<no service> -> yrn:yahoo dbglogging_1.default.elog('could not set ' + keys.NO_SERVICE_KEY + ' subkey under ' + keys.DOMAIN_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } subkeylist = [keys.NO_SERVICE_REGION_KEY]; if (!dkcobj.setSubkeys(keys.NO_SERVICE_KEY, subkeylist)) { // set subkey yrn:yahoo::<no region> -> yrn:yahoo:<no service> dbglogging_1.default.elog('could not set ' + keys.NO_SERVICE_REGION_KEY + ' subkey under ' + keys.NO_SERVICE_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } subkeylist = [keys.NO_SERVICE_TENANT_KEY]; if (!dkcobj.setSubkeys(keys.NO_SERVICE_REGION_KEY, subkeylist)) { // set subkey yrn:yahoo:::<no tenant> -> yrn:yahoo::<no region> dbglogging_1.default.elog('could not set ' + keys.NO_SERVICE_TENANT_KEY + ' subkey under ' + keys.NO_SERVICE_REGION_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } subkeylist = [keys.USER_TOP_KEY, keys.TOKEN_TOP_KEY, keys.ACTION_TOP_KEY, keys.KEYSTONE_TOP_KEY, keys.MASTER_SERVICE_TOP_KEY, keys.IAAS_TOP_KEY]; if (!dkcobj.setSubkeys(keys.NO_SERVICE_TENANT_KEY, subkeylist)) { // set subkey yrn:yahoo::::{user, token, action, keystone, service, iaas} -> yrn:yahoo:::<no tenant> dbglogging_1.default.elog('could not set ' + keys.USER_TOP_KEY + ', ' + keys.ACTION_TOP_KEY + ', ' + keys.TOKEN_TOP_KEY + ', ' + keys.KEYSTONE_TOP_KEY + ', ' + keys.MASTER_SERVICE_TOP_KEY + ', ' + keys.IAAS_TOP_KEY + ' subkeys under ' + keys.NO_SERVICE_TENANT_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // yrn:yahoo::::action // // [NOTE] // We do not need value for read/write action key, but we need to make this key. // Thus we set value as dummy into it. // subkeylist = [keys.ACTION_READ_KEY, keys.ACTION_WRITE_KEY]; if (!dkcobj.setSubkeys(keys.ACTION_TOP_KEY, subkeylist)) { // set subkey yrn:yahoo::::action:{read, write} -> yrn:yahoo::::action dbglogging_1.default.elog('could not set ' + keys.ACTION_READ_KEY + ', ' + keys.ACTION_WRITE_KEY + ' subkeys under ' + keys.ACTION_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } if (!dkcobj.setValue(keys.ACTION_READ_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::action:read dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.ACTION_READ_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } if (!dkcobj.setValue(keys.ACTION_WRITE_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::action:write dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.ACTION_WRITE_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // yrn:yahoo::::user // // [NOTE] // We do not need value for user top key, but we need to make this key // for adding subkeys after processing. Thus we set value as dummy into it. // if (!dkcobj.setValue(keys.USER_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::user dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.USER_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // yrn:yahoo::::token // // [NOTE] // We do not need value for token user/role top key, but we need to make this key // for adding subkeys after processing. Thus we set value as dummy into it. // subkeylist = [keys.TOKEN_USER_TOP_KEY, keys.TOKEN_ROLE_TOP_KEY]; if (!dkcobj.setSubkeys(keys.TOKEN_TOP_KEY, subkeylist)) { // set subkey yrn:yahoo::::token:{user, role} -> yrn:yahoo::::token dbglogging_1.default.elog('could not set ' + keys.TOKEN_USER_TOP_KEY + ', ' + keys.TOKEN_ROLE_TOP_KEY + ' subkeys under ' + keys.TOKEN_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } if (!dkcobj.setValue(keys.TOKEN_USER_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::token:user dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.ACTION_READ_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } if (!dkcobj.setValue(keys.TOKEN_ROLE_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::token:role dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.ACTION_WRITE_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // yrn:yahoo::::keystone // // [NOTE] // We do not need value for keystone top key, but we need to make this key // for adding subkeys after processing. Thus we set value as dummy into it. // if (!dkcobj.setValue(keys.KEYSTONE_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::keystone dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.KEYSTONE_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // yrn:yahoo::::iaas // // [NOTE] // We do not need value for iaas and iaas:{openstack|k8s} top key, but we need to make this key // for adding subkeys after processing. Thus we set value as dummy into it. // if (!dkcobj.setValue(keys.IAAS_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::iaas dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.IAAS_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // create openstack and kubernetes key subkeylist = [keys.IAAS_OS_TOP_KEY, keys.IAAS_K8S_TOP_KEY]; if (!dkcobj.setSubkeys(keys.IAAS_TOP_KEY, subkeylist)) { // set subkey yrn:yahoo::::iaas:{openstack|k8s} -> yrn:yahoo::::iaas dbglogging_1.default.elog('could not set ' + keys.IAAS_OS_TOP_KEY + ' and ' + keys.IAAS_K8S_TOP_KEY + ' subkey under ' + keys.IAAS_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } if (!dkcobj.setValue(keys.IAAS_OS_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::iaas:openstack dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.IAAS_OS_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } if (!dkcobj.setValue(keys.IAAS_K8S_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::iaas:k8s dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.IAAS_K8S_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // yrn:yahoo::::service // // [NOTE] // We do not need value for service top key, but we need to make this key // for adding subkeys after processing. Thus we set value as dummy into it. // if (!dkcobj.setValue(keys.MASTER_SERVICE_TOP_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::service dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.SERVICE_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } // create any tenant key subkeylist = [keys.ANYTENANT_SERVICE_TOP_KEY]; if (!dkcobj.setSubkeys(keys.MASTER_SERVICE_TOP_KEY, subkeylist)) { // set subkey yrn:yahoo::::service: -> yrn:yahoo::::service dbglogging_1.default.elog('could not set ' + keys.ANYTENANT_SERVICE_TOP_KEY + ' subkey under ' + keys.MASTER_SERVICE_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } subkeylist = [keys.ANYTENANT_SERVICE_KEY]; if (!dkcobj.setSubkeys(keys.ANYTENANT_SERVICE_TOP_KEY, subkeylist)) { // set subkey yrn:yahoo::::service::anytenant -> yrn:yahoo::::service: dbglogging_1.default.elog('could not set ' + keys.ANYTENANT_SERVICE_KEYANYTENANT_SERVICE_TOP_KEY + ' subkey under ' + keys.ANYTENANT_SERVICE_TOP_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } if (!dkcobj.setValue(keys.ANYTENANT_SERVICE_KEY, keys.VALUE_ENABLE)) { // set value enable(dummy) -> yrn:yahoo::::service::anytenant dbglogging_1.default.elog('could not set ' + keys.VALUE_ENABLE + ' value to ' + keys.ANYTENANT_SERVICE_KEY + ' key'); if (need_clean) { dkcobj.clean(); } return false; } is_init_key_hierarchy = true; if (need_clean) { dkcobj.clean(); } return true; }; //--------------------------------------------------------- // create service key //--------------------------------------------------------- // // Create Service Main key // // tenant : service owner tenant name // servicename : service name // verify : verify URL or any object // // [NOTE] // Must create tenant(service owner) before calling this function. // const rawCreateService = (tenant, servicename, verify) => { const resobj = { result: true, message: null }; if (!k2hr3apiutil_1.default.isSafeString(tenant) || !k2hr3apiutil_1.default.isSafeString(servicename)) { resobj.result = false; resobj.message = 'parameters are wrong : tenant=' + JSON.stringify(tenant) + ', service=' + JSON.stringify(servicename); dbglogging_1.default.elog(resobj.message); return resobj; } let _verify; if (!k2hr3apiutil_1.default.isSafeEntity(verify)) { _verify = JSON.stringify(null); // default null } else if (k2hr3apiutil_1.default.isSafeString(verify) && k2hr3apiutil_1.default.isSafeUrl(verify)) { // allow any URL // // Verify URL is called as like following: // GET http://<verify host[:port]>{/<path>}?service=<service name>&tenant=<tenant name>&tenantid=<tenant id>&user=<user name>&userid=<user id> // // service : service name // tenant : tenant name // tenantid : tenant id // user : user name // userid : user id // _verify = verify; } else if (!k2hr3apiutil_1.default.isSafeString(verify)) { // allow any object _verify = JSON.stringify(verify); // formatted JSON } else { _verify = verify; } const dkcobj = (0, k2hdkc_1.default)(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean) const keys = (0, k2hr3keys_1.getK2hr3Keys)(null, tenant, servicename); if (!rawInitKeyHierarchy(dkcobj)) { resobj.result = false; resobj.message = 'Not initialize yet, or configuration is not set'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } // // check tenant key exists // if (!rawCheckTenantEnable(dkcobj, tenant, servicename)) { resobj.result = false; resobj.message = 'service owner tenant(' + tenant + ') is not found.'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } // // Check service key exists and owner // let subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_TOP_KEY, true)); if (k2hr3apiutil_1.default.findStringInArray(subkeylist, keys.MASTER_SERVICE_KEY)) { // check subkey yrn:yahoo::::service:<service> -> yrn:yahoo::::service subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true)); if (k2hr3apiutil_1.default.findStringInArray(subkeylist, keys.SERVICE_OWNER_KEY)) { // check subkey yrn:yahoo::::service:<service>:owner -> yrn:yahoo::::service:<service> const value_tmp = dkcobj.getValue(keys.SERVICE_OWNER_KEY, null, true, null); // get value -> yrn:yahoo::::service:<service>:owner if (k2hr3apiutil_1.default.isSafeString(value_tmp)) { if (value_tmp != keys.MASTER_TENANT_TOP_KEY) { // existing service owner is not specified owner(tenant) resobj.result = false; resobj.message = 'already existed service owner is tenant(' + value_tmp + '), it is not as same as specified owner tenant(' + tenant + ')'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } } } // // Check service key exists and create these. // subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_TOP_KEY, true)); if (k2hr3apiutil_1.default.tryAddStringToArray(subkeylist, keys.MASTER_SERVICE_KEY)) { if (!dkcobj.setSubkeys(keys.MASTER_SERVICE_TOP_KEY, subkeylist)) { // add subkey yrn:yahoo::::service:<service> -> yrn:yahoo::::service resobj.result = false; resobj.message = 'could not add ' + keys.MASTER_SERVICE_KEY + ' subkey under ' + keys.MASTER_SERVICE_TOP_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } // // Check owner/tenant/verify key in service key // subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true)); if (k2hr3apiutil_1.default.tryAddStringToArray(subkeylist, keys.SERVICE_OWNER_KEY)) { if (!dkcobj.setSubkeys(keys.MASTER_SERVICE_KEY, subkeylist)) { // add subkey yrn:yahoo::::service:<service>:owner -> yrn:yahoo::::service:<service> resobj.result = false; resobj.message = 'could not add ' + keys.SERVICE_OWNER_KEY + ' subkey under ' + keys.MASTER_SERVICE_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true)); if (k2hr3apiutil_1.default.tryAddStringToArray(subkeylist, keys.SERVICE_TENANT_KEY)) { if (!dkcobj.setSubkeys(keys.MASTER_SERVICE_KEY, subkeylist)) { // add subkey yrn:yahoo::::service:<service>:tenant -> yrn:yahoo::::service:<service> resobj.result = false; resobj.message = 'could not add ' + keys.SERVICE_TENANT_KEY + ' subkey under ' + keys.MASTER_SERVICE_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true)); if (k2hr3apiutil_1.default.tryAddStringToArray(subkeylist, keys.SERVICE_VERIFY_TENANT_KEY)) { if (!dkcobj.setSubkeys(keys.MASTER_SERVICE_KEY, subkeylist)) { // add subkey yrn:yahoo::::service:<service>:verify -> yrn:yahoo::::service:<service> resobj.result = false; resobj.message = 'could not add ' + keys.SERVICE_VERIFY_TENANT_KEY + ' subkey under ' + keys.MASTER_SERVICE_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } // // Update owner tenant key in service key // let value = dkcobj.getValue(keys.SERVICE_OWNER_KEY, null, true, null); if (!k2hr3apiutil_1.default.isSafeString(value)) { if (!dkcobj.setValue(keys.SERVICE_OWNER_KEY, keys.MASTER_TENANT_TOP_KEY)) { // update(set) value -> yrn:yahoo::::service:<service>:owner resobj.result = false; resobj.message = 'could not set ' + keys.MASTER_TENANT_TOP_KEY + ' value to ' + keys.SERVICE_OWNER_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } else if (value != keys.MASTER_TENANT_TOP_KEY) { resobj.result = false; resobj.message = 'could not set service owner tenant(' + keys.MASTER_TENANT_TOP_KEY + '), because it already set another tenant(' + JSON.stringify(value) + ')'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } // // Update tenant key in service's tenant list key // subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.SERVICE_TENANT_KEY, true)); if (k2hr3apiutil_1.default.tryAddStringToArray(subkeylist, keys.MASTER_TENANT_TOP_KEY)) { // add master tenant key to service's tenant list if (!dkcobj.setSubkeys(keys.SERVICE_TENANT_KEY, subkeylist)) { // add subkey yrn:yahoo:::<tenant> -> yrn:yahoo::::service:<service>:tenant resobj.result = false; resobj.message = 'could not add ' + keys.MASTER_TENANT_TOP_KEY + ' subkey under ' + keys.SERVICE_TENANT_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } // // Update service key to tenant's service list // subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(keys.TENANT_SERVICE_KEY, true)); if (k2hr3apiutil_1.default.tryAddStringToArray(subkeylist, keys.MASTER_SERVICE_KEY)) { // add tenant's service key to master tenant key if (!dkcobj.setSubkeys(keys.TENANT_SERVICE_KEY, subkeylist)) { // add subkey yrn:yahoo::::service:<service> -> yrn:yahoo:::<tenant>:service resobj.result = false; resobj.message = 'could not add ' + keys.MASTER_SERVICE_KEY + ' subkey under ' + keys.TENANT_SERVICE_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } // // Update verify/tenant key in service key // value = dkcobj.getValue(keys.SERVICE_VERIFY_TENANT_KEY, null, true, null); if (value != _verify) { if (!dkcobj.setValue(keys.SERVICE_VERIFY_TENANT_KEY, _verify)) { // update value verify -> yrn:yahoo::::service:<service>:verify resobj.result = false; resobj.message = 'could not set ' + _verify + ' value to ' + keys.SERVICE_VERIFY_TENANT_KEY + ' key'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } } dkcobj.clean(); return resobj; }; //--------------------------------------------------------- // check tenant is service owner //--------------------------------------------------------- // // Check tenant in service's owner // // tenant : tenant name // servicename : service name // const rawCheckTenantInServiceOwner = (dkcobj_permanent, tenant, service) => { if (!k2hr3apiutil_1.default.isPlainObject(dkcobj_permanent) || !dkcobj_permanent.isPermanent()) { dbglogging_1.default.elog('parameter dkcobj_permanent is not object or not permanent'); return false; } if (!k2hr3apiutil_1.default.isSafeString(tenant) || !k2hr3apiutil_1.default.isSafeString(service)) { dbglogging_1.default.elog('parameters are wrong : tenant=' + JSON.stringify(tenant) + ', service=' + JSON.stringify(service)); return false; } const cvt_tenant = tenant; // normalize tenant(if tenant is full yrn path, it should be tenant name) let keys = (0, k2hr3keys_1.getK2hr3Keys)(null, tenant, service); const yrnptn = new RegExp('^' + keys.MATCH_ANY_TENANT_MAIN); // regex = /^yrn:yahoo:(.*)::(.*)/ const matches = cvt_tenant.match(yrnptn); if (k2hr3apiutil_1.default.isNotEmptyArray(matches) && 3 <= matches.length) { if (!k2hr3apiutil_1.default.isSafeString(matches[2]) || !k2hr3apiutil_1.default.isSafeString(matches[2].trim())) { dbglogging_1.default.elog('parameters are wrong : tenant=' + JSON.stringify(cvt_tenant)); return false; } tenant = matches[2].trim(); keys = (0, k2hr3keys_1.getK2hr3Keys)(null, tenant, service); // remake } // // Check tenant is owner // const value = dkcobj_permanent.getValue(keys.SERVICE_OWNER_KEY, null, true, null); // check value in yrn:yahoo::::service:<service>:owner if (!k2hr3apiutil_1.default.isSafeString(value) || !k2hr3apiutil_1.default.compareCaseString(value, keys.MASTER_TENANT_TOP_KEY)) { dbglogging_1.default.dlog('tenant(' + keys.MASTER_TENANT_TOP_KEY + ') is not owner for service(' + keys.MASTER_SERVICE_KEY + ')'); return false; } return true; }; //--------------------------------------------------------- // Get service raw function //--------------------------------------------------------- // resTypeGetServiceAll = { // "result": true/false // "message": <error message> / null / undefined // "service": dkcTypeServiceRawValue = { // "name": <service name> // "owner": <owner tenant name> // "verify": <verify url> or <verify object> // "tenant": [<tenant yrn full path>, ...] // } // } // const rawGetServiceAll = (tenant, servicename) => { const resobj = { result: true, message: null }; if (!k2hr3apiutil_1.default.isSafeString(tenant) || !k2hr3apiutil_1.default.isSafeString(servicename)) { resobj.result = false; resobj.message = 'parameters are wrong : tenant=' + JSON.stringify(tenant) + ', service=' + JSON.stringify(servicename); dbglogging_1.default.elog(resobj.message); return resobj; } const dkcobj = (0, k2hdkc_1.default)(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean) if (!rawInitKeyHierarchy(dkcobj)) { resobj.result = false; resobj.message = 'Not initialize yet, or configuration is not set'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } // // Keys // const keys = (0, k2hr3keys_1.getK2hr3Keys)(null, tenant, servicename); const service_key = keys.MASTER_SERVICE_KEY; // "yrn:yahoo::::service:<service>" const owner_key = keys.SERVICE_OWNER_KEY; // "yrn:yahoo::::service:<service>:owner" const tenant_key = keys.SERVICE_TENANT_KEY; // "yrn:yahoo::::service:<service>:tenant" const verify_key = keys.SERVICE_VERIFY_TENANT_KEY; // "yrn:yahoo::::service:<service>:verify" // // Check service main key & children keys // let subkeylist = dkcobj.getSubkeys(service_key, true); // get subkey list in "yrn:yahoo::::service:<service>" if (!k2hr3apiutil_1.default.findStringInArray(subkeylist, owner_key) || !k2hr3apiutil_1.default.findStringInArray(subkeylist, tenant_key) || !k2hr3apiutil_1.default.findStringInArray(subkeylist, verify_key)) { resobj.result = false; resobj.message = owner_key + ' or ' + tenant_key + ' or ' + verify_key + ' are not found in ' + service_key + ' subkey list.'; dkcobj.clean(); return resobj; } // // Check tenant is owner // if (!rawCheckTenantInServiceOwner(dkcobj, tenant, servicename)) { resobj.result = false; resobj.message = 'tenant(' + tenant + ') is not owner for service(' + JSON.stringify(servicename) + ')'; dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } // // Get verify // const value = dkcobj.getValue(verify_key, null, true, null); // check value in yrn:yahoo::::service:<service>:verify if (!k2hr3apiutil_1.default.isSafeString(value)) { resobj.result = false; resobj.message = 'key(' + verify_key + ') does not have safe verify url nor JSON string : ' + JSON.stringify(value); dbglogging_1.default.elog(resobj.message); dkcobj.clean(); return resobj; } let service_verify; if (k2hr3apiutil_1.default.checkSimpleJSON(value)) { service_verify = JSON.parse(value); } else { service_verify = value; } // // Get tenant list // subkeylist = k2hr3apiutil_1.default.getSafeStringArray(dkcobj.getSubkeys(tenant_key, true)); // get subkey list in yrn:yahoo::::service:<service>:tenant let service_tenant = null; if (k2hr3apiutil_1.default.isNotEmptyArray(subkeylist)) { service_tenant = subkeylist; } // set policy key into result object const service_data = { name: servicename, owner: tenant, verify: service_verify, tenant: service_tenant }; resobj.service = service_data; dkcobj.clean(); return resobj; }; //--------------------------------------------------------- // Common remove tenant under service //--------------------------------------------------------- // t