diff options
Diffstat (limited to 'controlloop/m2/guard/src/main')
10 files changed, 1006 insertions, 8 deletions
diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java new file mode 100644 index 000000000..0331b7aab --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.function.Supplier; +import org.drools.core.WorkingMemory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CallGuardTask implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(CallGuardTask.class); + + /** + * Actor/recipe pairs whose guard requests need a VF Module count. Each element is of + * the form "<actor>:<recipe>". + */ + private static final Set<String> NEEDS_VF_COUNT = new HashSet<>(); + + /** + * Actor/recipe pairs whose guard requests need the VF Module count to be incremented + * (i.e., because a module is being added). Each element is of the form + * "<actor>:<recipe>". + */ + private static final Set<String> INCR_VF_COUNT = new HashSet<>(); + + static { + INCR_VF_COUNT.add("SO:VF Module Create"); + NEEDS_VF_COUNT.addAll(INCR_VF_COUNT); + } + + private WorkingMemory workingMemory; + private String clname; + private String actor; + private String recipe; + private String target; + private String requestId; + private Integer vfCount; + + /** + * Populated once the response has been determined, which may happen during the + * constructor or later, during {@link #run()}. + */ + private PolicyGuardResponse guardResponse; + + /** + * Guard url is grabbed from PolicyEngine manager properties. + */ + public CallGuardTask(WorkingMemory wm, String cl, String act, + String rec, String tar, String reqId, Supplier<Integer> vfcnt) { + workingMemory = wm; + clname = cl; + actor = act; + recipe = rec; + requestId = reqId; + target = tar; + + vfCount = null; + + String key = act + ":" + rec; + + if (NEEDS_VF_COUNT.contains(key)) { + // this actor/recipe needs the count - get it + if ((vfCount = vfcnt.get()) == null) { + /* + * The count is missing - create an artificial Deny, which will be + * inserted into working memory when "run()" is called. + */ + guardResponse = new PolicyGuardResponse(Util.DENY, UUID.fromString(requestId), recipe); + logger.error("CallGuardTask.run missing VF Module count; requestId={}", requestId); + return; + } + + if (INCR_VF_COUNT.contains(key)) { + // this actor/recipe needs the count to be incremented + ++vfCount; + } + } + } + + @Override + public void run() { + if (guardResponse != null) { + // already have a response - just insert it + workingMemory.insert(guardResponse); + return; + } + + final long startTime = System.nanoTime(); + + PolicyGuardXacmlRequestAttributes xacmlReq = + new PolicyGuardXacmlRequestAttributes(clname, actor, recipe, target, requestId, vfCount); + + logger.debug("\n********** XACML REQUEST START ********"); + logger.debug("{}", xacmlReq); + logger.debug("********** XACML REQUEST END ********\n"); + + String guardDecision = null; + + // + // Make guard request + // + guardDecision = new PolicyGuardXacmlHelper().callPdp(xacmlReq); + + logger.debug("\n********** XACML RESPONSE START ********"); + logger.debug("{}", guardDecision); + logger.debug("********** XACML RESPONSE END ********\n"); + + // + // Check if the restful call was unsuccessful or property doesn't exist + // + if (guardDecision == null) { + logger.error("********** XACML FAILED TO CONNECT ********"); + guardDecision = Util.INDETERMINATE; + } + + guardResponse = new PolicyGuardResponse(guardDecision, UUID.fromString(this.requestId), this.recipe); + + // + // Create an artificial Guard response in case we didn't get a clear Permit or Deny + // + if ("Indeterminate".equals(guardResponse.getResult())) { + guardResponse.setOperation(recipe); + guardResponse.setRequestId(UUID.fromString(requestId)); + } + + long estimatedTime = System.nanoTime() - startTime; + logger.debug("\n\n============ Guard inserted with decision {} !!! =========== time took: {} mili sec \n\n", + guardResponse.getResult(), (double) estimatedTime / 1000 / 1000); + workingMemory.insert(guardResponse); + + } + +} diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/GuardContext.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/GuardContext.java index d41e30cb6..75163e24e 100644 --- a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/GuardContext.java +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/GuardContext.java @@ -31,6 +31,7 @@ import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.drools.core.WorkingMemory; +import org.eclipse.persistence.config.PersistenceUnitProperties; import org.onap.policy.drools.core.PolicyContainer; import org.onap.policy.drools.core.PolicySession; import org.onap.policy.drools.system.PolicyControllerConstants; @@ -48,8 +49,6 @@ import org.slf4j.LoggerFactory; public class GuardContext implements Serializable { private static final long serialVersionUID = 1L; - private static final String ECLIPSE_LINK_KEY_DRIVER = "javax.persistence.jdbc.driver"; - private static Logger logger = LoggerFactory.getLogger(GuardContext.class); // object that should be serialized @@ -158,13 +157,15 @@ public class GuardContext implements Serializable { // extract 'guard.java.persistence.jdbc.*' parameters, // which are all mandatory dbProperties = new Properties(); - setProperty(dbProperties, Util.ONAP_KEY_URL, Util.ECLIPSE_LINK_KEY_URL, sb); - setProperty(dbProperties, Util.ONAP_KEY_USER, Util.ECLIPSE_LINK_KEY_USER, sb); - setProperty(dbProperties, Util.ONAP_KEY_PASS, Util.ECLIPSE_LINK_KEY_PASS, sb); - String driver = properties.getProperty("guard." + ECLIPSE_LINK_KEY_DRIVER); + setProperty(dbProperties, Util.ONAP_KEY_URL, PersistenceUnitProperties.JDBC_URL, sb); + setProperty(dbProperties, Util.ONAP_KEY_USER, PersistenceUnitProperties.JDBC_USER, sb); + setProperty(dbProperties, Util.ONAP_KEY_PASS, PersistenceUnitProperties.JDBC_PASSWORD, sb); + String driver = properties.getProperty("guard." + PersistenceUnitProperties.JDBC_DRIVER); if (driver != null) { - dbProperties.setProperty(ECLIPSE_LINK_KEY_DRIVER, driver); + dbProperties.setProperty(PersistenceUnitProperties.JDBC_DRIVER, driver); } + dbProperties.setProperty(Util.PROP_GUARD_PERSISTENCE_UNIT, + properties.getProperty(Util.PROP_GUARD_PERSISTENCE_UNIT, Util.PU_KEY)); // if there are any errors, update 'errorMessage' & disable guard queries if (sb.length() != 0) { @@ -266,7 +267,8 @@ public class GuardContext implements Serializable { propertiesMap.put("eclipselink.ddl-generation", "create-tables"); // create entity manager factory - emf = Persistence.createEntityManagerFactory("OperationsHistoryPU", propertiesMap); + String persistenceUnit = dbProperties.getProperty(Util.PROP_GUARD_PERSISTENCE_UNIT); + emf = Persistence.createEntityManagerFactory(persistenceUnit, propertiesMap); } // create and return the 'EntityManager' diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/GuardResult.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/GuardResult.java new file mode 100644 index 000000000..6b11c1afa --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/GuardResult.java @@ -0,0 +1,25 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +public enum GuardResult { + LOCK_ACQUIRED, LOCK_DENIED, LOCK_EXCEPTION; +} diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardRequest.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardRequest.java new file mode 100644 index 000000000..8887e00b7 --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardRequest.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import java.util.UUID; + +public class PolicyGuardRequest { + private String actor; + private String target; + private UUID requestId; + private String operation; + + /** + * Construct an instance. + * + * @param actor the actor + * @param target the target + * @param requestId the request Id + * @param operation the operation + */ + public PolicyGuardRequest(String actor, String target, UUID requestId, String operation) { + super(); + this.actor = actor; + this.target = target; + this.requestId = requestId; + this.operation = operation; + } + + @Override + public String toString() { + return "PolicyGuardRequest [actor=" + actor + ", target=" + target + ", requestId=" + requestId + ", operation=" + + operation + "]"; + } + + public String getActor() { + return actor; + } + + public void setActor(String actor) { + this.actor = actor; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public UUID getRequestId() { + return requestId; + } + + public void setRequestId(UUID requestId) { + this.requestId = requestId; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } +} diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardResponse.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardResponse.java new file mode 100644 index 000000000..574c50b79 --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardResponse.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import java.util.UUID; + +public class PolicyGuardResponse { + private UUID requestId; + private String operation; + private String result; + + /** + * Create an instance. + * + * @param result the result + * @param req the request Id + * @param op the operation + */ + public PolicyGuardResponse(String result, UUID req, String op) { + this.result = result; + this.requestId = req; + this.operation = op; + } + + @Override + public String toString() { + return "PolicyGuardResponse [requestId=" + requestId + ", operation=" + operation + ", result=" + result + "]"; + } + + public UUID getRequestId() { + return requestId; + } + + public void setRequestId(UUID requestId) { + this.requestId = requestId; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } +} diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java new file mode 100644 index 000000000..d9ace1d83 --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java @@ -0,0 +1,139 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019 Samsung Electronics Co., Ltd. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.utils.NetLoggerUtil; +import org.onap.policy.common.endpoints.utils.NetLoggerUtil.EventType; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.drools.system.PolicyEngineConstants; +import org.onap.policy.models.decisions.concepts.DecisionRequest; +import org.onap.policy.models.decisions.concepts.DecisionResponse; +import org.onap.policy.rest.RestManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class PolicyGuardXacmlHelper { + private static final Logger logger = LoggerFactory.getLogger(PolicyGuardXacmlHelper.class); + + private String url; + private String user; + private String pwd; + + /** + * Constructor. + */ + public PolicyGuardXacmlHelper() { + this.url = PolicyEngineConstants.getManager().getEnvironmentProperty("guard.url"); + this.user = PolicyEngineConstants.getManager().getEnvironmentProperty("pdpx.username"); + this.pwd = PolicyEngineConstants.getManager().getEnvironmentProperty("pdpx.password"); + } + + /** + * Call PDP. + * + * @param xacmlReq the XACML request + * @return the response + */ + public String callPdp(PolicyGuardXacmlRequestAttributes xacmlReq) { + // + // Create a request suitable for API + // + DecisionRequest decisionRequest = new DecisionRequest(); + decisionRequest.setOnapName("Policy"); + decisionRequest.setOnapComponent("Drools PDP"); + decisionRequest.setOnapInstance("usecase template"); + decisionRequest.setRequestId(UUID.randomUUID().toString()); + decisionRequest.setAction("guard"); + Map<String, String> guard = new HashMap<>(); + guard.put("actor", xacmlReq.getActorId()); + guard.put("operation", xacmlReq.getOperationId()); + guard.put("target", xacmlReq.getTargetId()); + if (xacmlReq.getClnameId() != null) { + guard.put("clname", xacmlReq.getClnameId()); + } + if (xacmlReq.getVfCount() != null) { + guard.put("vfCount", Integer.toString(xacmlReq.getVfCount())); + } + Map<String, Object> resources = new HashMap<>(); + resources.put("guard", guard); + decisionRequest.setResource(resources); + + try { + // + // Call RESTful PDP + // + NetLoggerUtil.log(EventType.OUT, CommInfrastructure.REST, this.url, decisionRequest.toString()); + String response = callRestfulPdp(decisionRequest); + NetLoggerUtil.log(EventType.IN, CommInfrastructure.REST, this.url, response); + + return response; + } catch (Exception e) { + logger.error("Exception in sending RESTful request: ", e); + } + + return Util.DENY; + } + + /** + * This makes an HTTP POST call to a running PDP RESTful servlet to get a decision. + * + * @param decisionRequest The Decision request + * @return response from guard which contains "Permit" or "Deny" + * @throws CoderException Exception when converting to/from JSON the message body + */ + private String callRestfulPdp(DecisionRequest decisionRequest) throws CoderException { + StandardCoder coder = new StandardCoder(); + + String jsonBody = coder.encode(decisionRequest); + RestManager restManager = new RestManager(); + + Map<String, String> headers = new HashMap<>(); + headers.put("Accepts", "application/json"); + + logger.info("Guard Decision Request: {}", jsonBody); + + Pair<Integer, String> httpDetails = restManager.post(url, user, pwd, headers, "application/json", jsonBody); + + if (httpDetails == null) { + logger.error("Guard rest call returned a null pair - defaulting to DENY"); + return Util.DENY; + } + + logger.info("Guard Decision REST Response {} {}", httpDetails.getLeft(), httpDetails.getRight()); + + if (httpDetails.getLeft() == 200) { + DecisionResponse decision = coder.decode(httpDetails.getRight(), DecisionResponse.class); + logger.info("Guard Decision {}", decision); + return decision.getStatus(); + } + + return Util.DENY; + } + +} diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributes.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributes.java new file mode 100644 index 000000000..c888f94c1 --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributes.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import com.att.research.xacml.std.annotations.XACMLAction; +import com.att.research.xacml.std.annotations.XACMLRequest; +import com.att.research.xacml.std.annotations.XACMLResource; +import com.att.research.xacml.std.annotations.XACMLSubject; + +@XACMLRequest(ReturnPolicyIdList = true, CombinedDecision = true) +public class PolicyGuardXacmlRequestAttributes { + + @XACMLSubject(includeInResults = true, attributeId = "urn:org:onap:guard:clname:clname-id") + String clnameId; + + @XACMLSubject(includeInResults = true, attributeId = "urn:org:onap:guard:actor:actor-id") + String actorId; + + @XACMLAction(includeInResults = true, attributeId = "urn:org:onap:guard:operation:operation-id") + String operationId; + + @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:target:target-id") + String targetId; + + @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:request:request-id") + String requestId; + + @XACMLResource(includeInResults = true, attributeId = "urn:org:onap:guard:request:vf-count") + Integer vfCount; + + /** + * Construct an instance. + * + * @param clnameId the control loop Id + * @param actorId the actor Id + * @param operationId the operation Id + * @param targetId the target Id + * @param requestId the request Id + * @param vfCount the new number of VF Modules + */ + public PolicyGuardXacmlRequestAttributes(String clnameId, String actorId, String operationId, String targetId, + String requestId, Integer vfCount) { + super(); + this.clnameId = clnameId; + this.actorId = actorId; + this.operationId = operationId; + this.targetId = targetId; + this.requestId = requestId; + this.vfCount = vfCount; + } + + @Override + public String toString() { + return "PolicyGuardXacmlRequestAttributes [actorId=" + actorId + ", operationId=" + operationId + ", targetId=" + + targetId + ", requestId=" + requestId + "]"; + } + + public String getActorId() { + return actorId; + } + + public void setActorId(String actorId) { + this.actorId = actorId; + } + + public String getOperationId() { + return operationId; + } + + public void setOperationId(String operationId) { + this.operationId = operationId; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getRequestId() { + return requestId; + } + + public void setRequestId(String requestId) { + this.requestId = requestId; + } + + public String getClnameId() { + return clnameId; + } + + public void setClnameId(String clnameId) { + this.clnameId = clnameId; + } + + public Integer getVfCount() { + return vfCount; + } + + public void setVfCount(Integer vfCount) { + this.vfCount = vfCount; + } +} diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardYamlToXacml.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardYamlToXacml.java new file mode 100644 index 000000000..60ccce05d --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/PolicyGuardYamlToXacml.java @@ -0,0 +1,210 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.function.Consumer; +import org.onap.policy.controlloop.policy.guard.Constraint; +import org.onap.policy.controlloop.policy.guard.ControlLoopGuard; +import org.onap.policy.controlloop.policy.guard.GuardPolicy; +import org.onap.policy.controlloop.policy.guard.MatchParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PolicyGuardYamlToXacml { + private static final Logger logger = LoggerFactory.getLogger(PolicyGuardYamlToXacml.class); + + private PolicyGuardYamlToXacml() { + // Construction of this static class is not allowed + } + + /** + * Convert from Yaml to Xacml. + * + * @param yamlFile the Yaml file + * @param xacmlTemplate the Xacml template + * @param xacmlPolicyOutput the Xacml output + */ + public static void fromYamlToXacml(String yamlFile, String xacmlTemplate, String xacmlPolicyOutput) { + fromYamlToXacml(yamlFile, xacmlTemplate, xacmlPolicyOutput, PolicyGuardYamlToXacml::generateXacmlGuard, + constraint -> { + logger.debug("num: {}", constraint.getFreq_limit_per_target()); + logger.debug("duration: {}", constraint.getTime_window()); + logger.debug("time_in_range: {}", constraint.getActive_time_range()); + }); + } + + /** + * Convert from Yaml to Xacml. + * + * @param yamlFile the Yaml file + * @param xacmlTemplate the Xacml template + * @param xacmlPolicyOutput the Xacml output + * @param generator function to generate the yaml from the xacml + * @param logConstraint function to log relevant fields of the constraint + */ + public static void fromYamlToXacml(String yamlFile, String xacmlTemplate, String xacmlPolicyOutput, + Generator generator, Consumer<Constraint> logConstraint) { + + ControlLoopGuard yamlGuardObject = Util.loadYamlGuard(yamlFile); + GuardPolicy guardPolicy = yamlGuardObject.getGuards().get(0); + logger.debug("clname: {}", guardPolicy.getMatch_parameters().getControlLoopName()); + logger.debug("actor: {}", guardPolicy.getMatch_parameters().getActor()); + logger.debug("recipe: {}", guardPolicy.getMatch_parameters().getRecipe()); + Constraint constraint = guardPolicy.getLimit_constraints().get(0); + logConstraint.accept(constraint); + + Path xacmlTemplatePath = Paths.get(xacmlTemplate); + String xacmlTemplateContent; + + try { + xacmlTemplateContent = new String(Files.readAllBytes(xacmlTemplatePath)); + + String xacmlPolicyContent = generator.apply(xacmlTemplateContent, + guardPolicy.getMatch_parameters(), constraint); + + Files.write(Paths.get(xacmlPolicyOutput), xacmlPolicyContent.getBytes()); + + } catch (IOException e) { + logger.error("fromYamlToXacml threw: ", e); + } + } + + /** + * Generate a Xacml guard. + * + * @param xacmlTemplateContent the Xacml template content + * @param matchParameters the paremeters to use + * @param constraint the constraint to use + * @return the guard + */ + private static String generateXacmlGuard(String xacmlTemplateContent, MatchParameters matchParameters, + Constraint constraint) { + + xacmlTemplateContent = doCommonReplacements(xacmlTemplateContent, matchParameters, constraint); + + String targetsRegex = ""; + if (isNullOrEmptyList(matchParameters.getTargets())) { + targetsRegex = ".*"; + } else { + StringBuilder targetsRegexSb = new StringBuilder(); + boolean addBarChar = false; + for (String t : matchParameters.getTargets()) { + targetsRegexSb.append(t); + if (addBarChar) { + targetsRegexSb.append("|"); + } else { + addBarChar = true; + } + } + targetsRegex = targetsRegexSb.toString(); + } + xacmlTemplateContent = xacmlTemplateContent.replace("${targets}", targetsRegex); + + xacmlTemplateContent = xacmlTemplateContent.replace("${limit}", + constraint.getFreq_limit_per_target().toString()); + + xacmlTemplateContent = xacmlTemplateContent.replace("${twValue}", constraint.getTime_window().get("value")); + + xacmlTemplateContent = xacmlTemplateContent.replace("${twUnits}", constraint.getTime_window().get("units")); + + logger.debug(xacmlTemplateContent); + + return xacmlTemplateContent; + } + + private static String doCommonReplacements(String xacmlTemplateContent, MatchParameters matchParameters, + Constraint constraint) { + + replaceNullOrEmpty(matchParameters.getControlLoopName(), matchParameters::setControlLoopName, ".*"); + xacmlTemplateContent = xacmlTemplateContent.replace("${clname}", matchParameters.getControlLoopName()); + + replaceNullOrEmpty(matchParameters.getActor(), matchParameters::setActor, ".*"); + xacmlTemplateContent = xacmlTemplateContent.replace("${actor}", matchParameters.getActor()); + + replaceNullOrEmpty(matchParameters.getRecipe(), matchParameters::setRecipe, ".*"); + xacmlTemplateContent = xacmlTemplateContent.replace("${recipe}", matchParameters.getRecipe()); + + xacmlTemplateContent = xacmlTemplateContent.replace("${guardActiveStart}", + constraint.getActive_time_range().get("start")); + + xacmlTemplateContent = xacmlTemplateContent.replace("${guardActiveEnd}", + constraint.getActive_time_range().get("end")); + + return xacmlTemplateContent; + } + + private static void replaceNullOrEmpty(String text, Consumer<String> replacer, String newValue) { + if (isNullOrEmpty(text)) { + replacer.accept(newValue); + } + } + + public static boolean isNullOrEmpty(String string) { + return string == null || string.trim().isEmpty(); + } + + public static boolean isNullOrEmptyList(List<String> list) { + return list == null || list.isEmpty(); + } + + /** + * Convert from Yaml to Xacml blacklist. + * + * @param yamlFile the Yaml file + * @param xacmlTemplate the Xacml template + * @param xacmlPolicyOutput the Xacml output + */ + public static void fromYamlToXacmlBlacklist(String yamlFile, String xacmlTemplate, String xacmlPolicyOutput) { + fromYamlToXacml(yamlFile, xacmlTemplate, xacmlPolicyOutput, PolicyGuardYamlToXacml::generateXacmlGuardBlacklist, + constraint -> { + logger.debug("freq_limit_per_target: {}", constraint.getFreq_limit_per_target()); + logger.debug("time_window: {}", constraint.getTime_window()); + logger.debug("active_time_range: {}", constraint.getActive_time_range()); + }); + } + + private static String generateXacmlGuardBlacklist(String xacmlTemplateContent, MatchParameters matchParameters, + Constraint constraint) { + + String result = doCommonReplacements(xacmlTemplateContent, matchParameters, constraint); + + for (String target : constraint.getBlacklist()) { + result = result.replace("${blackListElement}", + "<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">" + target + + "</AttributeValue>" + "\n\t\t\t\t\t\t\\${blackListElement}\n"); + } + + result = result.replace("\t\t\t\t\t\t\\${blackListElement}\n", ""); + + return result; + } + + @FunctionalInterface + private static interface Generator { + public String apply(String xacmlTemplateContent, MatchParameters matchParameters, + Constraint constraint); + } +} diff --git a/controlloop/m2/guard/src/main/java/org/onap/policy/guard/Util.java b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/Util.java new file mode 100644 index 000000000..d1eed1bb4 --- /dev/null +++ b/controlloop/m2/guard/src/main/java/org/onap/policy/guard/Util.java @@ -0,0 +1,146 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import org.apache.commons.io.IOUtils; +import org.onap.policy.controlloop.policy.ControlLoopPolicy; +import org.onap.policy.controlloop.policy.guard.ControlLoopGuard; +import org.onap.policy.drools.system.PolicyEngineConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +public final class Util { + /* + * Keys for guard properties + */ + public static final String PROP_GUARD_URL = "guard.url"; + public static final String PROP_GUARD_USER = "pdpx.username"; + public static final String PROP_GUARD_PASS = "pdpx.password"; + public static final String PROP_GUARD_DISABLED = "guard.disabled"; + public static final String PROP_GUARD_PERSISTENCE_UNIT = "guard.persistenceUnit"; + + /* + * Keys for ONAP properties + */ + public static final String ONAP_KEY_URL = "guard.jdbc.url"; + public static final String ONAP_KEY_USER = "sql.db.username"; + public static final String ONAP_KEY_PASS = "sql.db.password"; + + /* + * Guard responses + */ + public static final String INDETERMINATE = "Indeterminate"; + public static final String PERMIT = "Permit"; + public static final String DENY = "Deny"; + + /* + * Junit props + */ + protected static final String PU_KEY = "OperationsHistoryPU"; + protected static final String JUNITPU = "OperationsHistoryPUTest"; + + private static final Logger logger = LoggerFactory.getLogger(Util.class); + + public static class Pair<A, B> { + public final A parameterA; + public final B parameterB; + + public Pair(A parameterA, B parameterB) { + this.parameterA = parameterA; + this.parameterB = parameterB; + } + } + + private Util() { + // This static class cannot be instantiated + } + + /** + * Load a Yaml file. + * + * @param testFile the Yaml file + * @return the policies + */ + public static Pair<ControlLoopPolicy, String> loadYaml(String testFile) { + try (InputStream is = new FileInputStream(new File(testFile))) { + String contents = IOUtils.toString(is, StandardCharsets.UTF_8); + // + // Read the yaml into our Java Object + // + Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class)); + Object obj = yaml.load(contents); + + logger.debug(contents); + + return new Pair<>((ControlLoopPolicy) obj, contents); + } catch (IOException e) { + logger.error(e.getLocalizedMessage(), e); + } + return null; + } + + /** + * Load a Yaml guard. + * + * @param testFile the Yaml file + * @return the guard + */ + public static ControlLoopGuard loadYamlGuard(String testFile) { + try (InputStream is = new FileInputStream(new File(testFile))) { + String contents = IOUtils.toString(is, StandardCharsets.UTF_8); + // + // Read the yaml into our Java Object + // + Yaml yaml = new Yaml(new Constructor(ControlLoopGuard.class)); + Object obj = yaml.load(contents); + return (ControlLoopGuard) obj; + } catch (IOException e) { + logger.error(e.getLocalizedMessage(), e); + } + return null; + } + + /** + * Sets Guard Properties. + * + * <p>see /guard/src/test/java/org/onap/policy/guard/UtilTest.java for setting test properties + */ + public static void setGuardEnvProps(String url, String username, String password) { + PolicyEngineConstants.getManager().setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_URL, url); + PolicyEngineConstants.getManager().setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_USER, username); + PolicyEngineConstants.getManager().setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_PASS, password); + } + + public static void setGuardEnvProp(String key, String value) { + PolicyEngineConstants.getManager().setEnvironmentProperty(key, value); + } + + public static String getGuardProp(String propName) { + return PolicyEngineConstants.getManager().getEnvironmentProperty(propName); + } +} diff --git a/controlloop/m2/guard/src/main/resources/META-INF/persistence.xml b/controlloop/m2/guard/src/main/resources/META-INF/persistence.xml new file mode 100644 index 000000000..cf7e28190 --- /dev/null +++ b/controlloop/m2/guard/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + ============LICENSE_START======================================================= + drools-applications + ================================================================================ + Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Licensed 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. + ============LICENSE_END========================================================= + --> +<persistence xmlns="http://java.sun.com/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence + http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> + + <persistence-unit name="OperationsHistoryPU" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + + <class>org.onap.policy.guard.OperationsHistory</class> + + <properties> + <property name="eclipselink.ddl-generation" value="create-tables"/> + <property name="eclipselink.logging.level" value="INFO" /> + <property name="javax.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:mariadb://mariadb:3306/operationshistory"/> + <property name="javax.persistence.jdbc.user" value="policy_user"/> + <property name="javax.persistence.jdbc.password" value="cG9saWN5X3VzZXI="/> + <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/> + <property name="javax.persistence.schema-generation.create-source" value="metadata"/> + </properties> + </persistence-unit> + +</persistence> |