blob: 405e80141401a7818555880abdf00215cbb8b3fd [file] [log] [blame]
#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import logging
from apache_ranger.exceptions import RangerServiceException
from apache_ranger.model.ranger_base import RangerBase, PList
from apache_ranger.model.ranger_policy import RangerPolicy
from apache_ranger.model.ranger_role import RangerRole
from apache_ranger.model.ranger_security_zone import RangerSecurityZone, RangerSecurityZoneV2, RangerSecurityZoneHeaderInfo, RangerSecurityZoneResource
from apache_ranger.model.ranger_service import RangerService, RangerServiceHeaderInfo
from apache_ranger.model.ranger_service_def import RangerServiceDef
from apache_ranger.model.ranger_service_tags import RangerServiceTags
from apache_ranger.utils import *
from requests import Session
from requests import Response
from requests.auth import AuthBase
from urllib.parse import urlencode
from urllib.parse import urljoin
LOG = logging.getLogger(__name__)
QUERY_PARAM_USER_DOT_NAME = 'user.name'.encode("utf-8")
class RangerClient:
def __init__(self, url, auth, query_params=None, headers=None):
self.client_http = RangerClientHttp(url, auth, query_params, headers)
self.session = self.client_http.session
logging.getLogger("requests").setLevel(logging.WARNING)
# Service Definition APIs
def create_service_def(self, serviceDef):
resp = self.client_http.call_api(RangerClient.CREATE_SERVICEDEF, request_data=serviceDef)
return type_coerce(resp, RangerServiceDef)
def update_service_def_by_id(self, serviceDefId, serviceDef):
resp = self.client_http.call_api(RangerClient.UPDATE_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }), request_data=serviceDef)
return type_coerce(resp, RangerServiceDef)
def update_service_def(self, serviceDefName, serviceDef):
resp = self.client_http.call_api(RangerClient.UPDATE_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }), request_data=serviceDef)
return type_coerce(resp, RangerServiceDef)
def delete_service_def_by_id(self, serviceDefId, params=None):
self.client_http.call_api(RangerClient.DELETE_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }), params)
def delete_service_def(self, serviceDefName, params=None):
self.client_http.call_api(RangerClient.DELETE_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }), params)
def get_service_def_by_id(self, serviceDefId):
resp = self.client_http.call_api(RangerClient.GET_SERVICEDEF_BY_ID.format_path({ 'id': serviceDefId }))
return type_coerce(resp, RangerServiceDef)
def get_service_def(self, serviceDefName):
resp = self.client_http.call_api(RangerClient.GET_SERVICEDEF_BY_NAME.format_path({ 'name': serviceDefName }))
return type_coerce(resp, RangerServiceDef)
def find_service_defs(self, filter=None):
resp = self.client_http.call_api(RangerClient.FIND_SERVICEDEFS, filter)
return type_coerce_list(resp, RangerServiceDef)
# Service APIs
def create_service(self, service):
resp = self.client_http.call_api(RangerClient.CREATE_SERVICE, request_data=service)
return type_coerce(resp, RangerService)
def get_service_by_id(self, serviceId):
resp = self.client_http.call_api(RangerClient.GET_SERVICE_BY_ID.format_path({ 'id': serviceId }))
return type_coerce(resp, RangerService)
def get_service(self, serviceName):
resp = self.client_http.call_api(RangerClient.GET_SERVICE_BY_NAME.format_path({ 'name': serviceName }))
return type_coerce(resp, RangerService)
def update_service_by_id(self, serviceId, service, params=None):
resp = self.client_http.call_api(RangerClient.UPDATE_SERVICE_BY_ID.format_path({ 'id': serviceId }), params, service)
return type_coerce(resp, RangerService)
def update_service(self, serviceName, service, params=None):
resp = self.client_http.call_api(RangerClient.UPDATE_SERVICE_BY_NAME.format_path({ 'name': serviceName }), params, service)
return type_coerce(resp, RangerService)
def delete_service_by_id(self, serviceId):
self.client_http.call_api(RangerClient.DELETE_SERVICE_BY_ID.format_path({ 'id': serviceId }))
def delete_service(self, serviceName):
self.client_http.call_api(RangerClient.DELETE_SERVICE_BY_NAME.format_path({ 'name': serviceName }))
def find_services(self, filter=None):
resp = self.client_http.call_api(RangerClient.FIND_SERVICES, filter)
return type_coerce_list(resp, RangerService)
# Policy APIs
def create_policy(self, policy, params=None):
resp = self.client_http.call_api(RangerClient.CREATE_POLICY, params, policy)
return type_coerce(resp, RangerPolicy)
def get_policy_by_id(self, policyId):
resp = self.client_http.call_api(RangerClient.GET_POLICY_BY_ID.format_path({ 'id': policyId }))
return type_coerce(resp, RangerPolicy)
def get_policy(self, serviceName, policyName):
resp = self.client_http.call_api(RangerClient.GET_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}))
return type_coerce(resp, RangerPolicy)
def get_policy_by_name_zone(self, serviceName, policyName, zoneName):
resp = self.client_http.call_api(RangerClient.GET_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}), { 'zoneName': zoneName })
return type_coerce(resp, RangerPolicy)
def get_policies_in_service(self, serviceName, params=None):
resp = self.client_http.call_api(RangerClient.GET_POLICIES_IN_SERVICE.format_path({ 'serviceName': serviceName }), params)
return type_coerce_list(resp, RangerPolicy)
def update_policy_by_id(self, policyId, policy):
resp = self.client_http.call_api(RangerClient.UPDATE_POLICY_BY_ID.format_path({ 'id': policyId }), request_data=policy)
return type_coerce(resp, RangerPolicy)
def update_policy(self, serviceName, policyName, policy):
resp = self.client_http.call_api(RangerClient.UPDATE_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}), request_data=policy)
return type_coerce(resp, RangerPolicy)
def update_policy_by_name_zone(self, serviceName, policyName, zoneName, policy):
resp = self.client_http.call_api(RangerClient.UPDATE_POLICY_BY_NAME.format_path({ 'serviceName': serviceName, 'policyName': policyName}), { 'zoneName': zoneName }, request_data=policy)
return type_coerce(resp, RangerPolicy)
def apply_policy(self, policy, params=None):
resp = self.client_http.call_api(RangerClient.APPLY_POLICY, params, policy)
return type_coerce(resp, RangerPolicy)
def delete_policy_by_id(self, policyId):
self.client_http.call_api(RangerClient.DELETE_POLICY_BY_ID.format_path({ 'id': policyId }))
def delete_policy(self, serviceName, policyName):
self.client_http.call_api(RangerClient.DELETE_POLICY_BY_NAME, { 'servicename': serviceName, 'policyname': policyName })
def delete_policy_by_name_zone(self, serviceName, policyName, zoneName):
self.client_http.call_api(RangerClient.DELETE_POLICY_BY_NAME, { 'servicename': serviceName, 'policyname': policyName, 'zoneName': zoneName })
def find_policies(self, filter=None):
resp = self.client_http.call_api(RangerClient.FIND_POLICIES, filter)
return type_coerce_list(resp, RangerPolicy)
# SecurityZone APIs
def create_security_zone(self, securityZone):
resp = self.client_http.call_api(RangerClient.CREATE_ZONE, request_data=securityZone)
return type_coerce(resp, RangerSecurityZone)
def update_security_zone_by_id(self, zoneId, securityZone):
resp = self.client_http.call_api(RangerClient.UPDATE_ZONE_BY_ID.format_path({ 'id': zoneId }), request_data=securityZone)
return type_coerce(resp, RangerSecurityZone)
def delete_security_zone_by_id(self, zoneId):
self.client_http.call_api(RangerClient.DELETE_ZONE_BY_ID.format_path({ 'id': zoneId }))
def delete_security_zone(self, zoneName):
self.client_http.call_api(RangerClient.DELETE_ZONE_BY_NAME.format_path({ 'name': zoneName }))
def get_security_zone_by_id(self, zoneId):
resp = self.client_http.call_api(RangerClient.GET_ZONE_BY_ID.format_path({ 'id': zoneId }))
return type_coerce(resp, RangerSecurityZone)
def get_security_zone(self, zoneName):
resp = self.client_http.call_api(RangerClient.GET_ZONE_BY_NAME.format_path({ 'name': zoneName }))
return type_coerce(resp, RangerSecurityZone)
def get_security_zone_headers(self):
resp = self.client_http.call_api(RangerClient.GET_ZONE_HEADERS)
return type_coerce_list(resp, RangerSecurityZoneHeaderInfo)
def get_security_zone_service_headers(self, zoneId):
resp = self.client_http.call_api(RangerClient.GET_ZONE_SERVICE_HEADERS.format_path({ 'id': zoneId }))
return type_coerce_list(resp, RangerServiceHeaderInfo)
def get_zone_names_for_resource(self, serviceName, resource):
return self.client_http.call_api(RangerClient.GET_ZONE_NAMES_FOR_RESOURCE.format_path({ 'serviceName': serviceName }), query_params=resource_to_query_params(resource))
def find_security_zones(self, filter=None):
resp = self.client_http.call_api(RangerClient.FIND_ZONES, filter)
return type_coerce_list(resp, RangerSecurityZone)
def create_security_zone_v2(self, securityZone):
resp = self.client_http.call_api(RangerClient.CREATE_ZONE_V2, request_data=securityZone)
return type_coerce(resp, RangerSecurityZoneV2)
def update_security_zone_v2(self, zoneId, securityZone):
resp = self.client_http.call_api(RangerClient.UPDATE_ZONE_V2_BY_ID.format_path({ 'id': zoneId }), request_data=securityZone)
return type_coerce(resp, RangerSecurityZoneV2)
def partial_update_security_zone_v2(self, zoneId, changeData):
resp = self.client_http.call_api(RangerClient.PARTIAL_UPDATE_ZONE_V2_BY_ID.format_path({ 'id': zoneId }), request_data=changeData)
return type_coerce(resp, RangerSecurityZoneV2)
def get_security_zone_v2(self, zoneName):
resp = self.client_http.call_api(RangerClient.GET_ZONE_V2_BY_NAME.format_path({ 'name': zoneName }))
return type_coerce(resp, RangerSecurityZoneV2)
def get_security_zone_v2_by_id(self, zoneId):
resp = self.client_http.call_api(RangerClient.GET_ZONE_V2_BY_ID.format_path({ 'id': zoneId }))
return type_coerce(resp, RangerSecurityZoneV2)
def zone_v2_get_resources(self, zoneName, serviceName, filter=None):
resp = self.client_http.call_api(RangerClient.ZONE_V2_GET_RESOURCES.format_path({'name': zoneName, 'serviceName': serviceName}), filter)
ret = type_coerce(resp, PList)
if ret is not None:
ret.type_coerce_list(RangerSecurityZoneResource)
return ret
def zone_v2_by_id_get_resources(self, zoneId, serviceName, filter=None):
resp = self.client_http.call_api(RangerClient.ZONE_V2_BY_ID_GET_RESOURCES.format_path({'id': zoneId, 'serviceName': serviceName}), filter)
ret = type_coerce(resp, PList)
if ret is not None:
ret.type_coerce_list(RangerSecurityZoneResource)
return ret
def find_security_zones_v2(self, filter=None):
resp = self.client_http.call_api(RangerClient.FIND_ZONES_V2, filter)
ret = type_coerce(resp, PList)
if ret is not None:
ret.type_coerce_list(RangerSecurityZoneV2)
return ret
# Role APIs
def create_role(self, serviceName, role, params=None):
if params is None:
params = {}
params['serviceName'] = serviceName
resp = self.client_http.call_api(RangerClient.CREATE_ROLE, params, role)
return type_coerce(resp, RangerRole)
def update_role(self, roleId, role, params=None):
resp = self.client_http.call_api(RangerClient.UPDATE_ROLE_BY_ID.format_path({ 'id': roleId }), params, role)
return type_coerce(resp, RangerRole)
def delete_role_by_id(self, roleId):
self.client_http.call_api(RangerClient.DELETE_ROLE_BY_ID.format_path({ 'id': roleId }))
def delete_role(self, roleName, execUser, serviceName):
self.client_http.call_api(RangerClient.DELETE_ROLE_BY_NAME.format_path({ 'name': roleName }), { 'execUser': execUser, 'serviceName': serviceName })
def get_role_by_id(self, roleId):
resp = self.client_http.call_api(RangerClient.GET_ROLE_BY_ID.format_path({ 'id': roleId }))
return type_coerce(resp, RangerRole)
def get_role(self, roleName, execUser, serviceName):
resp = self.client_http.call_api(RangerClient.GET_ROLE_BY_NAME.format_path({ 'name': roleName }), { 'execUser': execUser, 'serviceName': serviceName })
return type_coerce(resp, RangerRole)
def get_all_role_names(self, execUser, serviceName):
resp = self.client_http.call_api(RangerClient.GET_ALL_ROLE_NAMES.format_path({ 'name': serviceName }), { 'execUser': execUser, 'serviceName': serviceName })
return resp
def get_user_roles(self, user, filters=None):
ret = self.client_http.call_api(RangerClient.GET_USER_ROLES.format_path({ 'name': user }), filters)
return list(ret) if ret is not None else None
def find_roles(self, filter=None):
resp = self.client_http.call_api(RangerClient.FIND_ROLES, filter)
return type_coerce_list(resp, RangerRole)
def grant_role(self, serviceName, request, params=None):
resp = self.client_http.call_api(RangerClient.GRANT_ROLE.format_path({ 'name': serviceName }), params, request)
return type_coerce(resp, RESTResponse)
def revoke_role(self, serviceName, request, params=None):
resp = self.client_http.call_api(RangerClient.REVOKE_ROLE.format_path({ 'name': serviceName }), params, request)
return type_coerce(resp, RESTResponse)
# Admin APIs
def import_service_tags(self, serviceName, svcTags):
self.client_http.call_api(RangerClient.IMPORT_SERVICE_TAGS.format_path({ 'serviceName': serviceName }), request_data=svcTags)
def get_service_tags(self, serviceName):
resp = self.client_http.call_api(RangerClient.GET_SERVICE_TAGS.format_path({ 'serviceName': serviceName }))
return type_coerce(resp, RangerServiceTags)
def delete_policy_deltas(self, days, reloadServicePoliciesCache):
self.client_http.call_api(RangerClient.DELETE_POLICY_DELTAS, { 'days': days, 'reloadServicePoliciesCache': reloadServicePoliciesCache})
def purge_records(self, record_type, retention_days):
return self.client_http.call_api(RangerClient.PURGE_RECORDS, { 'type': record_type, 'retentionDays': retention_days})
def set_log_level(self, logger_name, log_level):
"""
Sets the log level for a specific class or package.
This operation requires ROLE_SYS_ADMIN role.
:param logger_name: The name of the logger (class or package name)
:param log_level: The log level to set (TRACE, DEBUG, INFO, WARN, ERROR, OFF)
:return: A message indicating the result of the operation
:raises: RangerServiceException if the operation fails
"""
request_data = {
'loggerName': logger_name,
'logLevel': log_level
}
return self.client_http.call_api(RangerClient.SET_LOG_LEVEL, request_data=request_data)
# URIs
URI_BASE = "service/public/v2/api"
URI_SERVICEDEF = URI_BASE + "/servicedef"
URI_SERVICEDEF_BY_ID = URI_SERVICEDEF + "/{id}"
URI_SERVICEDEF_BY_NAME = URI_SERVICEDEF + "/name/{name}"
URI_SERVICE = URI_BASE + "/service"
URI_SERVICE_BY_ID = URI_SERVICE + "/{id}"
URI_SERVICE_BY_NAME = URI_SERVICE + "/name/{name}"
URI_POLICIES_IN_SERVICE = URI_SERVICE + "/{serviceName}/policy"
URI_POLICY = URI_BASE + "/policy"
URI_APPLY_POLICY = URI_POLICY + "/apply"
URI_POLICY_BY_ID = URI_POLICY + "/{id}"
URI_POLICY_BY_NAME = URI_SERVICE + "/{serviceName}/policy/{policyName}"
URI_ROLE = URI_BASE + "/roles"
URI_ROLE_NAMES = URI_ROLE + "/names"
URI_ROLE_BY_ID = URI_ROLE + "/{id}"
URI_ROLE_BY_NAME = URI_ROLE + "/name/{name}"
URI_USER_ROLES = URI_ROLE + "/user/{name}"
URI_GRANT_ROLE = URI_ROLE + "/grant/{name}"
URI_REVOKE_ROLE = URI_ROLE + "/revoke/{name}"
URI_ZONE = URI_BASE + "/zones"
URI_ZONE_BY_ID = URI_ZONE + "/{id}"
URI_ZONE_BY_NAME = URI_ZONE + "/name/{name}"
URI_ZONE_HEADERS = URI_BASE + "/zone-headers"
URI_ZONE_SERVICE_HEADERS = URI_ZONE + "/{id}/service-headers"
URI_ZONE_NAMES_FOR_RESOURCE = URI_BASE + "/zone-names/{serviceName}/resource"
URI_ZONE_V2 = URI_BASE + "/zones-v2"
URI_ZONE_V2_BY_ID = URI_ZONE_V2 + "/{id}"
URI_ZONE_V2_BY_NAME = URI_ZONE_V2 + "/name/{name}"
URL_ZONE_V2_BY_ID_RESOURCES = URI_ZONE_V2_BY_ID + "/resources/{serviceName}"
URL_ZONE_V2_BY_NAME_RESOURCES = URI_ZONE_V2_BY_NAME+ "/resources/{serviceName}"
URI_ZONE_V2_PARTIAL_BY_ID = URI_ZONE_V2_BY_ID + "/partial"
URI_SERVICE_TAGS = URI_SERVICE + "/{serviceName}/tags"
URI_PLUGIN_INFO = URI_BASE + "/plugins/info"
URI_POLICY_DELTAS = URI_BASE + "/server/policydeltas"
URI_PURGE_RECORDS = URI_BASE + "/server/purge/records"
URI_LOGGERS_SET_LEVEL = "service/admin/set-logger-level"
# APIs
CREATE_SERVICEDEF = API(URI_SERVICEDEF, HttpMethod.POST, HTTPStatus.OK)
UPDATE_SERVICEDEF_BY_ID = API(URI_SERVICEDEF_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
UPDATE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
DELETE_SERVICEDEF_BY_ID = API(URI_SERVICEDEF_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
DELETE_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
GET_SERVICEDEF_BY_ID = API(URI_SERVICEDEF_BY_ID, HttpMethod.GET, HTTPStatus.OK)
GET_SERVICEDEF_BY_NAME = API(URI_SERVICEDEF_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
FIND_SERVICEDEFS = API(URI_SERVICEDEF, HttpMethod.GET, HTTPStatus.OK)
CREATE_SERVICE = API(URI_SERVICE, HttpMethod.POST, HTTPStatus.OK)
UPDATE_SERVICE_BY_ID = API(URI_SERVICE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
UPDATE_SERVICE_BY_NAME = API(URI_SERVICE_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
DELETE_SERVICE_BY_ID = API(URI_SERVICE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
DELETE_SERVICE_BY_NAME = API(URI_SERVICE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
GET_SERVICE_BY_ID = API(URI_SERVICE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
GET_SERVICE_BY_NAME = API(URI_SERVICE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
FIND_SERVICES = API(URI_SERVICE, HttpMethod.GET, HTTPStatus.OK)
CREATE_POLICY = API(URI_POLICY, HttpMethod.POST, HTTPStatus.OK)
UPDATE_POLICY_BY_ID = API(URI_POLICY_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
UPDATE_POLICY_BY_NAME = API(URI_POLICY_BY_NAME, HttpMethod.PUT, HTTPStatus.OK)
APPLY_POLICY = API(URI_APPLY_POLICY, HttpMethod.POST, HTTPStatus.OK)
DELETE_POLICY_BY_ID = API(URI_POLICY_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
DELETE_POLICY_BY_NAME = API(URI_POLICY, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
GET_POLICY_BY_ID = API(URI_POLICY_BY_ID, HttpMethod.GET, HTTPStatus.OK)
GET_POLICY_BY_NAME = API(URI_POLICY_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
GET_POLICIES_IN_SERVICE = API(URI_POLICIES_IN_SERVICE, HttpMethod.GET, HTTPStatus.OK)
FIND_POLICIES = API(URI_POLICY, HttpMethod.GET, HTTPStatus.OK)
CREATE_ZONE = API(URI_ZONE, HttpMethod.POST, HTTPStatus.OK)
UPDATE_ZONE_BY_ID = API(URI_ZONE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
DELETE_ZONE_BY_ID = API(URI_ZONE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
DELETE_ZONE_BY_NAME = API(URI_ZONE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
GET_ZONE_BY_ID = API(URI_ZONE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
GET_ZONE_BY_NAME = API(URI_ZONE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
FIND_ZONES = API(URI_ZONE, HttpMethod.GET, HTTPStatus.OK)
GET_ZONE_HEADERS = API(URI_ZONE_HEADERS, HttpMethod.GET, HTTPStatus.OK)
GET_ZONE_SERVICE_HEADERS = API(URI_ZONE_SERVICE_HEADERS, HttpMethod.GET, HTTPStatus.OK)
GET_ZONE_NAMES_FOR_RESOURCE = API(URI_ZONE_NAMES_FOR_RESOURCE, HttpMethod.GET, HTTPStatus.OK)
CREATE_ZONE_V2 = API(URI_ZONE_V2, HttpMethod.POST, HTTPStatus.OK)
UPDATE_ZONE_V2_BY_ID = API(URI_ZONE_V2_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
PARTIAL_UPDATE_ZONE_V2_BY_ID = API(URI_ZONE_V2_PARTIAL_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
GET_ZONE_V2_BY_NAME = API(URI_ZONE_V2_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
GET_ZONE_V2_BY_ID = API(URI_ZONE_V2_BY_ID, HttpMethod.GET, HTTPStatus.OK)
ZONE_V2_GET_RESOURCES = API(URL_ZONE_V2_BY_NAME_RESOURCES, HttpMethod.GET, HTTPStatus.OK)
ZONE_V2_BY_ID_GET_RESOURCES = API(URL_ZONE_V2_BY_ID_RESOURCES, HttpMethod.GET, HTTPStatus.OK)
FIND_ZONES_V2 = API(URI_ZONE_V2, HttpMethod.GET, HTTPStatus.OK)
CREATE_ROLE = API(URI_ROLE, HttpMethod.POST, HTTPStatus.OK)
UPDATE_ROLE_BY_ID = API(URI_ROLE_BY_ID, HttpMethod.PUT, HTTPStatus.OK)
DELETE_ROLE_BY_ID = API(URI_ROLE_BY_ID, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
DELETE_ROLE_BY_NAME = API(URI_ROLE_BY_NAME, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
GET_ROLE_BY_ID = API(URI_ROLE_BY_ID, HttpMethod.GET, HTTPStatus.OK)
GET_ROLE_BY_NAME = API(URI_ROLE_BY_NAME, HttpMethod.GET, HTTPStatus.OK)
GET_ALL_ROLE_NAMES = API(URI_ROLE_NAMES, HttpMethod.GET, HTTPStatus.OK)
GET_USER_ROLES = API(URI_USER_ROLES, HttpMethod.GET, HTTPStatus.OK)
GRANT_ROLE = API(URI_GRANT_ROLE, HttpMethod.PUT, HTTPStatus.OK)
REVOKE_ROLE = API(URI_REVOKE_ROLE, HttpMethod.PUT, HTTPStatus.OK)
FIND_ROLES = API(URI_ROLE, HttpMethod.GET, HTTPStatus.OK)
IMPORT_SERVICE_TAGS = API(URI_SERVICE_TAGS, HttpMethod.PUT, HTTPStatus.NO_CONTENT)
GET_SERVICE_TAGS = API(URI_SERVICE_TAGS, HttpMethod.GET, HTTPStatus.OK)
GET_PLUGIN_INFO = API(URI_PLUGIN_INFO, HttpMethod.GET, HTTPStatus.OK)
DELETE_POLICY_DELTAS = API(URI_POLICY_DELTAS, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
PURGE_RECORDS = API(URI_PURGE_RECORDS, HttpMethod.DELETE, HTTPStatus.OK)
SET_LOG_LEVEL = API(URI_LOGGERS_SET_LEVEL, HttpMethod.POST, HTTPStatus.OK)
class HadoopSimpleAuth(AuthBase):
def __init__(self, user_name):
self.user_name = user_name.encode("utf-8")
def __call__(self, req):
sep_char = '?'
if req.url.find('?') != -1:
sep_char = '&'
req.url = req.url + sep_char + urlencode({ QUERY_PARAM_USER_DOT_NAME: self.user_name })
return req
class Message(RangerBase):
def __init__(self, attrs=None):
if attrs is None:
attrs = {}
RangerBase.__init__(self, attrs)
self.name = attrs.get('name')
self.rbKey = attrs.get('rbKey')
self.message = attrs.get('message')
self.objectId = attrs.get('objectId')
self.fieldName = attrs.get('fieldName')
class RESTResponse(RangerBase):
def __init__(self, attrs=None):
if attrs is None:
attrs = {}
RangerBase.__init__(self, attrs)
self.httpStatusCode = attrs.get('httpStatusCode')
self.statusCode = attrs.get('statusCode')
self.msgDesc = attrs.get('msgDesc')
self.messageList = non_null(attrs.get('messageList'), [])
def type_coerce_attrs(self):
super(RangerPolicy, self).type_coerce_attrs()
self.messageList = type_coerce_dict(self.messageList, Message)
class RangerClientHttp:
def __init__(self, url, auth, query_params=None, headers=None):
self.url = url.rstrip('/') + '/' # ensure that self.url ends with a /
self.query_params = query_params
self.headers = headers
self.session = Session()
self.session.auth = auth
def call_api(self, api, query_params=None, request_data=None):
ret = None
params = { 'headers': { 'Accept': api.consumes, 'Content-type': api.produces } }
if self.headers:
params['headers'].update(self.headers)
if self.query_params:
if query_params:
merged_query_params = {}
merged_query_params.update(self.query_params)
merged_query_params.update(query_params)
query_params = merged_query_params
else:
query_params = self.query_params
if query_params:
params['params'] = query_params
if request_data:
params['data'] = json.dumps(request_data)
path = urljoin(self.url, api.path.lstrip('/'))
if LOG.isEnabledFor(logging.DEBUG):
LOG.debug("------------------------------------------------------")
LOG.debug("Call : %s %s", api.method, path)
LOG.debug("Content-type : %s", api.consumes)
LOG.debug("Accept : %s", api.produces)
response = None
if api.method == HttpMethod.GET:
response = self.session.get(path, **params)
elif api.method == HttpMethod.POST:
response = self.session.post(path, **params)
elif api.method == HttpMethod.PUT:
response = self.session.put(path, **params)
elif api.method == HttpMethod.DELETE:
response = self.session.delete(path, **params)
if LOG.isEnabledFor(logging.DEBUG):
LOG.debug("HTTP Status: %s", response.status_code if response else "None")
if response is None:
ret = None
elif response.status_code == api.expected_status:
try:
if response.status_code == HTTPStatus.NO_CONTENT or response.content is None:
ret = None
else:
if LOG.isEnabledFor(logging.DEBUG):
LOG.debug("<== __call_api(%s, %s, %s), result=%s", vars(api), params, request_data, response)
LOG.debug(response.content)
if response.content:
try:
ret = response.json()
except Exception:
ret = response.content
except Exception as e:
print(e)
LOG.exception("Exception occurred while parsing response with msg: %s", e)
raise RangerServiceException(api, response)
elif response.status_code == HTTPStatus.SERVICE_UNAVAILABLE:
LOG.error("Ranger server at %s unavailable. HTTP Status: %s", self.url, HTTPStatus.SERVICE_UNAVAILABLE)
ret = None
elif response.status_code == HTTPStatus.NOT_FOUND:
LOG.error("Not found. HTTP Status: %s", HTTPStatus.NOT_FOUND)
ret = None
elif response.status_code == HTTPStatus.NOT_MODIFIED:
ret = None
else:
raise RangerServiceException(api, response)
return ret
class RangerClientPrivate:
def __init__(self, url, auth):
self.client_http = RangerClientHttp(url, auth)
logging.getLogger("requests").setLevel(logging.WARNING)
# URLs
URI_DELETE_USER = "service/xusers/secure/users/{name}"
URI_DELETE_GROUP = "service/xusers/secure/groups/{name}"
URI_FORCE_DELETE_EXTERNAL_USERS = "service/xusers/delete/external/users"
URI_FORCE_DELETE_EXTERNAL_GROUPS = "service/xusers/delete/external/groups"
# APIs
DELETE_USER = API(URI_DELETE_USER, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
DELETE_GROUP = API(URI_DELETE_GROUP, HttpMethod.DELETE, HTTPStatus.NO_CONTENT)
FORCE_DELETE_EXTERNAL_USERS = API(URI_FORCE_DELETE_EXTERNAL_USERS, HttpMethod.DELETE, HTTPStatus.OK)
FORCE_DELETE_EXTERNAL_GROUPS = API(URI_FORCE_DELETE_EXTERNAL_GROUPS, HttpMethod.DELETE, HTTPStatus.OK)
def delete_user(self, userName, execUser, isForceDelete='true'):
self.client_http.call_api(RangerClientPrivate.DELETE_USER.format_path({ 'name': userName }), { 'execUser': execUser, 'forceDelete': isForceDelete })
def delete_group(self, groupName, execUser, isForceDelete='true'):
self.client_http.call_api(RangerClientPrivate.DELETE_GROUP.format_path({ 'name': groupName }), { 'execUser': execUser, 'forceDelete': isForceDelete })
def force_delete_external_users(self, filter=None):
"""
Proceed with <tt>caution</tt>.
Force deletes external users from ranger db.
Optionally, Query Params may be specified using the param 'filter'
to delete specific external users.
:param filter:
:return:
"""
return self.client_http.call_api(RangerClientPrivate.FORCE_DELETE_EXTERNAL_USERS, filter).decode('utf-8')
def force_delete_external_groups(self, filter=None):
"""
Proceed with <tt>caution</tt>.
Force deletes external groups from ranger db.
Optionally, Query Params may be specified using the param 'filter'
to delete specific external groups.
:param filter:
:return:
"""
return self.client_http.call_api(RangerClientPrivate.FORCE_DELETE_EXTERNAL_GROUPS, filter).decode('utf-8')