scripts/lua/management/lib/tenants.lua (136 lines of code) (raw):

-- -- Licensed to the Apache Software Foundation (ASF) under one or more -- contributor license agreements. See the NOTICE file distributed with -- this work for additional information regarding copyright ownership. -- The ASF licenses this file to You under the Apache License, Version 2.0 -- (the "License"); you may not use this file except in compliance with -- the License. You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- --- @module tenants -- Management interface for tenants for the gateway local cjson = require "cjson" local utils = require "lib/utils" local request = require "lib/request" local apis = require "management/lib/apis" local _M = {}; function _M.addTenant(dataStore, decoded, existingTenant) -- Return tenant object local uuid = existingTenant ~= nil and existingTenant.id or utils.uuid() local tenantObj = { id = uuid, namespace = decoded.namespace, instance = decoded.instance } tenantObj = dataStore:addTenant(uuid, tenantObj) return cjson.decode(tenantObj) end --- Filter tenants based on query parameters -- @param tenants list of tenants -- @param queryParams query parameters to filter tenants local function filterTenants(tenants, queryParams) local namespace = queryParams['filter[where][namespace]'] local instance = queryParams['filter[where][instance]'] -- missing or invalid query parameters if (namespace == nil and instance == nil) or (instance ~= nil and namespace == nil) then return nil end -- filter tenants local tenantList = {} for k, v in pairs(tenants) do if k%2 == 0 then local tenant = cjson.decode(v) if (namespace ~= nil and instance == nil and tenant.namespace == namespace) or (namespace ~= nil and instance ~= nil and tenant.namespace == namespace and tenant.instance == instance) then tenantList[#tenantList+1] = tenant end end end return tenantList end --- Get all tenants in redis -- @param ds redis client -- @param queryParams object containing optional query parameters function _M.getAllTenants(dataStore, queryParams) local tenants = dataStore:getAllTenants() local tenantList if next(queryParams) ~= nil then tenantList = filterTenants(tenants, queryParams); end if tenantList == nil then tenantList = {} for k, v in pairs(tenants) do if k%2 == 0 then tenantList[#tenantList+1] = cjson.decode(v) end end end return tenantList end --- Get tenant by its id -- @param ds redis client -- @param id tenant id function _M.getTenant(dataStore, id) local tenant = dataStore:getTenant(id) if tenant == nil then request.err(404, utils.concatStrings({"Unknown tenant id ", id })) end return tenant end -- Apply paging on apis -- @param apis the list of apis -- @param queryparams object containing optional query parameters local function applyPagingToAPIs(apiList, queryParams) local skip = queryParams['skip'] == nil and 1 or queryParams['skip'] local limit = queryParams['limit'] == nil and table.getn(apiList) or queryParams['limit'] skip = tonumber(skip) limit = tonumber(limit) if (limit == nil or limit < 1) then return {} end if (skip == nil or skip <= 0) then skip = 1 else skip = skip + 1 end if ((skip + limit - 1) > table.getn(apiList)) then limit = table.getn(apiList) else limit = skip + limit - 1 end local apis_obj = {} local idx = 0 for i = skip, limit do apis_obj[idx] = apiList[i] idx = idx + 1 end return apis_obj end --- Filter apis based on query parameters -- @param queryParams query parameters to filter apis local function filterTenantAPIs(id, apis_obj, queryParams) local basePath = queryParams['filter[where][basePath]'] basePath = basePath == nil and queryParams['basePath'] or basePath local name = queryParams['filter[where][name]'] name = name == nil and queryParams['title'] or name -- missing query parameters if (basePath == nil and name == nil)then return nil end -- filter apis local apiList = {} for k, v in pairs(apis_obj) do if k%2 == 0 then local api = cjson.decode(v) if api.tenantId == id and ((basePath ~= nil and name == nil and api.basePath == basePath) or (name ~= nil and basePath == nil and api.name == name) or (basePath ~= nil and name ~= nil and api.basePath == basePath and api.name == name)) then apiList[#apiList+1] = api end end end return apiList end --- Get APIs associated with tenant -- @param ds redis client -- @param id tenant id -- @param queryParams object containing optional query parameters function _M.getTenantAPIs(dataStore, id, queryParams) local apis_obj = dataStore:getAllAPIs() local apiList if next(queryParams) ~= nil then apiList = filterTenantAPIs(id, apis_obj, queryParams); end if apiList == nil then apiList = {} for k, v in pairs(apis_obj) do if k%2 == 0 then local decoded = cjson.decode(v) if decoded.tenantId == id then apiList[#apiList+1] = decoded end end end end if (((queryParams['skip'] == nil or queryParams['skip'] == 'undefined') and (queryParams['limit'] == nil or queryParams['limit'] == 'undefined')) or table.getn(apiList) == 0) then return apiList else return applyPagingToAPIs(apiList, queryParams) end end --- Delete tenant from gateway -- @param ds redis client -- @param id id of tenant to delete function _M.deleteTenant(dataStore, id) local tenantAPIs = _M.getTenantAPIs(dataStore, id, {}) for _, v in pairs(tenantAPIs) do apis.deleteAPI(dataStore, v.id) end dataStore:deleteTenant(id) return {} end return _M