blob: 0af7a1da212ee4b0ffe636f47dcd4138438c72eb [file] [log] [blame]
/*
* 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.patch;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.ranger.biz.RangerBizUtil;
import org.apache.ranger.biz.ServiceDBStore;
import org.apache.ranger.common.AppConstants;
import org.apache.ranger.common.JSONUtil;
import org.apache.ranger.common.RangerCommonEnums;
import org.apache.ranger.common.SearchCriteria;
import org.apache.ranger.common.ServiceUtil;
import org.apache.ranger.common.StringUtil;
import org.apache.ranger.db.RangerDaoManager;
import org.apache.ranger.entity.XXAsset;
import org.apache.ranger.entity.XXAuditMap;
import org.apache.ranger.entity.XXGroup;
import org.apache.ranger.entity.XXPolicy;
import org.apache.ranger.entity.XXPolicyConditionDef;
import org.apache.ranger.entity.XXPortalUser;
import org.apache.ranger.entity.XXResource;
import org.apache.ranger.entity.XXServiceConfigDef;
import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.entity.XXUser;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.service.RangerPolicyService;
import org.apache.ranger.service.XPermMapService;
import org.apache.ranger.service.XPolicyService;
import org.apache.ranger.util.CLIUtil;
import org.apache.ranger.view.VXPermMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class PatchMigration_J10002 extends BaseLoader {
private static final Logger logger = Logger.getLogger(PatchMigration_J10002.class);
@Autowired
RangerDaoManager daoMgr;
@Autowired
ServiceDBStore svcDBStore;
@Autowired
JSONUtil jsonUtil;
@Autowired
RangerPolicyService policyService;
@Autowired
StringUtil stringUtil;
@Autowired
XPolicyService xPolService;
@Autowired
XPermMapService xPermMapService;
@Autowired
RangerBizUtil bizUtil;
private static int policyCounter = 0;
private static int serviceCounter = 0;
static Set<String> unsupportedLegacyPermTypes = new HashSet<String>();
static {
unsupportedLegacyPermTypes.add("Unknown");
unsupportedLegacyPermTypes.add("Reset");
unsupportedLegacyPermTypes.add("Obfuscate");
unsupportedLegacyPermTypes.add("Mask");
}
public static void main(String[] args) {
logger.info("main()");
try {
PatchMigration_J10002 loader = (PatchMigration_J10002) CLIUtil.getBean(PatchMigration_J10002.class);
loader.init();
while (loader.isMoreToProcess()) {
loader.load();
}
logger.info("Load complete. Exiting!!!");
System.exit(0);
} catch (Exception e) {
logger.error("Error loading", e);
System.exit(1);
}
}
@Override
public void init() throws Exception {
// Do Nothing
}
@Override
public void execLoad() {
logger.info("==> MigrationPatch.execLoad()");
try {
migrateServicesToNewSchema();
migratePoliciesToNewSchema();
updateSequences();
} catch (Exception e) {
logger.error("Error whille migrating data.", e);
}
logger.info("<== MigrationPatch.execLoad()");
}
@Override
public void printStats() {
logger.info("Total Number of migrated repositories/services: " + serviceCounter);
logger.info("Total Number of migrated resources/policies: " + policyCounter);
}
public void migrateServicesToNewSchema() throws Exception {
logger.info("==> MigrationPatch.migrateServicesToNewSchema()");
try {
List<XXAsset> repoList = daoMgr.getXXAsset().getAll();
if (repoList.isEmpty()) {
return;
}
if (!repoList.isEmpty()) {
EmbeddedServiceDefsUtil.instance().init(svcDBStore);
}
svcDBStore.setPopulateExistingBaseFields(true);
for (XXAsset xAsset : repoList) {
if (xAsset.getActiveStatus() == AppConstants.STATUS_DELETED) {
continue;
}
RangerService existing = svcDBStore.getServiceByName(xAsset.getName());
if (existing != null) {
logger.info("Repository/Service already exists. Ignoring migration of repo: " + xAsset.getName());
continue;
}
RangerService service = new RangerService();
service = mapXAssetToService(service, xAsset);
service = svcDBStore.createService(service);
serviceCounter++;
logger.info("New Service created. ServiceName: " + service.getName());
}
svcDBStore.setPopulateExistingBaseFields(false);
} catch (Exception e) {
throw new Exception("Error while migrating data to new Plugin Schema.", e);
}
logger.info("<== MigrationPatch.migrateServicesToNewSchema()");
}
public void migratePoliciesToNewSchema() throws Exception {
logger.info("==> MigrationPatch.migratePoliciesToNewSchema()");
try {
List<XXResource> resList = daoMgr.getXXResource().getAll();
if (resList.isEmpty()) {
return;
}
svcDBStore.setPopulateExistingBaseFields(true);
for (XXResource xRes : resList) {
if (xRes.getResourceStatus() == AppConstants.STATUS_DELETED) {
continue;
}
XXAsset xAsset = daoMgr.getXXAsset().getById(xRes.getAssetId());
if (xAsset == null) {
logger.error("No Repository found for policyName: " + xRes.getPolicyName());
continue;
}
RangerService service = svcDBStore.getServiceByName(xAsset.getName());
if (service == null) {
logger.error("No Service found for policy. Ignoring migration of such policy, policyName: "
+ xRes.getPolicyName());
continue;
}
XXPolicy existing = daoMgr.getXXPolicy().findByNameAndServiceId(xRes.getPolicyName(), service.getId());
if (existing != null) {
logger.info("Policy already exists. Ignoring migration of policy: " + existing.getName());
continue;
}
RangerPolicy policy = new RangerPolicy();
policy = mapXResourceToPolicy(policy, xRes, service);
if(policy != null) {
policy = svcDBStore.createPolicy(policy);
policyCounter++;
logger.info("New policy created. policyName: " + policy.getName());
}
}
svcDBStore.setPopulateExistingBaseFields(false);
} catch (Exception e) {
throw new Exception("Error while migrating data to new Plugin Schema.", e);
}
logger.info("<== MigrationPatch.migratePoliciesToNewSchema()");
}
private RangerService mapXAssetToService(RangerService service, XXAsset xAsset) throws Exception {
String type = "";
String name = xAsset.getName();
String description = xAsset.getDescription();
Map<String, String> configs = null;
int typeInt = xAsset.getAssetType();
XXServiceDef serviceDef = daoMgr.getXXServiceDef().findByName(AppConstants.getLabelFor_AssetType(typeInt).toLowerCase());
if (serviceDef == null) {
throw new Exception("No ServiceDefinition found for repository: " + name);
}
type = serviceDef.getName();
configs = jsonUtil.jsonToMap(xAsset.getConfig());
List<XXServiceConfigDef> mandatoryConfigs = daoMgr.getXXServiceConfigDef().findByServiceDefName(type);
for (XXServiceConfigDef serviceConf : mandatoryConfigs) {
if (serviceConf.getIsMandatory()) {
if (!stringUtil.isEmpty(configs.get(serviceConf.getName()))) {
continue;
}
String dataType = serviceConf.getType();
String defaultValue = serviceConf.getDefaultvalue();
if (stringUtil.isEmpty(defaultValue)) {
defaultValue = getDefaultValueForDataType(dataType);
}
configs.put(serviceConf.getName(), defaultValue);
}
}
service.setType(type);
service.setName(name);
service.setDescription(description);
service.setConfigs(configs);
service.setCreateTime(xAsset.getCreateTime());
service.setUpdateTime(xAsset.getUpdateTime());
XXPortalUser createdByUser = daoMgr.getXXPortalUser().getById(xAsset.getAddedByUserId());
XXPortalUser updByUser = daoMgr.getXXPortalUser().getById(xAsset.getUpdatedByUserId());
if (createdByUser != null) {
service.setCreatedBy(createdByUser.getLoginId());
}
if (updByUser != null) {
service.setUpdatedBy(updByUser.getLoginId());
}
service.setId(xAsset.getId());
return service;
}
private String getDefaultValueForDataType(String dataType) {
String defaultValue = "";
switch (dataType) {
case "int":
defaultValue = "0";
break;
case "string":
defaultValue = "unknown";
break;
case "bool":
defaultValue = "false";
break;
case "enum":
defaultValue = "0";
break;
case "password":
defaultValue = "password";
break;
default:
break;
}
return defaultValue;
}
private RangerPolicy mapXResourceToPolicy(RangerPolicy policy, XXResource xRes, RangerService service) {
String serviceName = service.getName();
String serviceType = service.getType();
String name = xRes.getPolicyName();
String description = xRes.getDescription();
Boolean isAuditEnabled = true;
Boolean isEnabled = true;
Map<String, RangerPolicyResource> resources = new HashMap<String, RangerPolicyResource>();
List<RangerPolicyItem> policyItems = new ArrayList<RangerPolicyItem>();
XXServiceDef svcDef = daoMgr.getXXServiceDef().findByName(serviceType);
if(svcDef == null) {
logger.error(serviceType + ": service-def not found. Skipping policy '" + name + "'");
return null;
}
List<XXAuditMap> auditMapList = daoMgr.getXXAuditMap().findByResourceId(xRes.getId());
if (stringUtil.isEmpty(auditMapList)) {
isAuditEnabled = false;
}
if (xRes.getResourceStatus() == AppConstants.STATUS_DISABLED) {
isEnabled = false;
}
Boolean isPathRecursive = xRes.getIsRecursive() == RangerCommonEnums.BOOL_TRUE;
Boolean isTableExcludes = xRes.getTableType() == RangerCommonEnums.POLICY_EXCLUSION;
Boolean isColumnExcludes = xRes.getColumnType() == RangerCommonEnums.POLICY_EXCLUSION;
if (StringUtils.equalsIgnoreCase(serviceType, "hdfs")) {
toRangerResourceList(xRes.getName(), "path", Boolean.FALSE, isPathRecursive, resources);
} else if (StringUtils.equalsIgnoreCase(serviceType, "hbase")) {
toRangerResourceList(xRes.getTables(), "table", isTableExcludes, Boolean.FALSE, resources);
toRangerResourceList(xRes.getColumnFamilies(), "column-family", Boolean.FALSE, Boolean.FALSE, resources);
toRangerResourceList(xRes.getColumns(), "column", isColumnExcludes, Boolean.FALSE, resources);
} else if (StringUtils.equalsIgnoreCase(serviceType, "hive")) {
toRangerResourceList(xRes.getDatabases(), "database", Boolean.FALSE, Boolean.FALSE, resources);
toRangerResourceList(xRes.getTables(), "table", isTableExcludes, Boolean.FALSE, resources);
toRangerResourceList(xRes.getColumns(), "column", isColumnExcludes, Boolean.FALSE, resources);
toRangerResourceList(xRes.getUdfs(), "udf", Boolean.FALSE, Boolean.FALSE, resources);
} else if (StringUtils.equalsIgnoreCase(serviceType, "knox")) {
toRangerResourceList(xRes.getTopologies(), "topology", Boolean.FALSE, Boolean.FALSE, resources);
toRangerResourceList(xRes.getServices(), "service", Boolean.FALSE, Boolean.FALSE, resources);
} else if (StringUtils.equalsIgnoreCase(serviceType, "storm")) {
toRangerResourceList(xRes.getTopologies(), "topology", Boolean.FALSE, Boolean.FALSE, resources);
}
policyItems = getPolicyItemListForRes(xRes, svcDef);
policy.setService(serviceName);
policy.setName(name);
policy.setDescription(description);
policy.setIsAuditEnabled(isAuditEnabled);
policy.setIsEnabled(isEnabled);
policy.setResources(resources);
policy.setPolicyItems(policyItems);
policy.setCreateTime(xRes.getCreateTime());
policy.setUpdateTime(xRes.getUpdateTime());
XXPortalUser createdByUser = daoMgr.getXXPortalUser().getById(xRes.getAddedByUserId());
XXPortalUser updByUser = daoMgr.getXXPortalUser().getById(xRes.getUpdatedByUserId());
if (createdByUser != null) {
policy.setCreatedBy(createdByUser.getLoginId());
}
if (updByUser != null) {
policy.setUpdatedBy(updByUser.getLoginId());
}
policy.setId(xRes.getId());
return policy;
}
private Map<String, RangerPolicy.RangerPolicyResource> toRangerResourceList(String resourceString, String resourceType, Boolean isExcludes, Boolean isRecursive, Map<String, RangerPolicy.RangerPolicyResource> resources) {
Map<String, RangerPolicy.RangerPolicyResource> ret = resources == null ? new HashMap<String, RangerPolicy.RangerPolicyResource>() : resources;
if(StringUtils.isNotBlank(resourceString)) {
RangerPolicy.RangerPolicyResource resource = ret.get(resourceType);
if(resource == null) {
resource = new RangerPolicy.RangerPolicyResource();
resource.setIsExcludes(isExcludes);
resource.setIsRecursive(isRecursive);
ret.put(resourceType, resource);
}
Collections.addAll(resource.getValues(), resourceString.split(","));
}
return ret;
}
private List<RangerPolicyItem> getPolicyItemListForRes(XXResource xRes, XXServiceDef svcDef) {
List<RangerPolicyItem> policyItems = new ArrayList<RangerPolicyItem>();
SearchCriteria sc = new SearchCriteria();
sc.addParam("resourceId", xRes.getId());
List<VXPermMap> permMapList = xPermMapService.searchXPermMaps(sc).getVXPermMaps();
HashMap<String, List<VXPermMap>> sortedPermMap = new HashMap<String, List<VXPermMap>>();
// re-group the list with permGroup as the key
if (permMapList != null) {
for(VXPermMap permMap : permMapList) {
String permGrp = permMap.getPermGroup();
List<VXPermMap> sortedList = sortedPermMap.get(permGrp);
if(sortedList == null) {
sortedList = new ArrayList<VXPermMap>();
sortedPermMap.put(permGrp, sortedList);
}
sortedList.add(permMap);
}
}
for (Entry<String, List<VXPermMap>> entry : sortedPermMap.entrySet()) {
List<String> userList = new ArrayList<String>();
List<String> groupList = new ArrayList<String>();
List<RangerPolicyItemAccess> accessList = new ArrayList<RangerPolicyItemAccess>();
String ipAddress = null;
RangerPolicy.RangerPolicyItem policyItem = new RangerPolicy.RangerPolicyItem();
for(VXPermMap permMap : entry.getValue()) {
if(permMap.getPermFor() == AppConstants.XA_PERM_FOR_USER) {
String userName = getUserName(permMap);
if (! userList.contains(userName)) {
userList.add(userName);
}
} else if(permMap.getPermFor() == AppConstants.XA_PERM_FOR_GROUP) {
String groupName = getGroupName(permMap);
if (! groupList.contains(groupName)) {
groupList.add(groupName);
}
}
String accessType = ServiceUtil.toAccessType(permMap.getPermType());
if(StringUtils.isBlank(accessType) || unsupportedLegacyPermTypes.contains(accessType)) {
logger.info(accessType + ": is not a valid access-type, ignoring accesstype for policy: " + xRes.getPolicyName());
continue;
}
if(StringUtils.equalsIgnoreCase(accessType, "Admin")) {
policyItem.setDelegateAdmin(Boolean.TRUE);
if ( svcDef.getId() == EmbeddedServiceDefsUtil.instance().getHBaseServiceDefId()) {
addAccessType(accessType, accessList);
}
} else {
addAccessType(accessType, accessList);
}
ipAddress = permMap.getIpAddress();
}
if(CollectionUtils.isEmpty(accessList)) {
logger.info("no access specified. ignoring policyItem for policy: " + xRes.getPolicyName());
continue;
}
if(CollectionUtils.isEmpty(userList) && CollectionUtils.isEmpty(groupList)) {
logger.info("no user or group specified. ignoring policyItem for policy: " + xRes.getPolicyName());
continue;
}
policyItem.setUsers(userList);
policyItem.setGroups(groupList);
policyItem.setAccesses(accessList);
if(ipAddress != null && !ipAddress.isEmpty()) {
XXPolicyConditionDef policyCond = daoMgr.getXXPolicyConditionDef().findByServiceDefIdAndName(svcDef.getId(), "ip-range");
if(policyCond != null) {
RangerPolicy.RangerPolicyItemCondition ipCondition = new RangerPolicy.RangerPolicyItemCondition("ip-range", Collections.singletonList(ipAddress));
policyItem.getConditions().add(ipCondition);
}
}
policyItems.add(policyItem);
}
return policyItems;
}
private void addAccessType(String accessType, List<RangerPolicyItemAccess> accessList) {
boolean alreadyExists = false;
for(RangerPolicyItemAccess access : accessList) {
if(StringUtils.equalsIgnoreCase(accessType, access.getType())) {
alreadyExists = true;
break;
}
}
if(!alreadyExists) {
accessList.add(new RangerPolicyItemAccess(accessType));
}
}
private void updateSequences() {
daoMgr.getXXServiceDef().updateSequence();
daoMgr.getXXService().updateSequence();
daoMgr.getXXPolicy().updateSequence();
}
private String getUserName(VXPermMap permMap) {
String userName = permMap.getUserName();
if(userName == null || userName.isEmpty()) {
Long userId = permMap.getUserId();
if(userId != null) {
XXUser xxUser = daoMgr.getXXUser().getById(userId);
if(xxUser != null) {
userName = xxUser.getName();
}
}
}
return userName;
}
private String getGroupName(VXPermMap permMap) {
String groupName = permMap.getGroupName();
if(groupName == null || groupName.isEmpty()) {
Long groupId = permMap.getGroupId();
if(groupId != null) {
XXGroup xxGroup = daoMgr.getXXGroup().getById(groupId);
if(xxGroup != null) {
groupName = xxGroup.getName();
}
}
}
return groupName;
}
}