k2hr3-api
Version:
K2HR3 REST API is K2hdkc based Resource and Roles and policy Rules
1,326 lines (1,230 loc) • 485 kB
JavaScript
/*
* 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:
*
*/
'use strict';
var k2hdkc = require('k2hdkc');
var apiutil = require('./k2hr3apiutil');
var r3keys = require('./k2hr3keys').getK2hr3Keys;
var r3token = require('./k2hr3tokens');
var acrutil = require('./k2hr3acrutil');
var r3templeng = require('./k2hr3template');
var r3Conf = require('./k2hr3config').r3ApiConfig;
var apiConf = new r3Conf();
// Debug logging objects
var r3logger = require('./dbglogging');
//---------------------------------------------------------
// Configuration and port number from Environment
//---------------------------------------------------------
var dkcconf = null;
var dkcport = null;
var dkccuk = null;
(function()
{
if(!apiutil.isSafeEntity(dkcconf)){
var tmpdkcconf = apiConf.getK2hdkcConfig();
if(!apiutil.checkFileExist(tmpdkcconf)){
r3logger.elog('k2hdkc slave configuration file(' + tmpdkcconf + ') specified in config json does not exist, then try to check K2HDKC_SLAVE_CONF environemnt.');
tmpdkcconf = apiutil.getSafeString(process.env.K2HDKC_SLAVE_CONF);
if(!apiutil.checkFileExist(tmpdkcconf)){
r3logger.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(!apiutil.isSafeEntity(dkcport)){
var tmpdkcport = apiConf.getK2hdkcPort();
if(isNaN(tmpdkcport) || null === tmpdkcport){
r3logger.elog('k2hdkc slave port number(' + JSON.stringify(tmpdkcport) + ') specified in config json is something wrong, then try to check K2HDKC_SLAVE_PORT environemnt.');
tmpdkcport = apiutil.getSafeString(process.env.K2HDKC_SLAVE_PORT);
if(!apiutil.isSafeString(tmpdkcport) || isNaN(tmpdkcport)){
r3logger.elog('k2hdkc slave port number(' + JSON.stringify(tmpdkcport) + ') specified by K2HDKC_SLAVE_PORT environment is something wrong, then use default port number(8031).');
tmpdkcport = 8031;
}
}
dkcport = parseInt(tmpdkcport);
}
if(!apiutil.isSafeEntity(dkccuk)){
var tmpdkccuk = apiConf.getK2hdkcCuk();
if(null === tmpdkccuk){
r3logger.mlog('k2hdkc slave cuk is not specified. then try to check K2HDKC_SLAVE_CUK environemnt.');
tmpdkccuk = apiutil.getSafeString(process.env.K2HDKC_SLAVE_CUK);
if(!apiutil.isSafeString(tmpdkccuk)){
r3logger.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
//---------------------------------------------------------
var is_allow_dummy_tenant = !(apiConf.isConfirmTenantForService());
//---------------------------------------------------------
// Normalization host information
//---------------------------------------------------------
//
// input_info : input is allow following
// (1) string = ip address or hostname
// (2) object = {
// 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)
// }
// (3) array = [ object, object, ...]
//
// result : result is following, this array can be specified by rawCreateRole()
// [
// {
// 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)
// },
// ....
// ]
//
// [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.
//
function getSafeHosts(input_info)
{
var result = new Array(0);
if(!apiutil.isSafeEntity(input_info)){
return result;
}
var ipaddr = null;
var hostname= null;
var portnum = 0;
var cuk = null;
var extra = null;
var tag = null;
if(input_info instanceof Object){
if(input_info instanceof Array){
// A case of array
for(var cnt = 0; cnt < input_info.length; ++cnt){
// reentrant
var tmp = getSafeHosts(input_info[cnt]);
result = result.concat(tmp);
}
}else{
var host_info;
// A case of object
if(apiutil.isSafeString(input_info.ip) && apiutil.isIpAddressString(input_info.ip)){
ipaddr = input_info.ip;
}
if(apiutil.isSafeString(input_info.hostname)){
hostname= input_info.hostname;
}
if(apiutil.isSafeEntity(input_info.port) && !isNaN(input_info.port)){
portnum = input_info.port;
}
if(apiutil.isSafeString(input_info.cuk)){
cuk = input_info.cuk;
}
if(apiutil.isSafeString(input_info.extra)){
extra = input_info.extra;
}
if(apiutil.isSafeString(input_info.tag)){
tag = input_info.tag;
}
// add to array(if hostname and ip address is existed, push two array)
if(apiutil.isSafeString(ipaddr)){
host_info = {ip: ipaddr, hostname: null, port: portnum, cuk: cuk, extra: extra, tag: tag};
}
if(apiutil.isSafeString(hostname)){
host_info = {ip: null, hostname: hostname, port: portnum, cuk: cuk, extra: extra, tag: tag};
}
// optional keys
if(apiutil.isSafeString(input_info.inboundip) && apiutil.isIpAddressString(input_info.inboundip)){
host_info.inboundip = input_info.inboundip;
}
if(apiutil.isSafeString(input_info.outboundip) && apiutil.isIpAddressString(input_info.outboundip)){
host_info.outboundip = input_info.outboundip;
}
result.push(host_info);
}
}else{
// A case of one host name(or ip address)
if(apiutil.isIpAddressString(input_info)){
ipaddr = input_info;
}else{
hostname= input_info;
}
result.push({ip: ipaddr, hostname: hostname, port: portnum, cuk: cuk, extra: extra, tag: tag});
}
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)
//
function rawIncDecReferenceCount(dkcobj_permanent, fullyrn, increment)
{
var resobj = {result: true, message: null};
if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
resobj.result = false;
resobj.message = 'parameter dkcobj_permanent is not object or not permanent';
r3logger.elog(resobj.message);
return resobj;
}
if(!apiutil.isSafeString(fullyrn)){
resobj.result = false;
resobj.message = 'some parameters aree wrong : fullyrn=' + JSON.stringify(fullyrn) + ', increment=' + JSON.stringify(increment);
r3logger.elog(resobj.message);
return resobj;
}
if('boolean' !== typeof increment){
resobj.result = false;
resobj.message = 'some parameters aree wrong : fullyrn=' + JSON.stringify(fullyrn) + ', increment=' + JSON.stringify(increment);
r3logger.elog(resobj.message);
return resobj;
}
//
// keys
//
var keys = r3keys();
var reference_key = fullyrn + '/' + keys.REFERENCE_KW;
// check fullyrn key
var subkeylist = dkcobj_permanent.getSubkeys(fullyrn, true);
if(!apiutil.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';
r3logger.elog(resobj.message);
}else{
r3logger.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 + ')';
r3logger.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/..."]
//
function rawCreateKeyTree(dkcobj_permanent, parent_key, keys, allow_empty_key)
{
if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
return false;
}
if(!apiutil.isSafeString(parent_key)){
r3logger.elog('parameters are wrong : parent_key=' + JSON.stringify(parent_key));
return false;
}
// build hierarchy array
var hierarchy = apiutil.expandHierarchy(parent_key, keys, '/', allow_empty_key);
if(null === hierarchy){
r3logger.elog('could not expand hierarchy array for parent and children.');
return false;
}
// loop for creating subkey in parent
for(var parent in hierarchy){
if(apiutil.isEmptyArray(hierarchy[parent])){
r3logger.wlog('parent key(' + parent + ') does not have new subkeys');
continue;
}
// get parent's subkeys
var subkeylist = dkcobj_permanent.getSubkeys(parent, true);
if(apiutil.isEmptyArray(subkeylist)){
subkeylist = new Array(0);
}
// check new subkey
var is_cahnged = false;
for(var cnt = 0; cnt < hierarchy[parent].length; ++cnt){
if(!apiutil.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
r3logger.elog('could not add ' + JSON.stringify(subkeylist) + ' under ' + parent + ' key');
return false;
}
}
}
return true;
}
//---------------------------------------------------------
// Small utility for tenant name
//---------------------------------------------------------
function rawGetKeysFromResourceKey(user, resource_key)
{
var keys = r3keys(user);
// make resource name from resource yrn path
var nameptn = new RegExp('^' + keys.MATCH_ANY_TENANT_RESOURCE); // regex = /^yrn:yahoo:(.*)::(.*):resource:(.*)/
var namematches = resource_key.match(nameptn);
if(apiutil.isEmptyArray(namematches) || namematches.length < 4 || !apiutil.isSafeString(namematches[2])){
// res_yrn is not full yrn to resource
return keys;
}
var service = namematches[1];
if(!apiutil.isSafeString(service)){
service = null;
}
return r3keys(user, namematches[2], service);
}
//---------------------------------------------------------
// initialize k2hdkc data
//---------------------------------------------------------
//
// global flag for all keys up in k2hdkc
//
var is_init_key_hierarchy = false;
function rawInitKeyHierarchy(dkcobj_permanent)
{
if(is_init_key_hierarchy){
return true;
}
var dkcobj = dkcobj_permanent;
var need_clean = false;
if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
if(null === dkcconf || null === dkcport){
r3logger.elog('Configuration is not set.');
return false;
}
need_clean = true;
dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
}
var keys = r3keys();
//
// Check top key "yrn" exists.
//
var subkeylist = dkcobj.getSubkeys(keys.YRN_KEY, true);
if(subkeylist instanceof Array && 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
r3logger.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
r3logger.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>
r3logger.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>
r3logger.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>
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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
r3logger.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:
r3logger.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
r3logger.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.
//
function rawCreateService(tenant, servicename, verify)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeStrings(tenant, servicename)){
resobj.result = false;
resobj.message = 'parameters are wrong : tenant=' + JSON.stringify(tenant) + ', service=' + JSON.stringify(servicename);
r3logger.elog(resobj.message);
return resobj;
}
if(!apiutil.isSafeEntity(verify)){
verify = JSON.stringify(null); // default null
}else if(apiutil.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
//
}else if(!apiutil.isSafeString(verify)){
// allow any object
verify = JSON.stringify(verify); // formatted JSON
}
var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
var keys = r3keys(null, tenant, servicename);
var subkeylist;
var value;
if(!rawInitKeyHierarchy(dkcobj)){
resobj.result = false;
resobj.message = 'Not initialize yet, or configuration is not set';
r3logger.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.';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
//
// Check service key exists and owner
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_TOP_KEY, true));
if(apiutil.findStringInArray(subkeylist, keys.MASTER_SERVICE_KEY)){ // check subkey yrn:yahoo::::service:<service> -> yrn:yahoo::::service
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true));
if(apiutil.findStringInArray(subkeylist, keys.SERVICE_OWNER_KEY)){ // check subkey yrn:yahoo::::service:<service>:owner -> yrn:yahoo::::service:<service>
value = dkcobj.getValue(keys.SERVICE_OWNER_KEY, null, true, null); // get value -> yrn:yahoo::::service:<service>:owner
if(apiutil.isSafeString(value)){
if(value != 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 + '), it is not as same as specified owner tenant(' + tenant + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
}
}
//
// Check service key exists and create these.
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_TOP_KEY, true));
if(apiutil.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';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
//
// Check owner/tenant/verify key in service key
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true));
if(apiutil.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';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true));
if(apiutil.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';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_KEY, true));
if(apiutil.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';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
//
// Update owner tenant key in service key
//
value = dkcobj.getValue(keys.SERVICE_OWNER_KEY, null, true, null);
if(!apiutil.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';
r3logger.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) + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
//
// Update tenant key in service's tenant list key
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.SERVICE_TENANT_KEY, true));
if(apiutil.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';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
//
// Update service key to tenant's service list
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.TENANT_SERVICE_KEY, true));
if(apiutil.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';
r3logger.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 ' + JSON.stringify(verify) + ' value to ' + keys.SERVICE_VERIFY_TENANT_KEY + ' key';
r3logger.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
//
function rawCheckTenantInServiceOwner(dkcobj_permanent, tenant, service)
{
if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
return false;
}
if(!apiutil.isSafeStrings(tenant, service)){
r3logger.elog('parameters are wrong : tenant=' + JSON.stringify(tenant) + ', service=' + JSON.stringify(service));
return false;
}
// normalize tenant(if tenant is full yrn path, it should be tenant name)
var keys = r3keys(null, tenant, service);
var value;
var yrnptn = new RegExp('^' + keys.MATCH_ANY_TENANT_MAIN); // regex = /^yrn:yahoo:(.*)::(.*)/
var matches = tenant.match(yrnptn);
if(!apiutil.isEmptyArray(matches) && 3 <= matches.length){
if(!apiutil.isSafeString(matches[2]) || !apiutil.isSafeString(matches[2].trim())){
r3logger.elog('parameters are wrong : tenant=' + JSON.stringify(tenant));
return false;
}
tenant = matches[2].trim();
keys = r3keys(null, tenant, service); // remake
}
//
// Check tenant is owner
//
value = dkcobj_permanent.getValue(keys.SERVICE_OWNER_KEY, null, true, null); // check value in yrn:yahoo::::service:<service>:owner
if(!apiutil.isSafeString(value) || !apiutil.compareCaseString(value, keys.MASTER_TENANT_TOP_KEY)){
r3logger.dlog('tenant(' + keys.MASTER_TENANT_TOP_KEY + ') is not owner for service(' + keys.MASTER_SERVICE_KEY + ')');
return false;
}
return true;
}
//---------------------------------------------------------
// Get service raw function
//---------------------------------------------------------
// return object
// {
// "result": true/false
// "message": <error message> / null / undefined
// "service": {
// "name": <service name>
// "owner": <owner tenant name>
// "verify": <verify url> or <verify object>
// "tenant": [<tenant yrn full path>, ...]
// }
// }
//
function rawGetServiceAll(tenant, servicename)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeStrings(tenant, servicename)){
resobj.result = false;
resobj.message = 'parameters are wrong : tenant=' + JSON.stringify(tenant) + ', service=' + JSON.stringify(servicename);
r3logger.elog(resobj.message);
return resobj;
}
var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
var subkeylist;
var value;
if(!rawInitKeyHierarchy(dkcobj)){
resobj.result = false;
resobj.message = 'Not initialize yet, or configuration is not set';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
//
// Keys
//
var keys = r3keys(null, tenant, servicename);
var service_key = keys.MASTER_SERVICE_KEY; // "yrn:yahoo::::service:<service>"
var owner_key = keys.SERVICE_OWNER_KEY; // "yrn:yahoo::::service:<service>:owner"
var tenant_key = keys.SERVICE_TENANT_KEY; // "yrn:yahoo::::service:<service>:tenant"
var verify_key = keys.SERVICE_VERIFY_TENANT_KEY; // "yrn:yahoo::::service:<service>:verify"
var service_data = {};
//
// Check service main key & children keys
//
subkeylist = dkcobj.getSubkeys(service_key, true); // get subkey list in "yrn:yahoo::::service:<service>"
if( !apiutil.findStringInArray(subkeylist, owner_key) ||
!apiutil.findStringInArray(subkeylist, tenant_key) ||
!apiutil.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;
}
service_data.name = servicename;
//
// Check tenant is owner
//
if(!rawCheckTenantInServiceOwner(dkcobj, tenant, servicename)){
resobj.result = false;
resobj.message = 'tenant(' + tenant + ') is not owner for service(' + servicename + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
service_data.owner = tenant;
//
// Get verify
//
value = dkcobj.getValue(verify_key, null, true, null); // check value in yrn:yahoo::::service:<service>:verify
if(!apiutil.isSafeString(value)){
resobj.result = false;
resobj.message = 'key(' + verify_key + ') does not have safe verify url nor JSON string : ' + JSON.stringify(value);
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
if(apiutil.checkSimpleJSON(value)){
service_data.verify = JSON.parse(value);
}else{
service_data.verify = value;
}
//
// Get tenant list
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(tenant_key, true)); // get subkey list in yrn:yahoo::::service:<service>:tenant
if(!apiutil.isEmptyArray(subkeylist)){
service_data.tenant = subkeylist;
}else{
service_data.tenant = null;
}
// set policy key into result object
resobj.service = service_data;
dkcobj.clean();
return resobj;
}
//---------------------------------------------------------
// Remove service raw function
//---------------------------------------------------------
function rawRemoveServiceAll(tenant, servicename)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeStrings(tenant, servicename)){
resobj.result = false;
resobj.message = 'parameters are wrong : tenant=' + JSON.stringify(tenant) + ', service=' + JSON.stringify(servicename);
r3logger.elog(resobj.message);
return resobj;
}
var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
var subkeylist;
var cnt;
if(!rawInitKeyHierarchy(dkcobj)){
resobj.result = false;
resobj.message = 'Not initialize yet, or configuration is not set';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
//
// Keys
//
var keys = r3keys(null, tenant, servicename);
var service_key = keys.MASTER_SERVICE_KEY; // "yrn:yahoo::::service:<service>"
var owner_key = keys.SERVICE_OWNER_KEY; // "yrn:yahoo::::service:<service>:owner"
var tenant_key = keys.SERVICE_TENANT_KEY; // "yrn:yahoo::::service:<service>:tenant"
var verify_key = keys.SERVICE_VERIFY_TENANT_KEY; // "yrn:yahoo::::service:<service>:verify"
//
// Check tenant is owner
//
if(!rawCheckTenantInServiceOwner(dkcobj, tenant, servicename)){
resobj.result = false;
resobj.message = 'tenant(' + tenant + ') is not owner for service(' + servicename + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
//
// Get tenant list
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(tenant_key, true)); // get subkey list in yrn:yahoo::::service:<service>:tenant
if(!apiutil.isEmptyArray(subkeylist)){
var tenantlist = subkeylist;
for(cnt = 0; cnt < tenantlist.length; ++cnt){
//
// Create related key
//
var yrnptn = new RegExp('^' + keys.MATCH_ANY_TENANT_MAIN); // regex = /^yrn:yahoo:(.*)::(.*)/
var matches = tenantlist[cnt].match(yrnptn);
if(apiutil.isEmptyArray(matches) || matches.length < 3){
r3logger.elog('tenant(' + tenantlist[cnt] + ') in service tenant list is something wrong, then skip this.');
continue;
}
var servicetenant = matches[2]; // tenant name under service's tenant
var tenant_service_key = tenantlist[cnt] + ':' + keys.SERVICE_KW; // "yrn:yahoo::::service:<service>"
var is_owner_service_tenant = apiutil.compareCaseString(keys.MASTER_TENANT_TOP_KEY, tenantlist[cnt]);
//
// Remove service key from all tenant member's service list
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(tenant_service_key, true)); // remove subkey "yrn:yahoo::::service:<service>" -> "yrn:yahoo:::<tenant>:service"
if(apiutil.removeStringFromArray(subkeylist, service_key)){
if(!dkcobj.setSubkeys(tenant_service_key, subkeylist)){ // reset new service list -> yrn:yahoo:::<tenant>:service
resobj.result = false;
resobj.message = 'could not set new(removed service) list under ' + keys.TENANT_SERVICE_KEY + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
//
// Remove service + tenant
//
if(!rawRemoveServiceTenantEx(dkcobj, servicetenant, servicename, !is_owner_service_tenant)){
resobj.result = false;
resobj.message = 'could not remove subkeys(role/policy/resources) under service(' + JSON.stringify(servicename) + ') and tenant(' + JSON.stringify(servicetenant) + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
}
//
// Remove service name in anytenant key
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.ANYTENANT_SERVICE_KEY, true)); // get subkey list in yrn:yahoo::::service::anytenant
if(apiutil.removeStringFromArray(subkeylist, service_key)){
if(!dkcobj.setSubkeys(keys.ANYTENANT_SERVICE_KEY, subkeylist)){ // reset new service list -> yrn:yahoo::::service::anytenant
resobj.result = false;
resobj.message = 'could not set new(removed service) list under ' + keys.ANYTENANT_SERVICE_KEY + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
//
// Remove verify/owner/tenant under service key
//
if(!dkcobj.remove(tenant_key, false)){ // remove "yrn:yahoo::::service:<service>:tenant"
r3logger.elog('could not remove ' + tenant_key + 'key, probably it is not existed.');
}
if(!dkcobj.remove(verify_key, false)){ // remove "yrn:yahoo::::service:<service>:verify"
r3logger.elog('could not remove ' + verify_key + 'key, probably it is not existed.');
}
if(!dkcobj.remove(owner_key, false)){ // remove "yrn:yahoo::::service:<service>:owner"
r3logger.elog('could not remove ' + owner_key + 'key, probably it is not existed.');
}
//
// Remove service key
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_TOP_KEY, true));// get subkey list in yrn:yahoo::::service
if(apiutil.removeStringFromArray(subkeylist, service_key)){
if(!dkcobj.setSubkeys(keys.MASTER_SERVICE_TOP_KEY, subkeylist)){ // reset new service list -> yrn:yahoo::::service
resobj.result = false;
resobj.message = 'could not set new(removed service) list under ' + keys.MASTER_SERVICE_TOP_KEY + ' key';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
}
if(!dkcobj.remove(service_key, false)){ // remove "yrn:yahoo::::service:<service>"
r3logger.elog('could not remove ' + service_key + 'key, probably it is not existed.');
}
dkcobj.clean();
return resobj;
}
//---------------------------------------------------------
// raw allow tenant to service
//---------------------------------------------------------
//
// Raw function for adding Service member tenants
//
// ownertenant : service owner tenant name
// servicename : service name
// tenantname : tenant name
//
function rawAllowTenantToServiceEx(dkcobj_permanent, ownertenant, servicename, tenantname)
{
if(!(dkcobj_permanent instanceof Object) || !dkcobj_permanent.isPermanent()){
r3logger.elog('parameter dkcobj_permanent is not object or not permanent');
return false;
}
if(!apiutil.isSafeStrings(ownertenant, servicename, tenantname)){
r3logger.elog('parameters are wrong : ownertenant=' + JSON.stringify(ownertenant) + ', service=' + JSON.stringify(servicename) + ' tenant=' + JSON.stringify(tenantname));
return false;
}
var keys = r3keys(null, tenantname, servicename);
var subkeylist;
//
// Check service key/owner key/tenant key exists.
//
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.MASTER_SERVICE_TOP_KEY, true));
if(!apiutil.findStringInArray(subkeylist, keys.MASTER_SERVICE_KEY)){ // check subkey yrn:yahoo::::service:<service> -> yrn:yahoo::::service
// not found master service key in master service top key.
r3logger.elog('Not found ' + keys.MASTER_SERVICE_KEY + ' subkey under ' + keys.MASTER_SERVICE_TOP_KEY + ' key(there is no master service key)');
return false;
}
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.MASTER_SERVICE_KEY, true));
if(!apiutil.findStringInArray(subkeylist, keys.SERVICE_OWNER_KEY)){ // check subkey yrn:yahoo::::service:<service>:owner -> yrn:yahoo::::service:<service>
// not found owner key in master service key.
r3logger.elog('Not found ' + keys.SERVICE_OWNER_KEY + ' subkey under ' + keys.MASTER_SERVICE_KEY + ' key(there is no owner key in master service key)');
return false;
}
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.MASTER_SERVICE_KEY, true));
if(!apiutil.findStringInArray(subkeylist, keys.SERVICE_TENANT_KEY)){ // check subkey yrn:yahoo::::service:<service>:tenant -> yrn:yahoo::::service:<service>
// not found tenant top key in master service key.
r3logger.elog('Not found ' + keys.SERVICE_TENANT_KEY + ' subkey under ' + keys.MASTER_SERVICE_KEY + ' key(there is no tenant key in master service key)');
return false;
}
//
// Check tenant is owner
//
if(!rawCheckTenantInServiceOwner(dkcobj_permanent, ownertenant, servicename)){
r3logger.elog('tenant(' + ownertenant + ') is not owner for service(' + servicename + ')');
return false;
}
//
// Check tenant key exists.
//
var is_any_tenant = (keys.VALUE_WILDCARD === tenantname ? true : false);
if(!is_any_tenant){
// case for not any tenant
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.NO_SERVICE_REGION_KEY, true));
if(!apiutil.findStringInArray(subkeylist, keys.MASTER_TENANT_TOP_KEY)){ // check subkey yrn:yahoo:::<tenant> -> yrn:yahoo::
// not found tenant
if(is_allow_dummy_tenant){
// [NOTE]
// Allow addition of unregistered tenant as service member.
// Unregistered tenants are temporarily registered here.
// The temporarily registered tenant is officially registered
// when the tenant owner user accesses it.
//
r3logger.dlog('Not found ' + keys.MASTER_TENANT_TOP_KEY + ' subkey under ' + keys.NO_SERVICE_REGION_KEY + ' key. It should be existed before adding it into master service key, but it tries to create it temporary.');
if(!rawCreateTenantTemporary(dkcobj_permanent, tenantname)){
r3logger.elog('Could not register tenant(' + tenantname + ') as temporary for service(' + servicename + ').');
return false;
}
}else{
r3logger.elog('Not found ' + keys.MASTER_TENANT_TOP_KEY + ' subkey under ' + keys.NO_SERVICE_REGION_KEY + ' key. It should be existed before adding it into master service key.');
return false;
}
}
}
//
// Add tenant key in service's tenant list key
//
var add_tenant_key = (is_any_tenant ? keys.VALUE_WILDCARD : keys.MASTER_TENANT_TOP_KEY);
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.SERVICE_TENANT_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, add_tenant_key)){
// add master tenant key to service's tenant list
if(!dkcobj_permanent.setSubkeys(keys.SERVICE_TENANT_KEY, subkeylist)){ // add subkey yrn:yahoo:::<tenant> or '*' -> yrn:yahoo::::service:<service>:tenant
r3logger.elog('could not add ' + add_tenant_key + ' subkey under ' + keys.SERVICE_TENANT_KEY + ' key');
return false;
}
}
//
// Add service key to tenant's service list
//
if(!is_any_tenant){
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.MASTER_TENANT_TOP_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, keys.TENANT_SERVICE_KEY)){
// add tenant's service key to master tenant key
if(!dkcobj_permanent.setSubkeys(keys.MASTER_TENANT_TOP_KEY, subkeylist)){ // add subkey yrn:yahoo:::<tenant>:service -> yrn:yahoo::::service:<service>
r3logger.elog('could not add ' + keys.TENANT_SERVICE_KEY + ' subkey under ' + keys.MASTER_TENANT_TOP_KEY + ' key');
return false;
}
}
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.TENANT_SERVICE_KEY, true));
if(apiutil.tryAddStringToArray(subkeylist, keys.MASTER_SERVICE_KEY)){
// add tenant's service key to master tenant key
if(!dkcobj_permanent.setSubkeys(keys.TENANT_SERVICE_KEY, subkeylist)){ // add subkey yrn:yahoo::::service:<service> -> yrn:yahoo:::<tenant>:service
r3logger.elog('could not add ' + keys.MASTER_SERVICE_KEY + ' subkey under ' + keys.TENANT_SERVICE_KEY + ' key');
return false;
}
}
}else{
//
// If allow any tenant, we set service path into anytenant.
//
subkeylist = apiutil.getSafeArray(dkcobj_permanent.getSubkeys(keys.ANYTENANT_SERVICE_KEY, true)); // get subkey list in yrn:yahoo::::service::anytenant
if(apiutil.tryAddStringToArray(subkeylist, keys.MASTER_SERVICE_KEY)){
if(!dkcobj_permanent.setSubkeys(keys.ANYTENANT_SERVICE_KEY, subkeylist)){ // set service path -> yrn:yahoo::::service::anytenant
r3logger.elog('could not add subkey(' + keys.MASTER_SERVICE_KEY + ') to ' + keys.ANYTENANT_SERVICE_KEY + ' key');
return false;
}
}
}
return true;
}
//---------------------------------------------------------
// allow tenant to service
//---------------------------------------------------------
//
// Add Service member tenants
//
// ownertenant : service owner tenant name
// servicename : service name
// tenantname : tenant name(any tenant string or '*')
//
// [NOTE]
// Must create tenant and service keys before calling this function.
//
function rawAllowTenantToService(ownertenant, servicename, tenantname)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeStrings(ownertenant, servicename, tenantname)){
resobj.result = false;
resobj.message = 'parameters are wrong : ownertenant=' + JSON.stringify(ownertenant) + ', service=' + JSON.stringify(servicename) + ' tenant=' + JSON.stringify(tenantname);
r3logger.elog(resobj.message);
return resobj;
}
var dkcobj = k2hdkc(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';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
// Add tenant to allowed list
if(!rawAllowTenantToServiceEx(dkcobj, ownertenant, servicename, tenantname)){
resobj.result = false;
resobj.message = 'could not set tenant(' + tenantname + ') to service(' + servicename + ') member which is owner(' + ownertenant + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
dkcobj.clean();
return resobj;
}
//---------------------------------------------------------
// deny tenant from service
//---------------------------------------------------------
//
// Deny(delete) Service member tenants
//
// ownertenant : service owner tenant name
// servicename : service name
// tenantname : tenant name(any tenant string or '*')
//
// [NOTE]
// Must create tenant and service keys before calling this function.
//
function rawDenyTenantFromService(ownertenant, servicename, tenantname)
{
var resobj = {result: true, message: null};
if(!apiutil.isSafeStrings(ownertenant, servicename, tenantname)){
resobj.result = false;
resobj.message = 'parameters are wrong : ownertenant=' + JSON.stringify(ownertenant) + ', service=' + JSON.stringify(servicename) + ' tenant=' + JSON.stringify(tenantname);
r3logger.elog(resobj.message);
return resobj;
}
var dkcobj = k2hdkc(dkcconf, dkcport, dkccuk, true, false); // use permanent object(need to clean)
var keys = r3keys(null, tenantname, servicename);
var ownerkeys = r3keys(null, ownertenant, null);
var subkeylist;
if(!rawInitKeyHierarchy(dkcobj)){
resobj.result = false;
resobj.message = 'Not initialize yet, or configuration is not set';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
//
// Check removing service+tenant is under owner tenant
//
var is_owner_service_tenant = false;
if(ownerkeys.MASTER_TENANT_TOP_KEY === keys.MASTER_TENANT_TOP_KEY){
is_owner_service_tenant = true;
}
//
// Check tenant is owner
//
if(!rawCheckTenantInServiceOwner(dkcobj, ownertenant, servicename)){
resobj.result = false;
resobj.message = 'tenant(' + ownertenant + ') is not owner for service(' + servicename + ')';
r3logger.elog(resobj.message);
dkcobj.clean();
return resobj;
}
//
// Check service key/owner key/tenant key exists.
//
subkeylist = apiutil.getSafeArray(dkcobj.getSubkeys(keys.MASTER_SERVICE_TOP_KEY, true));
if(!apiutil.findStringInArray(subkeylist, keys.MASTER_SERVICE_KEY)){ // check subkey yrn:yahoo::::service:<service> -> yrn:yahoo::::service
// not found master service key in master service top key.
resobj.result = false;
resobj.m