diff options
Diffstat (limited to 'onap-dcae-dcaepolicy-lib')
-rw-r--r-- | onap-dcae-dcaepolicy-lib/LICENSE.txt | 30 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/MANIFEST.in | 1 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/README.md | 293 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py | 22 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py | 200 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/pom.xml | 247 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/requirements.txt | 1 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/setup.py | 39 | ||||
-rw-r--r-- | onap-dcae-dcaepolicy-lib/tox.ini | 11 |
9 files changed, 844 insertions, 0 deletions
diff --git a/onap-dcae-dcaepolicy-lib/LICENSE.txt b/onap-dcae-dcaepolicy-lib/LICENSE.txt new file mode 100644 index 0000000..45ec201 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/LICENSE.txt @@ -0,0 +1,30 @@ +============LICENSE_START======================================================= +org.onap.dcae +================================================================================ +Copyright (c) 2017 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========================================================= +ECOMP is a trademark and service mark of AT&T Intellectual Property. + +Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +================================================================================ +Licensed under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +you may not use this documentation except in compliance with the License. +You may obtain a copy of the License at + https://creativecommons.org/licenses/by/4.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. diff --git a/onap-dcae-dcaepolicy-lib/MANIFEST.in b/onap-dcae-dcaepolicy-lib/MANIFEST.in new file mode 100644 index 0000000..f9bd145 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/MANIFEST.in @@ -0,0 +1 @@ +include requirements.txt diff --git a/onap-dcae-dcaepolicy-lib/README.md b/onap-dcae-dcaepolicy-lib/README.md new file mode 100644 index 0000000..71fdc6a --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/README.md @@ -0,0 +1,293 @@ +# onap_dcae_dcaepolicy_lib - policy in dcae controller +- python-package to be used in cloudify plugins to maintain the policies lifecycle + +## [setup pypi connection](./nexus_pypi.md) to **nexus** repo server + +## build = register and upload to nexus repo server + +```bash +./dev_run.sh build +``` + +## upload the python package to nexus repo server + +```bash +./dev_run.sh upload +``` + +--- +# usage in plugins + +**requirements.txt** +```python +--extra-index-url https://YOUR_NEXUS_PYPI_SERVER/simple +onap-dcae-dcaepolicy-lib +``` + +**tasks.py** +- import + +```python +from onap_dcae_dcaepolicy_lib import Policies +``` + +# examples of **@operation** with **@Policies.<>** decorator + +## Usage + +import the dcaepolicy-node-type.yaml into your blueprint to use the dcae.nodes.type node + +```yaml +imports: + - https://YOUR_NEXUS_RAW_SERVER/type_files/dcaepolicy/1.0.0/node-type.yaml +``` + +provide the value for policy_id property + +```yaml +node_templates: +... + host_capacity_policy: + type: dcae.nodes.policy + properties: + policy_id: { get_input: host_capacity_policy_id } +``` + +Then the dcaepolicyplugin will bring the latest policy to the dcae.nodes.policy node during the install workflow of cloudify. + +------ +## cloudify.interfaces.lifecycle.**configure** +- gather policy data into runtime_properties of policy consumer node +```yaml +cloudify.interfaces.lifecycle: + configure: + implementation: dcae_policy_plugin.onap_dcae_dcaepolicy_lib.node_configure +``` + +```python +from onap_dcae_dcaepolicy_lib import Policies, POLICIES +from .discovery import DiscoveryClient +from .demo_app import DemoApp + +APPLICATION_CONFIG = "application_config" +SERVICE_COMPONENT_NAME = "service_component_name" + +@operation +@Policies.gather_policies_to_node +def node_configure(**kwargs): + """decorate with @Policies.gather_policies_to_node on policy consumer node to + prepopulate runtime_properties[POLICIES] + """ + app_config = None + if APPLICATION_CONFIG in ctx.node.properties: + # dockerized blueprint puts the app config into property application_config + app_config = ctx.node.properties.get(APPLICATION_CONFIG) + else: + # CDAP components expect that in property app_config + app_config = ctx.node.properties.get("app_config") + + app_config = Policies.shallow_merge_policies_into(app_config) + ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config + ctx.logger.info("example: applied policy_configs to property app_config: {0}" \ + .format(json.dumps(app_config))) + + if SERVICE_COMPONENT_NAME in ctx.instance.runtime_properties: + ctx.logger.info("saving app_config({0}) to consul under key={1}" \ + .format(json.dumps(app_config), \ + ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME])) + DiscoveryClient.put_kv(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME], app_config) + + # alternative 1 - use the list of policy configs from policies in runtime_properties + policy_configs = Policies.get_policy_configs() + if policy_configs: + ctx.logger.warn("TBD: apply policy_configs: {0}".format(json.dumps(policy_configs))) + + # alternative 2 - use the policies dict by policy_id from runtime_properties + if POLICIES in ctx.instance.runtime_properties: + policies = ctx.instance.runtime_properties[POLICIES] + ctx.logger.warn("TBD: apply policies: {0}".format(json.dumps(policies))) + + ctx.logger.info("deploying the demo component: {0}...".format(ctx.node.id)) + demo_app = DemoApp(ctx.node.id) + demo_app.start() + ctx.logger.info("deployed the demo component: {0}".format(demo_app.container_id)) + demo_app.get_logs() +``` + +------ +## execute-operation **policy-update** +```yaml +dcae.interfaces.policy: + policy_update: + implementation: dcae_policy_plugin.onap_dcae_dcaepolicy_lib.policy_update +``` + +execute-operation **policy-update** that gets a list of changed policy-configs +```python + +from .discovery import DiscoveryClient +from .demo_app import DemoApp + +APPLICATION_CONFIG = "application_config" +SERVICE_COMPONENT_NAME = "service_component_name" + +@operation +@Policies.update_policies_on_node(configs_only=True) +def policy_update(updated_policies, **kwargs): + """decorate with @Policies.update_policies_on_node() to update runtime_properties[POLICIES] + + :updated_policies: contains the list of changed policy-configs when configs_only=True (default). + Use configs_only=False to bring the full policy objects in :updated_policies:. + """ + app_config = DiscoveryClient.get_value(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME]) + + # This is how to merge the policies into app_config object + app_config = Policies.shallow_merge_policies_into(app_config) + + ctx.logger.info("merged updated_policies {0} into app_config {1}" + .format(json.dumps(updated_policies), json.dumps(app_config))) + + ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config + + DiscoveryClient.put_kv(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME], app_config) + + # example how to notify the dockerized component about the policy change + notify_app_through_script = True + if notify_app_through_script: + ctx.logger.info("notify dockerized app about updated_policies {0} and app_config {1}" + .format(json.dumps(updated_policies), json.dumps(app_config))) + demo_app = DemoApp(ctx.node.id) + demo_app.notify_app_through_script( + POLICY_MESSAGE_TYPE, + updated_policies=updated_policies, + application_config=app_config + ) +``` + +example of the **changed\_policies** with **configs_only=True** +- list of config objects (preparsed from json string) +- manual mess produced by mock_policy_updater +```json +[{ + "policy_updated_from_ver": "2", + "policy_updated_to_ver": "3", + "updated_policy_id": "DCAE_alex.Config_db_client_policy_id_value", + "policy_hello": "world!", + "policy_updated_ts": "2017-08-17T21:49:39.279187Z" +}] +``` +--- + +example of **policies** in runtime_properties **before policy-update** + +```json +"runtime_properties": { + "execute_operation": "policy_update", + "service_component_name": "some-uuid.unknown.unknown.unknown.dcae.ecomp.company.com", + "application_config": { + "policy_hello": "world!", + "db": { + "type": "db", + "input_db_port": 5555, + "database_port": 5555 + }, + "policy_updated_from_ver": "1", + "intention": "policies are shallow merged to the copy of the application_config", + "updated_policy_id": "DCAE_alex.Config_db_client_policy_id_value", + "client": { + "client_version": "1.2.2", + "type": "client", + "client_policy_id": "DCAE_alex.Config_db_client_policy_id_value" + }, + "policy_updated_ts": "2017-08-17T21:13:47.268782Z", + "policy_updated_to_ver": "2" + }, + "exe_task": "node_configure", + "policies": { + "DCAE_alex.Config_db_client_policy_id_value": { + "policy_apply_mode": "script", + "policy_body": { + "policyName": "DCAE_alex.Config_db_client_policy_id_value.2.xml", + "policyConfigMessage": "Config Retrieved! ", + "responseAttributes": { + + }, + "policyConfigStatus": "CONFIG_RETRIEVED", + "matchingConditions": { + "ECOMPName": "DCAE", + "ConfigName": "alex_config_name" + }, + "type": "OTHER", + "property": null, + "config": { + "policy_updated_from_ver": "1", + "policy_updated_to_ver": "2", + "updated_policy_id": "DCAE_alex.Config_db_client_policy_id_value", + "policy_hello": "world!", + "policy_updated_ts": "2017-08-17T21:13:47.268782Z" + }, + "policyVersion": "2" + }, + "policy_id": "DCAE_alex.Config_db_client_policy_id_value" + } + } +} +``` + +example of **policies** in runtime_properties **after policy-update** + +```json +"runtime_properties": { + "execute_operation": "policy_update", + "service_component_name": "some-uuid.unknown.unknown.unknown.dcae.ecomp.company.com", + "application_config": { + "policy_hello": "world!", + "db": { + "input_db_port": 5555, + "type": "db", + "database_port": 5555 + }, + "policy_updated_ts": "2017-08-17T21:49:39.279187Z", + "policy_updated_from_ver": "2", + "intention": "policies are shallow merged to the copy of the application_config", + "client": { + "client_version": "1.2.2", + "type": "client", + "client_policy_id": "DCAE_alex.Config_db_client_policy_id_value" + }, + "updated_policy_id": "DCAE_alex.Config_db_client_policy_id_value", + "policy_updated_to_ver": "3" + }, + "exe_task": "node_configure", + "policies": { + "DCAE_alex.Config_db_client_policy_id_value": { + "policy_apply_mode": "script", + "policy_body": { + "policyName": "DCAE_alex.Config_db_client_policy_id_value.3.xml", + "policyConfigMessage": "Config Retrieved! ", + "responseAttributes": { + + }, + "policyConfigStatus": "CONFIG_RETRIEVED", + "matchingConditions": { + "ECOMPName": "DCAE", + "ConfigName": "alex_config_name" + }, + "type": "OTHER", + "property": null, + "config": { + "policy_updated_from_ver": "2", + "policy_updated_to_ver": "3", + "updated_policy_id": "DCAE_alex.Config_db_client_policy_id_value", + "policy_hello": "world!", + "policy_updated_ts": "2017-08-17T21:49:39.279187Z" + }, + "policyVersion": "3" + }, + "policy_id": "DCAE_alex.Config_db_client_policy_id_value" + } + } +} +``` + +---
\ No newline at end of file diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py new file mode 100644 index 0000000..b3658b1 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py @@ -0,0 +1,22 @@ +"""expose the Policies class on the package level""" + +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2017 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========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +from .dcae_policy import Policies, POLICIES, POLICY_MESSAGE_TYPE diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py new file mode 100644 index 0000000..d64d50f --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py @@ -0,0 +1,200 @@ +"""dcae_policy contains decorators for the policy lifecycle in cloudify""" + +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2017 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========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +import json +import copy +from functools import wraps + +from cloudify import ctx +from cloudify.context import NODE_INSTANCE +from cloudify.exceptions import NonRecoverableError + +POLICIES = 'policies' + +POLICY_ID = 'policy_id' +POLICY_APPLY_MODE = 'policy_apply_mode' +POLICY_BODY = 'policy_body' +POLICY_VERSION = "policyVersion" +POLICY_CONFIG = 'config' +DCAE_POLICY_TYPE = 'dcae.nodes.policy' +POLICY_MESSAGE_TYPE = 'policy' + +class Policies(object): + """static class for policy operations""" + + @staticmethod + def gather_policies_to_node(func): + """decorate with @Policies.gather_policies_to_node to + gather the policies from dcae.nodes.policy nodes this node depends on. + + Places the policies into runtime_properties["policies"]. + + Call Policies.shallow_merge_policies_into(config) to merge the policies into config. + """ + def _merge_policy_with_node(target): + """get all properties of the policy node and add the actual policy""" + policy = dict(target.node.properties) + if POLICY_BODY in target.instance.runtime_properties: + policy[POLICY_BODY] = target.instance.runtime_properties[POLICY_BODY] + return policy + + if not func: + return + + @wraps(func) + def wrapper(*args, **kwargs): + """gather and save the policies from dcae.nodes.policy nodes this node related to""" + try: + if ctx.type == NODE_INSTANCE: + policies = dict([(rel.target.node.properties[POLICY_ID], \ + _merge_policy_with_node(rel.target)) \ + for rel in ctx.instance.relationships \ + if DCAE_POLICY_TYPE in rel.target.node.type_hierarchy \ + and POLICY_ID in rel.target.node.properties \ + and rel.target.node.properties[POLICY_ID] \ + ]) + if policies: + ctx.instance.runtime_properties[POLICIES] = policies + except Exception as ex: + error = "Failed to set the policies {0}".format(str(ex)) + ctx.logger.error(error) + raise NonRecoverableError(error) + + return func(*args, **kwargs) + return wrapper + + @staticmethod + def _update_policies_on_ctx(updated_policies): + """update policies in runtime_properties and return changed_policies""" + if POLICIES not in ctx.instance.runtime_properties: + return + if not updated_policies: + ctx.logger.error("update_policies_on_ctx - no updated_policies provided in arguments") + return + + policies = ctx.instance.runtime_properties[POLICIES] + ctx.logger.info("update_policies_on_ctx: {0}".format(json.dumps(updated_policies))) + changed_policies = [] + ignored_policies = [] + unexpected_policies = [] + same_policies = [] + for policy in updated_policies: + if POLICY_ID not in policy or policy[POLICY_ID] not in policies: + ignored_policies.append(policy) + continue + if POLICY_BODY not in policy or POLICY_VERSION not in policy[POLICY_BODY] \ + or not policy[POLICY_BODY][POLICY_VERSION]: + unexpected_policies.append(policy) + continue + + deployed_policy = policies[policy[POLICY_ID]].get(POLICY_BODY, {}) + new_policy_body = policy[POLICY_BODY] + if not deployed_policy or POLICY_VERSION not in deployed_policy \ + or not deployed_policy[POLICY_VERSION] \ + or deployed_policy[POLICY_VERSION] != new_policy_body[POLICY_VERSION]: + policies[policy[POLICY_ID]][POLICY_BODY] = new_policy_body + changed_policies.append(dict(policies[policy[POLICY_ID]])) + else: + same_policies.append(policy) + + if same_policies: + ctx.logger.info("same policies: {0}".format(json.dumps(same_policies))) + if ignored_policies: + ctx.logger.info("ignored policies: {0}".format(json.dumps(ignored_policies))) + if unexpected_policies: + ctx.logger.warn("unexpected policies: {0}".format(json.dumps(unexpected_policies))) + + if changed_policies: + ctx.instance.runtime_properties[POLICIES] = policies + return changed_policies + + @staticmethod + def update_policies_on_node(configs_only=True): + """decorate each policy_update operation with @Policies.update_policies_on_node to + filter out the updated_policies to only what applies to the current node instance, + update runtime_properties["policies"] + + :configs_only: - set to True if expect to see only the config in updated_policies + instead of the whole policy object (False) + + Passes through the filtered list of updated_policies that apply to the current node instance + + :updated_policies: contains the list of changed policy-configs when configs_only=True. + """ + def update_policies_decorator(func): + """actual decorator""" + if not func: + return + + @wraps(func) + def wrapper(updated_policies, **kwargs): + """update matching policies on context""" + if ctx.type != NODE_INSTANCE: + return + + updated_policies = Policies._update_policies_on_ctx(updated_policies) + if updated_policies: + if configs_only: + updated_policies = [policy[POLICY_BODY][POLICY_CONFIG] \ + for policy in updated_policies \ + if POLICY_BODY in policy \ + and POLICY_CONFIG in policy[POLICY_BODY] \ + ] + return func(updated_policies, **kwargs) + return wrapper + return update_policies_decorator + + + @staticmethod + def get_policy_configs(): + """returns the list of policy configs from the runtime policies""" + if ctx.type != NODE_INSTANCE \ + or POLICIES not in ctx.instance.runtime_properties: + return + policies = ctx.instance.runtime_properties[POLICIES] + if not policies: + return + policy_configs = [policies[policy_id][POLICY_BODY][POLICY_CONFIG] \ + for policy_id in policies \ + if POLICY_BODY in policies[policy_id] \ + and POLICY_CONFIG in policies[policy_id][POLICY_BODY] \ + ] + return policy_configs + + @staticmethod + def shallow_merge_policies_into(config): + """shallow merge the policy configs (dict) into config that is expected to be a dict""" + if config is None: + config = {} + policy_configs = Policies.get_policy_configs() + if not policy_configs or not isinstance(config, dict): + return config + + for policy_config in copy.deepcopy(policy_configs): + if not isinstance(policy_config, dict): + continue + + config.update(policy_config) + for cfg_item in policy_config: + if policy_config[cfg_item] is None: + config.pop(cfg_item, None) + + return config diff --git a/onap-dcae-dcaepolicy-lib/pom.xml b/onap-dcae-dcaepolicy-lib/pom.xml new file mode 100644 index 0000000..642ed5d --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/pom.xml @@ -0,0 +1,247 @@ +<?xml version="1.0"?> +<!-- +================================================================================ +Copyright (c) 2017 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========================================================= + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.dcaegen2.utils</groupId> + <artifactId>utils</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + <groupId>org.onap.dcaegen2.utils</groupId> + <artifactId>onap-dcae-dcaepolicy-lib</artifactId> + <name>dcaegen2-utils-onap-dcae-dcaepolicy-lib</name> + <version>1.0.0-SNAPSHOT</version> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <sonar.sources>.</sonar.sources> + <!-- customize the SONARQUBE URL --> + <!-- sonar.host.url>http://localhost:9000</sonar.host.url --> + <!-- below are language dependent --> + <!-- for Python --> + <sonar.language>py</sonar.language> + <sonar.pluginName>Python</sonar.pluginName> + <sonar.inclusions>**/*.py</sonar.inclusions> + <!-- for JavaScaript --> + <!-- + <sonar.language>js</sonar.language> + <sonar.pluginName>JS</sonar.pluginName> + <sonar.inclusions>**/*.js</sonar.inclusions> + --> + </properties> + <build> + <finalName>${project.artifactId}-${project.version}</finalName> + <pluginManagement> + <plugins> + <!-- the following plugins are invoked from oparent, we do not need them --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.7</version> + <configuration> + <skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <!-- This version supports the "deployAtEnd" parameter --> + <version>2.8</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- first disable the default Java plugins at various stages --> + <!-- maven-resources-plugin is called during "*resource" phases by default behavior. it prepares + the resources dir. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- maven-compiler-plugin is called during "compile" phases by default behavior. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- maven-jar-plugin is called during "compile" phase by default behavior. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>2.4</version> + <executions> + <execution> + <id>default-jar</id> + <phase/> + </execution> + </executions> + </plugin> + <!-- maven-install-plugin is called during "install" phase by default behavior. it tries to copy stuff under + target dir to ~/.m2. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>2.4</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- maven-surefire-plugin is called during "test" phase by default behavior. it triggers junit test. + we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.12.4</version> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </pluginManagement> + <plugins> + <!-- plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.4.1</version> + <configuration> + <descriptors> + <descriptor>assembly/dep.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin --> + <!-- now we configure custom action (calling a script) at various lifecycle phases --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>1.2.1</version> + <executions> + <execution> + <id>clean phase script</id> + <phase>clean</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>clean</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>generate-sources script</id> + <phase>generate-sources</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>generate-sources</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>compile script</id> + <phase>compile</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>compile</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>package script</id> + <phase>package</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>package</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>test script</id> + <phase>test</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>test</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>install script</id> + <phase>install</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>install</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>deploy script</id> + <phase>deploy</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>deploy</argument> + </arguments> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/onap-dcae-dcaepolicy-lib/requirements.txt b/onap-dcae-dcaepolicy-lib/requirements.txt new file mode 100644 index 0000000..2f98303 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/requirements.txt @@ -0,0 +1 @@ +# - not here because cloudify provides it: cloudify-plugins-common==3.4 diff --git a/onap-dcae-dcaepolicy-lib/setup.py b/onap-dcae-dcaepolicy-lib/setup.py new file mode 100644 index 0000000..b149729 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/setup.py @@ -0,0 +1,39 @@ +"""setup.py is used for package build and distribution""" + +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2017 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========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +from setuptools import setup + +setup( + name='onap_dcae_dcaepolicy_lib', + description='lib of policy decorators to be used by cloudify plugins of dcae controller', + version="1.0.0", + author='Alex Shatov', + email="dcae@lists.openecomp.org", + packages=['onap_dcae_dcaepolicy_lib'], + install_requires=[ + ], + keywords='policy dcae controller cloudify plugin', + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'Programming Language :: Python :: 2.7' + ] +) diff --git a/onap-dcae-dcaepolicy-lib/tox.ini b/onap-dcae-dcaepolicy-lib/tox.ini new file mode 100644 index 0000000..987b009 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/tox.ini @@ -0,0 +1,11 @@ +# content of: tox.ini , put in same dir as setup.py +[tox] +envlist = py27,py35 + +[testenv] +deps= + -rrequirements.txt + pytest + coverage + pytest-cov +commands=pytest --junitxml xunit-results.xml --cov {envsitepackagesdir} --cov-report=xml |