You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2022/04/20 23:01:27 UTC
[ranger] branch master updated: RANGER-3475: added public REST API endpoint to import tags
This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 6e9a8ccfe RANGER-3475: added public REST API endpoint to import tags
6e9a8ccfe is described below
commit 6e9a8ccfec9b88abdca7d4dd2fa861c058da1356
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Tue Apr 12 12:57:29 2022 -0700
RANGER-3475: added public REST API endpoint to import tags
---
.../ranger/plugin/model/RangerServiceTags.java | 215 +++++++++++++++++++++
.../main/java/org/apache/ranger/RangerClient.java | 11 ++
.../python/apache_ranger/client/ranger_client.py | 12 ++
.../apache_ranger/model/ranger_service_resource.py | 51 +++++
.../apache_ranger/model/ranger_service_tags.py | 52 +++++
.../main/python/apache_ranger/model/ranger_tag.py | 40 ++++
.../python/apache_ranger/model/ranger_tagdef.py | 47 +++++
.../ranger/examples/sampleclient/SampleClient.java | 55 ++++++
.../sample-client/src/main/python/sample_client.py | 59 +++++-
.../java/org/apache/ranger/rest/PublicAPIsv2.java | 48 +++++
10 files changed, 584 insertions(+), 6 deletions(-)
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceTags.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceTags.java
new file mode 100644
index 000000000..8f59aa5ee
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceTags.java
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+package org.apache.ranger.plugin.model;
+
+
+import org.apache.ranger.plugin.util.ServiceTags;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonAutoDetect(fieldVisibility=Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RangerServiceTags implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ public static final String OP_SET = "set"; // set tags for the given serviceResources
+ public static final String OP_DELETE = "delete"; // delete tags associated with the given serviceResources
+ public static final String OP_REPLACE = "replace"; // replace all resources and tags in the given serviceName with the given serviceResources and tags
+
+ private String op = OP_SET;
+ private String serviceName;
+ private Map<Long, RangerTagDef> tagDefinitions;
+ private Map<Long, RangerTag> tags;
+ private List<RangerServiceResource> serviceResources;
+ private Map<Long, List<Long>> resourceToTagIds;
+ private Long tagVersion; // read-only field
+ private Date tagUpdateTime; // read-only field
+
+ public RangerServiceTags() {
+ this(OP_SET, null, null, null, null, null, null, null);
+ }
+
+ public RangerServiceTags(String op, String serviceName, Map<Long, RangerTagDef> tagDefinitions,
+ Map<Long, RangerTag> tags, List<RangerServiceResource> serviceResources,
+ Map<Long, List<Long>> resourceToTagIds, Long tagVersion, Date tagUpdateTime) {
+ setOp(op);
+ setServiceName(serviceName);
+ setTagDefinitions(tagDefinitions);
+ setTags(tags);
+ setServiceResources(serviceResources);
+ setResourceToTagIds(resourceToTagIds);
+ setTagVersion(tagVersion);
+ setTagUpdateTime(tagUpdateTime);
+ }
+
+ /**
+ * @return the op
+ */
+ public String getOp() {
+ return op;
+ }
+
+ /**
+ * @return the serviceName
+ */
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ /**
+ * @param op the op to set
+ */
+ public void setOp(String op) {
+ this.op = op;
+ }
+
+ /**
+ * @param serviceName the serviceName to set
+ */
+ public void setServiceName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+ public Map<Long, RangerTagDef> getTagDefinitions() {
+ return tagDefinitions;
+ }
+
+ public void setTagDefinitions(Map<Long, RangerTagDef> tagDefinitions) {
+ this.tagDefinitions = tagDefinitions == null ? new HashMap<>() : tagDefinitions;
+ }
+
+ public Map<Long, RangerTag> getTags() {
+ return tags;
+ }
+
+ public void setTags(Map<Long, RangerTag> tags) {
+ this.tags = tags == null ? new HashMap<>() : tags;
+ }
+
+ public List<RangerServiceResource> getServiceResources() {
+ return serviceResources;
+ }
+
+ public void setServiceResources(List<RangerServiceResource> serviceResources) {
+ this.serviceResources = serviceResources == null ? new ArrayList<>() : serviceResources;
+ }
+
+ public Map<Long, List<Long>> getResourceToTagIds() {
+ return resourceToTagIds;
+ }
+
+ public void setResourceToTagIds(Map<Long, List<Long>> resourceToTagIds) {
+ this.resourceToTagIds = resourceToTagIds == null ? new HashMap<>() : resourceToTagIds;
+ }
+
+ public Long getTagVersion() {
+ return tagVersion;
+ }
+
+ public void setTagVersion(Long tagVersion) {
+ this.tagVersion = tagVersion;
+ }
+
+ public Date getTagUpdateTime() {
+ return tagUpdateTime;
+ }
+
+ public void setTagUpdateTime(Date tagUpdateTime) {
+ this.tagUpdateTime = tagUpdateTime;
+ }
+
+
+ @Override
+ public String toString( ) {
+ StringBuilder sb = new StringBuilder();
+
+ toString(sb);
+
+ return sb.toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerServiceTags={")
+ .append("op=").append(op).append(", ")
+ .append("serviceName=").append(serviceName).append(", ")
+ .append("}");
+
+ return sb;
+ }
+
+ public static ServiceTags toServiceTags(RangerServiceTags tags) {
+ ServiceTags ret = null;
+
+ if (tags != null) {
+ ret = new ServiceTags(toServiceTagsOp(tags.getOp()), tags.getServiceName(),
+ tags.tagVersion, tags.getTagUpdateTime(), tags.getTagDefinitions(), tags.getTags(),
+ tags.getServiceResources(), tags.getResourceToTagIds(), false,
+ ServiceTags.TagsChangeExtent.ALL);
+ }
+
+ return ret;
+ }
+
+ public static RangerServiceTags toRangerServiceTags(ServiceTags tags) {
+ RangerServiceTags ret = null;
+
+ if (tags != null) {
+ ret = new RangerServiceTags(toRangerServiceTagsOp(tags.getOp()), tags.getServiceName(),
+ tags.getTagDefinitions(), tags.getTags(), tags.getServiceResources(),
+ tags.getResourceToTagIds(), tags.getTagVersion(), tags.getTagUpdateTime());
+ }
+
+ return ret;
+ }
+
+ private static String toServiceTagsOp(String rangerServiceTagsOp) {
+ String ret = rangerServiceTagsOp;
+
+ if (RangerServiceTags.OP_SET.equals(rangerServiceTagsOp)) {
+ ret = ServiceTags.OP_ADD_OR_UPDATE;
+ }
+
+ return ret;
+ }
+
+ private static String toRangerServiceTagsOp(String serviceTagsOp) {
+ String ret = serviceTagsOp;
+
+ if (ServiceTags.OP_ADD_OR_UPDATE.equals(serviceTagsOp)) {
+ ret = RangerServiceTags.OP_SET;
+ }
+
+ return ret;
+ }
+}
diff --git a/intg/src/main/java/org/apache/ranger/RangerClient.java b/intg/src/main/java/org/apache/ranger/RangerClient.java
index add084f1a..f92116d36 100644
--- a/intg/src/main/java/org/apache/ranger/RangerClient.java
+++ b/intg/src/main/java/org/apache/ranger/RangerClient.java
@@ -80,6 +80,7 @@ public class RangerClient {
private static final String URI_ZONE_BY_ID = URI_ZONE + "/%d";
private static final String URI_ZONE_BY_NAME = URI_ZONE + "/name/%s";
+ private static final String URI_SERVICE_TAGS = URI_SERVICE + "/%s/tags";
private static final String URI_PLUGIN_INFO = URI_BASE + "/plugins/info";
private static final String URI_POLICY_DELTAS = URI_BASE + "/server/policydeltas";
@@ -135,6 +136,8 @@ public class RangerClient {
public static final API REVOKE_ROLE = new API(URI_REVOKE_ROLE, HttpMethod.PUT, Response.Status.OK);
public static final API FIND_ROLES = new API(URI_ROLE, HttpMethod.GET, Response.Status.OK);
+ public static final API IMPORT_SERVICE_TAGS = new API(URI_SERVICE_TAGS, HttpMethod.PUT, Response.Status.NO_CONTENT);
+ public static final API GET_SERVICE_TAGS = new API(URI_SERVICE_TAGS, HttpMethod.GET, Response.Status.OK);
public static final API GET_PLUGIN_INFO = new API(URI_PLUGIN_INFO, HttpMethod.GET, Response.Status.OK);
public static final API DELETE_POLICY_DELTAS = new API(URI_POLICY_DELTAS, HttpMethod.DELETE, Response.Status.NO_CONTENT);
@@ -396,6 +399,14 @@ public class RangerClient {
/*
* Admin APIs
*/
+ public void importServiceTags(String serviceName, RangerServiceTags svcTags) throws RangerServiceException {
+ callAPI(IMPORT_SERVICE_TAGS.applyUrlFormat(serviceName), null, svcTags, (GenericType<Void>) null);
+ }
+
+ public RangerServiceTags getServiceTags(String serviceName) throws RangerServiceException {
+ return callAPI(GET_SERVICE_TAGS.applyUrlFormat(serviceName), null, null, RangerServiceTags.class);
+ }
+
public List<RangerPluginInfo> getPluginsInfo() throws RangerServiceException {
return callAPI(GET_PLUGIN_INFO, null, null, new GenericType<List<RangerPluginInfo>>(){});
}
diff --git a/intg/src/main/python/apache_ranger/client/ranger_client.py b/intg/src/main/python/apache_ranger/client/ranger_client.py
index 9f3a6e076..85f66a43e 100644
--- a/intg/src/main/python/apache_ranger/client/ranger_client.py
+++ b/intg/src/main/python/apache_ranger/client/ranger_client.py
@@ -27,6 +27,7 @@ from apache_ranger.model.ranger_role import RangerRole
from apache_ranger.model.ranger_security_zone import RangerSecurityZone
from apache_ranger.model.ranger_service import RangerService
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
@@ -262,6 +263,14 @@ class RangerClient:
# 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})
@@ -298,6 +307,7 @@ class RangerClient:
URI_ZONE_BY_ID = URI_ZONE + "/{id}"
URI_ZONE_BY_NAME = URI_ZONE + "/name/{name}"
+ URI_SERVICE_TAGS = URI_SERVICE + "/{serviceName}/tags"
URI_PLUGIN_INFO = URI_BASE + "/plugins/info"
URI_POLICY_DELTAS = URI_BASE + "/server/policydeltas"
@@ -352,6 +362,8 @@ class RangerClient:
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)
diff --git a/intg/src/main/python/apache_ranger/model/ranger_service_resource.py b/intg/src/main/python/apache_ranger/model/ranger_service_resource.py
new file mode 100644
index 000000000..2a6b8ebf4
--- /dev/null
+++ b/intg/src/main/python/apache_ranger/model/ranger_service_resource.py
@@ -0,0 +1,51 @@
+#!/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.
+
+
+from apache_ranger.model.ranger_base import *
+from apache_ranger.model.ranger_policy import RangerPolicyResource
+from apache_ranger.utils import *
+
+
+class RangerServiceResource(RangerBaseModelObject):
+ def __init__(self, attrs=None):
+ if attrs is None:
+ attrs = {}
+
+ RangerBaseModelObject.__init__(self, attrs)
+
+ self.serviceName = attrs.get('serviceName')
+ self.resourceElements = attrs.get('resourceElements')
+ self.ownerUser = attrs.get('ownerUser')
+ self.additionalInfo = attrs.get('additionalInfo')
+
+ def type_coerce_attrs(self):
+ super(RangerServiceResource, self).type_coerce_attrs()
+
+ self.resourceElements = type_coerce_dict(self.resourceElements, RangerPolicyResource)
+
+
+class RangerTagAttributeDef(RangerBase):
+ def __init__(self, attrs=None):
+ if attrs is None:
+ attrs = {}
+
+ RangerBase.__init__(self, attrs)
+
+ self.name = attrs.get('name')
+ self.type = attrs.get('type')
diff --git a/intg/src/main/python/apache_ranger/model/ranger_service_tags.py b/intg/src/main/python/apache_ranger/model/ranger_service_tags.py
new file mode 100644
index 000000000..9773a8d14
--- /dev/null
+++ b/intg/src/main/python/apache_ranger/model/ranger_service_tags.py
@@ -0,0 +1,52 @@
+#!/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.
+
+
+from apache_ranger.model.ranger_base import *
+from apache_ranger.model.ranger_service_resource import RangerServiceResource
+from apache_ranger.model.ranger_tag import RangerTag
+from apache_ranger.model.ranger_tagdef import RangerTagDef
+from apache_ranger.utils import *
+
+
+class RangerServiceTags(RangerBase):
+ OP_SET = 'set' # set tags for the given serviceResources
+ OP_DELETE = 'delete' # delete tags associated with the given serviceResources
+ OP_REPLACE = 'replace' # replace all resources and tags in the given serviceName with the given serviceResources and tags
+
+ def __init__(self, attrs=None):
+ if attrs is None:
+ attrs = {}
+
+ RangerBase.__init__(self, attrs)
+
+ self.op = non_null(attrs.get('op'), 'set')
+ self.serviceName = attrs.get('serviceName')
+ self.tagDefinitions = attrs.get('tagDefinitions')
+ self.tags = attrs.get('tags')
+ self.serviceResources = attrs.get('serviceResources')
+ self.resourceToTagIds = attrs.get('resourceToTagIds')
+ self.tagVersion = attrs.get('tagVersion')
+ self.tagUpdateTime = attrs.get('tagUpdateTime')
+
+ def type_coerce_attrs(self):
+ super(RangerServiceTags, self).type_coerce_attrs()
+
+ self.tagDefinitions = type_coerce_dict(self.tagDefinitions, RangerTagDef)
+ self.tags = type_coerce_dict(self.tags, RangerTag)
+ self.serviceResources = type_coerce_list(self.serviceResources, RangerServiceResource)
diff --git a/intg/src/main/python/apache_ranger/model/ranger_tag.py b/intg/src/main/python/apache_ranger/model/ranger_tag.py
new file mode 100644
index 000000000..0e329783a
--- /dev/null
+++ b/intg/src/main/python/apache_ranger/model/ranger_tag.py
@@ -0,0 +1,40 @@
+#!/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.
+
+
+from apache_ranger.model.ranger_base import *
+from apache_ranger.model.ranger_policy import RangerValiditySchedule
+from apache_ranger.utils import *
+
+
+class RangerTag(RangerBaseModelObject):
+ def __init__(self, attrs=None):
+ if attrs is None:
+ attrs = {}
+
+ RangerBaseModelObject.__init__(self, attrs)
+
+ self.type = attrs.get('type')
+ self.attributes = attrs.get('attributes')
+ self.options = attrs.get('options')
+ self.validityPeriods = attrs.get('validityPeriods')
+
+ def type_coerce_attrs(self):
+ super(RangerTag, self).type_coerce_attrs()
+
+ self.validityPeriods = type_coerce_list(self.validitySchedules, RangerValiditySchedule)
diff --git a/intg/src/main/python/apache_ranger/model/ranger_tagdef.py b/intg/src/main/python/apache_ranger/model/ranger_tagdef.py
new file mode 100644
index 000000000..335888436
--- /dev/null
+++ b/intg/src/main/python/apache_ranger/model/ranger_tagdef.py
@@ -0,0 +1,47 @@
+#!/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.
+
+
+from apache_ranger.model.ranger_base import *
+from apache_ranger.utils import *
+
+
+class RangerTagDef(RangerBaseModelObject):
+ def __init__(self, attrs=None):
+ if attrs is None:
+ attrs = {}
+
+ RangerBaseModelObject.__init__(self, attrs)
+
+ self.name = attrs.get('name')
+ self.source = attrs.get('source')
+ self.attributeDefs = attrs.get('attributeDefs')
+
+ def type_coerce_attrs(self):
+ super(RangerTagDef, self).type_coerce_attrs()
+
+
+class RangerTagAttributeDef(RangerBase):
+ def __init__(self, attrs=None):
+ if attrs is None:
+ attrs = {}
+
+ RangerBase.__init__(self, attrs)
+
+ self.name = attrs.get('name')
+ self.type = attrs.get('type')
diff --git a/ranger-examples/sample-client/src/main/java/org/apache/ranger/examples/sampleclient/SampleClient.java b/ranger-examples/sample-client/src/main/java/org/apache/ranger/examples/sampleclient/SampleClient.java
index 7d5795065..d0202e47e 100644
--- a/ranger-examples/sample-client/src/main/java/org/apache/ranger/examples/sampleclient/SampleClient.java
+++ b/ranger-examples/sample-client/src/main/java/org/apache/ranger/examples/sampleclient/SampleClient.java
@@ -24,9 +24,15 @@ import org.apache.commons.cli.*;
import org.apache.ranger.RangerClient;
import org.apache.ranger.RangerServiceException;
import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerRole;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.apache.ranger.plugin.model.RangerServiceTags;
+import org.apache.ranger.plugin.model.RangerTag;
+import org.apache.ranger.plugin.model.RangerTagDef;
+import org.apache.ranger.plugin.model.RangerTagDef.RangerTagAttributeDef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -158,6 +164,55 @@ public class SampleClient {
rangerClient.deletePolicy(serviceName, policyName);
LOG.info("Policy {} successfully deleted", policyName);
+ /* import tags */
+ RangerTagDef tagDefTest1 = new RangerTagDef("test1");
+ RangerTagDef tagDefTest2 = new RangerTagDef("test2");
+
+ tagDefTest1.setAttributeDefs(Arrays.asList(new RangerTagAttributeDef("attr1", "string")));
+
+ RangerTag tagTest1Val1 = new RangerTag(tagDefTest1.getName(), Collections.singletonMap("attr1", "val1"));
+ RangerTag tagTest1Val2 = new RangerTag(tagDefTest1.getName(), Collections.singletonMap("attr1", "val2"));
+ RangerTag tagTest2 = new RangerTag(tagDefTest2.getName(), Collections.emptyMap());
+
+ RangerServiceResource db1 = new RangerServiceResource(serviceName, Collections.singletonMap("database", new RangerPolicyResource("db1")));
+ RangerServiceResource db2 = new RangerServiceResource(serviceName, Collections.singletonMap("database", new RangerPolicyResource("db2")));
+
+ db1.setId(1L);
+ db2.setId(2L);
+
+ RangerServiceTags serviceTags = new RangerServiceTags();
+
+ serviceTags.setOp(RangerServiceTags.OP_SET);
+ serviceTags.getTagDefinitions().put(0L, tagDefTest1);
+ serviceTags.getTagDefinitions().put(1L, tagDefTest2);
+ serviceTags.getTags().put(0L, tagTest1Val1);
+ serviceTags.getTags().put(1L, tagTest1Val2);
+ serviceTags.getTags().put(2L, tagTest2);
+ serviceTags.getServiceResources().add(db1);
+ serviceTags.getServiceResources().add(db2);
+ serviceTags.getResourceToTagIds().put(db1.getId(), Arrays.asList(0L, 2L));
+ serviceTags.getResourceToTagIds().put(db2.getId(), Arrays.asList(1L, 2L));
+
+ LOG.info("Importing tags: {}", serviceTags);
+
+ rangerClient.importServiceTags(serviceName, serviceTags);
+
+ RangerServiceTags serviceTags2 = rangerClient.getServiceTags(serviceName);
+
+ LOG.info("Imported tags: {}", serviceTags2);
+
+ serviceTags.setOp(RangerServiceTags.OP_DELETE);
+ serviceTags.setTagDefinitions(Collections.emptyMap());
+ serviceTags.setTags(Collections.emptyMap());
+ serviceTags.setResourceToTagIds(Collections.emptyMap());
+
+ LOG.info("Deleting tags: {}" + serviceTags);
+
+ rangerClient.importServiceTags(serviceName, serviceTags);
+
+ serviceTags2 = rangerClient.getServiceTags(serviceName);
+
+ LOG.info("Service tags after delete: {}", serviceTags2);
/*
Delete a Service
diff --git a/ranger-examples/sample-client/src/main/python/sample_client.py b/ranger-examples/sample-client/src/main/python/sample_client.py
index 902734901..e558b6e1e 100644
--- a/ranger-examples/sample-client/src/main/python/sample_client.py
+++ b/ranger-examples/sample-client/src/main/python/sample_client.py
@@ -16,11 +16,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import time
-from apache_ranger.model.ranger_service import *
-from apache_ranger.client.ranger_client import *
-from apache_ranger.model.ranger_policy import *
+from apache_ranger.client.ranger_client import *
+from apache_ranger.model.ranger_policy import *
+from apache_ranger.model.ranger_service import *
+from apache_ranger.model.ranger_service_resource import *
+from apache_ranger.model.ranger_service_tags import *
+from apache_ranger.model.ranger_tagdef import *
+from apache_ranger.model.ranger_tag import *
+from datetime import datetime
+
## create a client to connect to Apache Ranger admin server
@@ -50,8 +55,9 @@ print(' ' + str(len(service_defs)) + ' service-defs found')
for service_def in service_defs:
print(' ' + 'id: ' + str(service_def.id) + ', name: ' + service_def.name)
+now = datetime.now()
-service_name = 'dev_hive-' + str(int(time.time() * 1000))
+service_name = 'dev_hive-' + now.strftime('%Y%m%d-%H%M%S-%f')
print('Creating service: name=' + service_name)
@@ -271,6 +277,47 @@ updated_policy2 = ranger.update_policy(service_name, policy_name, updated_policy
print(' updated policy: id: ' + str(updated_policy2.id) + ', description: ' + saved_value + ', updatedDescription: ' + updated_policy2.description)
+tagdef_test1 = RangerTagDef({'name': 'test1', 'attributeDefs': [ RangerTagAttributeDef({'name': 'attr1', 'type': 'string'}) ]})
+tagdef_test2 = RangerTagDef({'name' : 'test2'})
+
+tag_test1_val1 = RangerTag({'type': 'test1', 'attributes': {'attr1': 'val1'}})
+tag_test1_val2 = RangerTag({'type': 'test1', 'attributes': {'attr1': 'val2'}})
+tag_test2 = RangerTag({'type': 'test2'})
+
+db1 = RangerServiceResource({'id': 1, 'serviceName': service_name})
+db1.resourceElements = { 'database': RangerPolicyResource({ 'values': [ 'db1' ]})}
+
+db2 = RangerServiceResource({'id': 2, 'serviceName': service_name})
+db2.resourceElements = { 'database': RangerPolicyResource({ 'values': [ 'db2' ]})}
+
+tags = RangerServiceTags({'serviceName': service_name})
+tags.op = RangerServiceTags.OP_SET
+tags.tagDefinitions = { 0: tagdef_test1, 1: tagdef_test2 }
+tags.tags = { 0: tag_test1_val1, 1: tag_test1_val2, 2: tag_test2 }
+tags.serviceResources = [ db1, db2 ]
+tags.resourceToTagIds = { 1: [ 0, 2 ], 2: [ 1, 2 ]}
+
+print('Importing tags: ' + str(tags))
+
+ranger.import_service_tags(service_name, tags)
+
+service_tags = ranger.get_service_tags(service_name)
+
+print('Imported tags: ' + str(service_tags))
+
+tags.op = RangerServiceTags.OP_DELETE
+tags.tagDefinitions = None
+tags.tags = None
+tags.resourceToTagIds = None
+
+print('Deleting tags: ' + str(tags))
+
+ranger.import_service_tags(service_name, tags)
+
+service_tags = ranger.get_service_tags(service_name)
+
+print('Service tags after delete: ' + str(service_tags))
+
print('Deleting policy: id=' + str(policy_id))
ranger.delete_policy_by_id(policy_id)
@@ -313,7 +360,7 @@ for security_zone in security_zones:
print('Listing roles..')
roles = ranger.find_roles()
-print(' ' + str(len(roles)) + ' roles zones found')
+print(' ' + str(len(roles)) + ' roles found')
for role in roles:
print(' id: ' + str(role.id) + ', name: ' + role.name)
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java b/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
index 2c5c60923..18d52fea3 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
@@ -32,8 +32,10 @@ import org.apache.ranger.plugin.model.RangerSecurityZoneHeaderInfo;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceHeaderInfo;
+import org.apache.ranger.plugin.model.RangerServiceTags;
import org.apache.ranger.plugin.util.GrantRevokeRoleRequest;
import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServiceTags;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -598,6 +600,52 @@ public class PublicAPIsv2 {
serviceREST.deletePolicyByGUIDAndServiceNameAndZoneName(guid, serviceName, zoneName);
}
+ @PUT
+ @Path("/api/service/{serviceName}/tags")
+ @Produces({ "application/json", "application/xml" })
+ @PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
+ public void importServiceTags(@PathParam("serviceName") String serviceName, RangerServiceTags svcTags) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("==> PublicAPIsv2.importServiceTags()");
+ }
+
+ ServiceTags serviceTags = RangerServiceTags.toServiceTags(svcTags);
+
+ // overwrite serviceName with the one given in url
+ serviceTags.setServiceName(serviceName);
+
+ tagREST.importServiceTags(serviceTags);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("<== PublicAPIsv2.importServiceTags()");
+ }
+ }
+
+ @GET
+ @Path("/api/service/{serviceName}/tags")
+ @Produces({ "application/json", "application/xml" })
+ @PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
+ public RangerServiceTags getServiceTags(@PathParam("serviceName") String serviceName, @Context HttpServletRequest request) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("==> PublicAPIsv2.getServiceTags()");
+ }
+
+ Long lastKnownVersion = -1L;
+ Long lastActivationTime = 0L;
+ String pluginId = null;
+ Boolean supportsTagDeltas = false;
+ String pluginCapabilities = "";
+ ServiceTags tags = tagREST.getServiceTagsIfUpdated(serviceName, lastKnownVersion, lastActivationTime, pluginId, supportsTagDeltas, pluginCapabilities, request);
+ RangerServiceTags ret = RangerServiceTags.toRangerServiceTags(tags);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("<== PublicAPIsv2.getServiceTags()");
+ }
+
+ return ret;
+ }
+
+
@GET
@Path("/api/plugins/info")
public List<RangerPluginInfo> getPluginsInfo(@Context HttpServletRequest request) {