From f8cc775377d2fe0286c526d5d293ea50945cc744 Mon Sep 17 00:00:00 2001 From: Edward Medvedev Date: Fri, 11 Nov 2016 15:50:52 +0700 Subject: [PATCH 01/45] Initial commit --- .gitignore | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 91 insertions(+) create mode 100644 .gitignore create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..72364f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,89 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject diff --git a/README.md b/README.md new file mode 100644 index 0000000..a45b698 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# exchange-incubator +An incubator repo From d459ed46e943790ebbd355a5bd49e12bfaa1d91c Mon Sep 17 00:00:00 2001 From: Edward Medvedev Date: Fri, 11 Nov 2016 16:31:09 +0700 Subject: [PATCH 02/45] Update README.md --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a45b698..c7c952e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,12 @@ -# exchange-incubator -An incubator repo +# StackStorm Exchange Incubator + +### What is this? + +This repository is a very special place where user-submitted packs get reviewed, perfected, approved, and finally transferred to the Exchange. + +If you want to submit your pack, it's simple! **Fork this repo, create a subdirectory with your pack, and open a Pull Request.** We'll take it from here. Pro-tip: if you've been working on your pack for quite a while already, and want your git history and versioning preserved, add your pack repo as a submodule. + +Even if your pack is work-in-progress, you can still submit it to get advice and early feedback from our engineers! Or ping us [on Slack](https://stackstorm.com/community-signup), which is generally the best place to get advice from the StackStorm Community. + +Before you submit a pack, make sure to read the [Create and Contribute a Pack](https://docs.stackstorm.com/reference/packs.html) section of our documentation. + From 89cbcc0a6e373e3a53daccf6a916be2942811c01 Mon Sep 17 00:00:00 2001 From: Edward Medvedev Date: Fri, 11 Nov 2016 23:54:26 +0700 Subject: [PATCH 03/45] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c7c952e..0389145 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,6 @@ Even if your pack is work-in-progress, you can still submit it to get advice and Before you submit a pack, make sure to read the [Create and Contribute a Pack](https://docs.stackstorm.com/reference/packs.html) section of our documentation. +Here's N.E.P.T.R. the StackStorm Exchange Ruler, giving you a thumbs-up: + +![](http://imgur.com/a/KM0cw) From 9cb07fdcbec98cf17e7d60851df07ccdcf7abe92 Mon Sep 17 00:00:00 2001 From: Edward Medvedev Date: Fri, 11 Nov 2016 23:55:01 +0700 Subject: [PATCH 04/45] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0389145..1e41d76 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,6 @@ Even if your pack is work-in-progress, you can still submit it to get advice and Before you submit a pack, make sure to read the [Create and Contribute a Pack](https://docs.stackstorm.com/reference/packs.html) section of our documentation. -Here's N.E.P.T.R. the StackStorm Exchange Ruler, giving you a thumbs-up: +Here's N.E.P.T.R. the StackStorm Exchange Governor, giving you a thumbs-up: -![](http://imgur.com/a/KM0cw) +![](http://i.imgur.com/3bqVAh0.gif) From 6a4351745056f4a4b78f5bbee016942d51a15e91 Mon Sep 17 00:00:00 2001 From: Edward Medvedev Date: Sat, 12 Nov 2016 00:41:18 +0700 Subject: [PATCH 05/45] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1e41d76..675a88d 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ This repository is a very special place where user-submitted packs get reviewed, perfected, approved, and finally transferred to the Exchange. -If you want to submit your pack, it's simple! **Fork this repo, create a subdirectory with your pack, and open a Pull Request.** We'll take it from here. Pro-tip: if you've been working on your pack for quite a while already, and want your git history and versioning preserved, add your pack repo as a submodule. +If you want to submit your pack, it's simple! **Fork this repo, create a subdirectory with your pack, and open a Pull Request.** We'll take it from here. Even if your pack is work-in-progress, you can still submit it to get advice and early feedback from our engineers! Or ping us [on Slack](https://stackstorm.com/community-signup), which is generally the best place to get advice from the StackStorm Community. -Even if your pack is work-in-progress, you can still submit it to get advice and early feedback from our engineers! Or ping us [on Slack](https://stackstorm.com/community-signup), which is generally the best place to get advice from the StackStorm Community. +**Pro-tip:** if you've been working on your pack for quite a while already, and want your git history and versioning preserved, add your pack repo as a submodule. Before you submit a pack, make sure to read the [Create and Contribute a Pack](https://docs.stackstorm.com/reference/packs.html) section of our documentation. From 929fd91864aa4187defe7be07cf357afaa901651 Mon Sep 17 00:00:00 2001 From: "Dmitri Zimin(e)" Date: Fri, 2 Dec 2016 20:58:49 -0800 Subject: [PATCH 06/45] Add contribution license agreement. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 675a88d..bb1489d 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,9 @@ Before you submit a pack, make sure to read the [Create and Contribute a Pack](h Here's N.E.P.T.R. the StackStorm Exchange Governor, giving you a thumbs-up: ![](http://i.imgur.com/3bqVAh0.gif) + +## Contributors License Agreement + +By contributing you agree that these contributions are your own (or approved by your employer) and +you grant a full, complete, irrevocable copyright license to all users and developers of the +project, present and future, pursuant to the license of the project. From 97892ee0756ab7afa24612ea8e935520696e5d44 Mon Sep 17 00:00:00 2001 From: Daniel Chamot Date: Wed, 26 Apr 2017 09:52:30 +0200 Subject: [PATCH 07/45] remove lib/ from .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 72364f9..a76c9cc 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ lib64/ parts/ sdist/ From 82cca0220189629ef3867bd6e717aa553bbc8d4a Mon Sep 17 00:00:00 2001 From: Daniel Chamot Date: Wed, 26 Apr 2017 09:53:21 +0200 Subject: [PATCH 08/45] Foreman Integration Pack --- stackstorm-foreman/LICENSE | 13 ++ stackstorm-foreman/README.md | 173 ++++++++++++++++++ stackstorm-foreman/actions/create_host.py | 23 +++ stackstorm-foreman/actions/create_host.yaml | 25 +++ stackstorm-foreman/actions/foreman_hosts.py | 9 + stackstorm-foreman/actions/foreman_hosts.yaml | 20 ++ stackstorm-foreman/actions/lib/__init__.py | 1 + stackstorm-foreman/actions/lib/foreman.py | 108 +++++++++++ stackstorm-foreman/actions/power_host.py | 11 ++ stackstorm-foreman/actions/power_host.yaml | 21 +++ stackstorm-foreman/actions/puppet_hosts.py | 9 + stackstorm-foreman/actions/puppet_hosts.yaml | 23 +++ stackstorm-foreman/config.schema.yaml | 18 ++ stackstorm-foreman/foreman.example.yaml | 7 + stackstorm-foreman/pack.yaml | 10 + stackstorm-foreman/requirements.txt | 1 + 16 files changed, 472 insertions(+) create mode 100644 stackstorm-foreman/LICENSE create mode 100644 stackstorm-foreman/README.md create mode 100644 stackstorm-foreman/actions/create_host.py create mode 100644 stackstorm-foreman/actions/create_host.yaml create mode 100644 stackstorm-foreman/actions/foreman_hosts.py create mode 100644 stackstorm-foreman/actions/foreman_hosts.yaml create mode 100644 stackstorm-foreman/actions/lib/__init__.py create mode 100644 stackstorm-foreman/actions/lib/foreman.py create mode 100644 stackstorm-foreman/actions/power_host.py create mode 100644 stackstorm-foreman/actions/power_host.yaml create mode 100644 stackstorm-foreman/actions/puppet_hosts.py create mode 100644 stackstorm-foreman/actions/puppet_hosts.yaml create mode 100644 stackstorm-foreman/config.schema.yaml create mode 100644 stackstorm-foreman/foreman.example.yaml create mode 100644 stackstorm-foreman/pack.yaml create mode 100644 stackstorm-foreman/requirements.txt diff --git a/stackstorm-foreman/LICENSE b/stackstorm-foreman/LICENSE new file mode 100644 index 0000000..090bab0 --- /dev/null +++ b/stackstorm-foreman/LICENSE @@ -0,0 +1,13 @@ +Copyright 2016 Daniel Chamot daniel@nullkarma.com + +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. diff --git a/stackstorm-foreman/README.md b/stackstorm-foreman/README.md new file mode 100644 index 0000000..7921169 --- /dev/null +++ b/stackstorm-foreman/README.md @@ -0,0 +1,173 @@ +# Foreman Integration Pack + +## Configuration + +```yaml +url: https://foreman.domain.tld +username: foo +password: bar +verify_ssl: False +``` + +## Actions + +### Puppet + +* `puppet.hosts` - List puppet hosts by environment + +### Foreman + +* `foreman.hosts` - List Hosts managed by Foreman +* `foreman.power_host` - Change a hosts powerstate +* `foreman.create_host` - Provision a new host + +## Examples + +### `foreman.create_host` + +`st2 run foreman.create_host name=host-1.domain.tld provision_method=image hostconfig= + +#### hostconfig + +``` +{ + "hostgroup_id": 18, + "location_id": 4, + "compute_resource_id": 1, + "compute_profile_id": 14, + "image_id": 3, + "build": true, + "compute_attributes": { + "start": "1" + } +} +``` + +Retrieve the ids by using `hammer-cli`. +#### payload + +``` +{ + "ip": "10.0.0.20", + "ip6": null, + "environment_id": 334344675, + "environment_name": "production", + "last_report": null, + "mac": "00:11:22:33:44:00", + "realm_id": null, + "realm_name": null, + "sp_mac": "00:11:22:33:44:01", + "sp_ip": null, + "sp_name": null, + "domain_id": 22495316, + "domain_name": "mydomain.net", + "architecture_id": 501905019, + "architecture_name": "x86_64", + "operatingsystem_id": 1073012828, + "operatingsystem_name": "RHEL 6.1", + "subnet_id": null, + "subnet_name": null, + "subnet6_id": null, + "subnet6_name": null, + "sp_subnet_id": null, + "ptable_id": 1007981702, + "ptable_name": "ptable29", + "medium_id": 980190962, + "medium_name": "CentOS 5.4", + "build": false, + "comment": null, + "disk": null, + "installed_at": null, + "model_id": null, + "hostgroup_id": null, + "owner_id": 886836129, + "owner_type": "User", + "enabled": true, + "managed": true, + "use_image": null, + "image_file": "", + "uuid": null, + "compute_resource_id": 980190962, + "compute_resource_name": "bigcompute", + "compute_profile_id": 281110143, + "compute_profile_name": "4-Networking", + "capabilities": [ + "build", + "image" + ], + "provision_method": "build", + "certname": "testhost11.mydomain.net", + "image_id": null, + "image_name": null, + "created_at": "2017-01-13 11:52:30 UTC", + "updated_at": "2017-01-13 11:52:30 UTC", + "last_compile": null, + "global_status": 0, + "global_status_label": "Warning", + "organization_id": 447626438, + "organization_name": "Organization 1", + "location_id": 255093256, + "location_name": "Location 1", + "puppet_status": 0, + "model_name": null, + "configuration_status": 0, + "configuration_status_label": "No reports", + "build_status": 0, + "build_status_label": "Installed", + "name": "testhost11.mydomain.net", + "id": 2, + "puppet_proxy_id": 182953976, + "puppet_proxy_name": "Puppetmaster Proxy", + "puppet_ca_proxy_id": 182953976, + "puppet_ca_proxy_name": "Puppetmaster Proxy", + "puppet_proxy": { + "name": "Puppetmaster Proxy", + "id": 182953976, + "url": "http://else.where:4567" + }, + "puppet_ca_proxy": { + "name": "Puppetmaster Proxy", + "id": 182953976, + "url": "http://else.where:4567" + }, + "hostgroup_name": null, + "hostgroup_title": null, + "interfaces": [ + { + "id": 2, + "name": "testhost11.mydomain.net", + "ip": "10.0.0.20", + "mac": "00:11:22:33:44:00", + "identifier": null, + "primary": true, + "provision": true, + "type": "interface" + }, + { + "id": 3, + "name": null, + "ip": null, + "mac": "00:11:22:33:44:01", + "identifier": null, + "primary": false, + "provision": false, + "type": "bmc" + } + ], + "puppetclasses": [], + "config_groups": [], + "all_puppetclasses": [], + "permissions": { + "console_hosts": true, + "build_hosts": true, + "power_hosts": true, + "edit_hosts": true, + "destroy_hosts": true, + "create_hosts": true, + "ipmi_boot_hosts": true, + "view_hosts": true, + "puppetrun_hosts": true + } +} +``` +Documentation: https://theforeman.org/api/1.14/index.html \ No newline at end of file diff --git a/stackstorm-foreman/actions/create_host.py b/stackstorm-foreman/actions/create_host.py new file mode 100644 index 0000000..17259ac --- /dev/null +++ b/stackstorm-foreman/actions/create_host.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +from lib.foreman import ForemanAPI +from time import time + + +class NewHost(ForemanAPI): + def __init__(self, config): + super(NewHost, self).__init__(config=config) + + def run(self, unattended, provision_method, name, hostconfig): + + hostconfig['provision_method'] = provision_method + payload = {"host": hostconfig} + + if unattended: + sec, ms = str(time()).split('.') + suffix = str(int(sec) + int(ms)) + hostconfig['name'] = name + suffix + else: + hostconfig['name'] = name + + return self.post(endpoint='hosts', verify_ssl=self.verify_ssl, payload=payload) diff --git a/stackstorm-foreman/actions/create_host.yaml b/stackstorm-foreman/actions/create_host.yaml new file mode 100644 index 0000000..2fba709 --- /dev/null +++ b/stackstorm-foreman/actions/create_host.yaml @@ -0,0 +1,25 @@ +--- + +name: create_host +description: "Create new Host" + +runner_type: python-script +entry_point: create_host.py + +parameters: + unattended: + type: boolean + default: False + description: "Unattended will use :name as prefix and create a single Instance." + provision_method: + type: string + enum: + - build + - image + default: image + name: + type: string + required: True + hostconfig: + type: object + description: "Foreman APIv2 /api/hosts Syntax" \ No newline at end of file diff --git a/stackstorm-foreman/actions/foreman_hosts.py b/stackstorm-foreman/actions/foreman_hosts.py new file mode 100644 index 0000000..8b603f5 --- /dev/null +++ b/stackstorm-foreman/actions/foreman_hosts.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +from lib.foreman import ForemanHosts + + +class ForemanHostSearch(ForemanHosts): + + def run(self, extended, running, query_filter=None): + return True, dict(hosts=self.hosts("hosts", extended, running, params=query_filter)) diff --git a/stackstorm-foreman/actions/foreman_hosts.yaml b/stackstorm-foreman/actions/foreman_hosts.yaml new file mode 100644 index 0000000..e011980 --- /dev/null +++ b/stackstorm-foreman/actions/foreman_hosts.yaml @@ -0,0 +1,20 @@ +--- + +name: hosts +description: "List Hosts managed by Foreman" + +runner_type: python-script +entry_point: foreman_hosts.py + +parameters: + running: + type: boolean + default: True + description: "Show only running hosts" + extended: + type: boolean + default: False + description: "Returns the whole json object, instead of a list of hostnames" + query_filter: + type: object + description: "Foreman Query Syntax -- environment = production and domain = domain.tld" diff --git a/stackstorm-foreman/actions/lib/__init__.py b/stackstorm-foreman/actions/lib/__init__.py new file mode 100644 index 0000000..4265cc3 --- /dev/null +++ b/stackstorm-foreman/actions/lib/__init__.py @@ -0,0 +1 @@ +#!/usr/bin/env python diff --git a/stackstorm-foreman/actions/lib/foreman.py b/stackstorm-foreman/actions/lib/foreman.py new file mode 100644 index 0000000..030b418 --- /dev/null +++ b/stackstorm-foreman/actions/lib/foreman.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python + +from st2actions.runners.pythonrunner import Action +import requests +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + + +class RequestsMethod(object): + @staticmethod + def method(method, url, auth=None, verify_ssl=False, headers=None, params=None, json=None): + methods = {'get': requests.get, + 'post': requests.post, + 'put': requests.put} + + if not params: + params = dict() + + if not json: + json = dict() + + requests_method = methods.get(method) + response = requests_method(url, auth=auth, headers=headers, params=params, json=json, verify=verify_ssl) + if response.status_code: + return response.json() + else: + return response.text + + +class ForemanAPI(Action): + def __init__(self, config): + super(ForemanAPI, self).__init__(config=config) + self.url = self.config.get('url', None) + self.username = self.config.get('username', None) + self.password = self.config.get('password', None) + self.verify_ssl = self.config.get('verify_ssl', False) + + self._headers = {"Accept": "version=2,application/json"} + + def running_hosts(self, hosts): + for host in hosts: + try: + hostname = host.get('name') + except AttributeError: + hostname = host + + host_status = self.get("hosts/{0}/vm_compute_attributes".format(hostname), + verify_ssl=self.verify_ssl).get('state') + if host_status.lower() not in ['shutoff']: + yield host + + def _get(self, endpoint, params=None, *args, **kwargs): + api_url = "{url}/{api_ext}/{endpoint}".format(url=self.url, api_ext='api', endpoint=endpoint) + return RequestsMethod.method('get', + url=api_url, + auth=(self.username, self.password), + verify_ssl=self.verify_ssl, + headers=self._headers, + params=params) + + def _post(self, endpoint, params=None, payload=None, *args, **kwargs): + api_url = "{url}/{api_ext}/{endpoint}".format(url=self.url, api_ext='api', endpoint=endpoint) + return RequestsMethod.method('post', + url=api_url, + auth=(self.username, self.password), + verify_ssl=self.verify_ssl, + headers=self._headers, + params=params, + json=payload) + + def _put(self, endpoint, params=None, payload=None, *args, **kwargs): + api_url = "{url}/{api_ext}/{endpoint}".format(url=self.url, api_ext='api', endpoint=endpoint) + return RequestsMethod.method('put', + url=api_url, + auth=(self.username, self.password), + verify_ssl=self.verify_ssl, + headers=self._headers, + params=params, + json=payload) + + def get(self, *args, **kwargs): + return self._get(*args, **kwargs) + + def post(self, *args, **kwargs): + return self._post(*args, **kwargs) + + def put(self, *args, **kwargs): + return self._put(*args, **kwargs) + + +class ForemanHosts(ForemanAPI): + def __init__(self, config): + super(ForemanHosts, self).__init__(config=config) + + def hosts(self, endpoint, extended, running, params): + hosts_raw = self.get(endpoint, params=params, verify_ssl=self.verify_ssl).get('results') + if running: + hosts = [host for host in self.running_hosts(hosts_raw)] + else: + hosts = hosts_raw + + if not extended: + try: + return [host.get('name') for host in hosts] + except AttributeError: + return [host for host in hosts] + + return hosts diff --git a/stackstorm-foreman/actions/power_host.py b/stackstorm-foreman/actions/power_host.py new file mode 100644 index 0000000..d5c1946 --- /dev/null +++ b/stackstorm-foreman/actions/power_host.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python + +from lib.foreman import ForemanAPI + + +class ForemanPowerHost(ForemanAPI): + def __init__(self, config): + super(ForemanPowerHost, self).__init__(config=config) + + def run(self, host, action): + return self.put(endpoint="{}/{}/power".format('hosts', host), params={"power_action": action}) diff --git a/stackstorm-foreman/actions/power_host.yaml b/stackstorm-foreman/actions/power_host.yaml new file mode 100644 index 0000000..d0a70ae --- /dev/null +++ b/stackstorm-foreman/actions/power_host.yaml @@ -0,0 +1,21 @@ +--- + +name: power_host +description: "Run power operation on host" + +runner_type: python-script +entry_point: power_host.py + +parameters: + host: + type: string + required: true + action: + type: string + enum: + - start + - stop + - reboot + - reset + - status + default: status diff --git a/stackstorm-foreman/actions/puppet_hosts.py b/stackstorm-foreman/actions/puppet_hosts.py new file mode 100644 index 0000000..cab27c1 --- /dev/null +++ b/stackstorm-foreman/actions/puppet_hosts.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +from lib.foreman import ForemanHosts + + +class PuppetHostSearch(ForemanHosts): + + def run(self, environment, extended, running, query_filter=None): + return True, dict(hosts=self.hosts('environments/{}/hosts'.format(environment), extended, running=running, params=query_filter)) \ No newline at end of file diff --git a/stackstorm-foreman/actions/puppet_hosts.yaml b/stackstorm-foreman/actions/puppet_hosts.yaml new file mode 100644 index 0000000..213afdc --- /dev/null +++ b/stackstorm-foreman/actions/puppet_hosts.yaml @@ -0,0 +1,23 @@ +--- + +name: puppet.hosts +description: "List puppet hosts by environment" + +runner_type: python-script +entry_point: puppet_hosts.py + +parameters: + environment: + type: string + default: production + running: + type: boolean + default: True + description: "Show only running hosts" + extended: + type: boolean + default: False + description: "Returns the whole json object, instead of a list of hostnames" + query_filter: + type: object + description: "Foreman Query Syntax -- environment = production and domain = domain.tld" diff --git a/stackstorm-foreman/config.schema.yaml b/stackstorm-foreman/config.schema.yaml new file mode 100644 index 0000000..246f459 --- /dev/null +++ b/stackstorm-foreman/config.schema.yaml @@ -0,0 +1,18 @@ +--- + +url: + description: "Foreman Url" + type: string + required: true + +username: + type: string + required: true + +password: + type: string + required: true + +verify_ssl: + type: boolean + default: False diff --git a/stackstorm-foreman/foreman.example.yaml b/stackstorm-foreman/foreman.example.yaml new file mode 100644 index 0000000..a10d650 --- /dev/null +++ b/stackstorm-foreman/foreman.example.yaml @@ -0,0 +1,7 @@ +--- + +url: https://example.com +username: foo +password: bar +verify_ssl: False + diff --git a/stackstorm-foreman/pack.yaml b/stackstorm-foreman/pack.yaml new file mode 100644 index 0000000..42e2970 --- /dev/null +++ b/stackstorm-foreman/pack.yaml @@ -0,0 +1,10 @@ +--- + +name: foreman +ref: foreman +description: Interact with Foreman API v2 +keywords: + - foreman +version: 0.2.1 +author: Daniel Chamot +email: daniel@nullkarma.com diff --git a/stackstorm-foreman/requirements.txt b/stackstorm-foreman/requirements.txt new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/stackstorm-foreman/requirements.txt @@ -0,0 +1 @@ +requests From 64b047b91e061b12bd865ff684553087c094b6f3 Mon Sep 17 00:00:00 2001 From: Daniel Chamot Date: Fri, 28 Apr 2017 09:36:59 +0200 Subject: [PATCH 09/45] pep8 applied --- stackstorm-foreman/actions/puppet_hosts.py | 5 ++++- stackstorm-foreman/icon.png | Bin 0 -> 6278 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 stackstorm-foreman/icon.png diff --git a/stackstorm-foreman/actions/puppet_hosts.py b/stackstorm-foreman/actions/puppet_hosts.py index cab27c1..4c7f112 100644 --- a/stackstorm-foreman/actions/puppet_hosts.py +++ b/stackstorm-foreman/actions/puppet_hosts.py @@ -6,4 +6,7 @@ class PuppetHostSearch(ForemanHosts): def run(self, environment, extended, running, query_filter=None): - return True, dict(hosts=self.hosts('environments/{}/hosts'.format(environment), extended, running=running, params=query_filter)) \ No newline at end of file + return True, dict(hosts=self.hosts('environments/{}/hosts'.format(environment), + extended, + running=running, + params=query_filter)) diff --git a/stackstorm-foreman/icon.png b/stackstorm-foreman/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bd64de03a1c4e7cc2824668d3301c616c36c58 GIT binary patch literal 6278 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 kbZHYp Date: Fri, 28 Apr 2017 21:18:19 -0700 Subject: [PATCH 10/45] Revert "Foreman Integration Pack" --- .gitignore | 1 + stackstorm-foreman/LICENSE | 13 -- stackstorm-foreman/README.md | 173 ------------------ stackstorm-foreman/actions/create_host.py | 23 --- stackstorm-foreman/actions/create_host.yaml | 25 --- stackstorm-foreman/actions/foreman_hosts.py | 9 - stackstorm-foreman/actions/foreman_hosts.yaml | 20 -- stackstorm-foreman/actions/lib/__init__.py | 1 - stackstorm-foreman/actions/lib/foreman.py | 108 ----------- stackstorm-foreman/actions/power_host.py | 11 -- stackstorm-foreman/actions/power_host.yaml | 21 --- stackstorm-foreman/actions/puppet_hosts.py | 12 -- stackstorm-foreman/actions/puppet_hosts.yaml | 23 --- stackstorm-foreman/config.schema.yaml | 18 -- stackstorm-foreman/foreman.example.yaml | 7 - stackstorm-foreman/icon.png | Bin 6278 -> 0 bytes stackstorm-foreman/pack.yaml | 10 - stackstorm-foreman/requirements.txt | 1 - 18 files changed, 1 insertion(+), 475 deletions(-) delete mode 100644 stackstorm-foreman/LICENSE delete mode 100644 stackstorm-foreman/README.md delete mode 100644 stackstorm-foreman/actions/create_host.py delete mode 100644 stackstorm-foreman/actions/create_host.yaml delete mode 100644 stackstorm-foreman/actions/foreman_hosts.py delete mode 100644 stackstorm-foreman/actions/foreman_hosts.yaml delete mode 100644 stackstorm-foreman/actions/lib/__init__.py delete mode 100644 stackstorm-foreman/actions/lib/foreman.py delete mode 100644 stackstorm-foreman/actions/power_host.py delete mode 100644 stackstorm-foreman/actions/power_host.yaml delete mode 100644 stackstorm-foreman/actions/puppet_hosts.py delete mode 100644 stackstorm-foreman/actions/puppet_hosts.yaml delete mode 100644 stackstorm-foreman/config.schema.yaml delete mode 100644 stackstorm-foreman/foreman.example.yaml delete mode 100644 stackstorm-foreman/icon.png delete mode 100644 stackstorm-foreman/pack.yaml delete mode 100644 stackstorm-foreman/requirements.txt diff --git a/.gitignore b/.gitignore index a76c9cc..72364f9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ dist/ downloads/ eggs/ .eggs/ +lib/ lib64/ parts/ sdist/ diff --git a/stackstorm-foreman/LICENSE b/stackstorm-foreman/LICENSE deleted file mode 100644 index 090bab0..0000000 --- a/stackstorm-foreman/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2016 Daniel Chamot daniel@nullkarma.com - -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. diff --git a/stackstorm-foreman/README.md b/stackstorm-foreman/README.md deleted file mode 100644 index 7921169..0000000 --- a/stackstorm-foreman/README.md +++ /dev/null @@ -1,173 +0,0 @@ -# Foreman Integration Pack - -## Configuration - -```yaml -url: https://foreman.domain.tld -username: foo -password: bar -verify_ssl: False -``` - -## Actions - -### Puppet - -* `puppet.hosts` - List puppet hosts by environment - -### Foreman - -* `foreman.hosts` - List Hosts managed by Foreman -* `foreman.power_host` - Change a hosts powerstate -* `foreman.create_host` - Provision a new host - -## Examples - -### `foreman.create_host` - -`st2 run foreman.create_host name=host-1.domain.tld provision_method=image hostconfig= - -#### hostconfig - -``` -{ - "hostgroup_id": 18, - "location_id": 4, - "compute_resource_id": 1, - "compute_profile_id": 14, - "image_id": 3, - "build": true, - "compute_attributes": { - "start": "1" - } -} -``` - -Retrieve the ids by using `hammer-cli`. -#### payload - -``` -{ - "ip": "10.0.0.20", - "ip6": null, - "environment_id": 334344675, - "environment_name": "production", - "last_report": null, - "mac": "00:11:22:33:44:00", - "realm_id": null, - "realm_name": null, - "sp_mac": "00:11:22:33:44:01", - "sp_ip": null, - "sp_name": null, - "domain_id": 22495316, - "domain_name": "mydomain.net", - "architecture_id": 501905019, - "architecture_name": "x86_64", - "operatingsystem_id": 1073012828, - "operatingsystem_name": "RHEL 6.1", - "subnet_id": null, - "subnet_name": null, - "subnet6_id": null, - "subnet6_name": null, - "sp_subnet_id": null, - "ptable_id": 1007981702, - "ptable_name": "ptable29", - "medium_id": 980190962, - "medium_name": "CentOS 5.4", - "build": false, - "comment": null, - "disk": null, - "installed_at": null, - "model_id": null, - "hostgroup_id": null, - "owner_id": 886836129, - "owner_type": "User", - "enabled": true, - "managed": true, - "use_image": null, - "image_file": "", - "uuid": null, - "compute_resource_id": 980190962, - "compute_resource_name": "bigcompute", - "compute_profile_id": 281110143, - "compute_profile_name": "4-Networking", - "capabilities": [ - "build", - "image" - ], - "provision_method": "build", - "certname": "testhost11.mydomain.net", - "image_id": null, - "image_name": null, - "created_at": "2017-01-13 11:52:30 UTC", - "updated_at": "2017-01-13 11:52:30 UTC", - "last_compile": null, - "global_status": 0, - "global_status_label": "Warning", - "organization_id": 447626438, - "organization_name": "Organization 1", - "location_id": 255093256, - "location_name": "Location 1", - "puppet_status": 0, - "model_name": null, - "configuration_status": 0, - "configuration_status_label": "No reports", - "build_status": 0, - "build_status_label": "Installed", - "name": "testhost11.mydomain.net", - "id": 2, - "puppet_proxy_id": 182953976, - "puppet_proxy_name": "Puppetmaster Proxy", - "puppet_ca_proxy_id": 182953976, - "puppet_ca_proxy_name": "Puppetmaster Proxy", - "puppet_proxy": { - "name": "Puppetmaster Proxy", - "id": 182953976, - "url": "http://else.where:4567" - }, - "puppet_ca_proxy": { - "name": "Puppetmaster Proxy", - "id": 182953976, - "url": "http://else.where:4567" - }, - "hostgroup_name": null, - "hostgroup_title": null, - "interfaces": [ - { - "id": 2, - "name": "testhost11.mydomain.net", - "ip": "10.0.0.20", - "mac": "00:11:22:33:44:00", - "identifier": null, - "primary": true, - "provision": true, - "type": "interface" - }, - { - "id": 3, - "name": null, - "ip": null, - "mac": "00:11:22:33:44:01", - "identifier": null, - "primary": false, - "provision": false, - "type": "bmc" - } - ], - "puppetclasses": [], - "config_groups": [], - "all_puppetclasses": [], - "permissions": { - "console_hosts": true, - "build_hosts": true, - "power_hosts": true, - "edit_hosts": true, - "destroy_hosts": true, - "create_hosts": true, - "ipmi_boot_hosts": true, - "view_hosts": true, - "puppetrun_hosts": true - } -} -``` -Documentation: https://theforeman.org/api/1.14/index.html \ No newline at end of file diff --git a/stackstorm-foreman/actions/create_host.py b/stackstorm-foreman/actions/create_host.py deleted file mode 100644 index 17259ac..0000000 --- a/stackstorm-foreman/actions/create_host.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python - -from lib.foreman import ForemanAPI -from time import time - - -class NewHost(ForemanAPI): - def __init__(self, config): - super(NewHost, self).__init__(config=config) - - def run(self, unattended, provision_method, name, hostconfig): - - hostconfig['provision_method'] = provision_method - payload = {"host": hostconfig} - - if unattended: - sec, ms = str(time()).split('.') - suffix = str(int(sec) + int(ms)) - hostconfig['name'] = name + suffix - else: - hostconfig['name'] = name - - return self.post(endpoint='hosts', verify_ssl=self.verify_ssl, payload=payload) diff --git a/stackstorm-foreman/actions/create_host.yaml b/stackstorm-foreman/actions/create_host.yaml deleted file mode 100644 index 2fba709..0000000 --- a/stackstorm-foreman/actions/create_host.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- - -name: create_host -description: "Create new Host" - -runner_type: python-script -entry_point: create_host.py - -parameters: - unattended: - type: boolean - default: False - description: "Unattended will use :name as prefix and create a single Instance." - provision_method: - type: string - enum: - - build - - image - default: image - name: - type: string - required: True - hostconfig: - type: object - description: "Foreman APIv2 /api/hosts Syntax" \ No newline at end of file diff --git a/stackstorm-foreman/actions/foreman_hosts.py b/stackstorm-foreman/actions/foreman_hosts.py deleted file mode 100644 index 8b603f5..0000000 --- a/stackstorm-foreman/actions/foreman_hosts.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python - -from lib.foreman import ForemanHosts - - -class ForemanHostSearch(ForemanHosts): - - def run(self, extended, running, query_filter=None): - return True, dict(hosts=self.hosts("hosts", extended, running, params=query_filter)) diff --git a/stackstorm-foreman/actions/foreman_hosts.yaml b/stackstorm-foreman/actions/foreman_hosts.yaml deleted file mode 100644 index e011980..0000000 --- a/stackstorm-foreman/actions/foreman_hosts.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- - -name: hosts -description: "List Hosts managed by Foreman" - -runner_type: python-script -entry_point: foreman_hosts.py - -parameters: - running: - type: boolean - default: True - description: "Show only running hosts" - extended: - type: boolean - default: False - description: "Returns the whole json object, instead of a list of hostnames" - query_filter: - type: object - description: "Foreman Query Syntax -- environment = production and domain = domain.tld" diff --git a/stackstorm-foreman/actions/lib/__init__.py b/stackstorm-foreman/actions/lib/__init__.py deleted file mode 100644 index 4265cc3..0000000 --- a/stackstorm-foreman/actions/lib/__init__.py +++ /dev/null @@ -1 +0,0 @@ -#!/usr/bin/env python diff --git a/stackstorm-foreman/actions/lib/foreman.py b/stackstorm-foreman/actions/lib/foreman.py deleted file mode 100644 index 030b418..0000000 --- a/stackstorm-foreman/actions/lib/foreman.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python - -from st2actions.runners.pythonrunner import Action -import requests -from requests.packages.urllib3.exceptions import InsecureRequestWarning -requests.packages.urllib3.disable_warnings(InsecureRequestWarning) - - -class RequestsMethod(object): - @staticmethod - def method(method, url, auth=None, verify_ssl=False, headers=None, params=None, json=None): - methods = {'get': requests.get, - 'post': requests.post, - 'put': requests.put} - - if not params: - params = dict() - - if not json: - json = dict() - - requests_method = methods.get(method) - response = requests_method(url, auth=auth, headers=headers, params=params, json=json, verify=verify_ssl) - if response.status_code: - return response.json() - else: - return response.text - - -class ForemanAPI(Action): - def __init__(self, config): - super(ForemanAPI, self).__init__(config=config) - self.url = self.config.get('url', None) - self.username = self.config.get('username', None) - self.password = self.config.get('password', None) - self.verify_ssl = self.config.get('verify_ssl', False) - - self._headers = {"Accept": "version=2,application/json"} - - def running_hosts(self, hosts): - for host in hosts: - try: - hostname = host.get('name') - except AttributeError: - hostname = host - - host_status = self.get("hosts/{0}/vm_compute_attributes".format(hostname), - verify_ssl=self.verify_ssl).get('state') - if host_status.lower() not in ['shutoff']: - yield host - - def _get(self, endpoint, params=None, *args, **kwargs): - api_url = "{url}/{api_ext}/{endpoint}".format(url=self.url, api_ext='api', endpoint=endpoint) - return RequestsMethod.method('get', - url=api_url, - auth=(self.username, self.password), - verify_ssl=self.verify_ssl, - headers=self._headers, - params=params) - - def _post(self, endpoint, params=None, payload=None, *args, **kwargs): - api_url = "{url}/{api_ext}/{endpoint}".format(url=self.url, api_ext='api', endpoint=endpoint) - return RequestsMethod.method('post', - url=api_url, - auth=(self.username, self.password), - verify_ssl=self.verify_ssl, - headers=self._headers, - params=params, - json=payload) - - def _put(self, endpoint, params=None, payload=None, *args, **kwargs): - api_url = "{url}/{api_ext}/{endpoint}".format(url=self.url, api_ext='api', endpoint=endpoint) - return RequestsMethod.method('put', - url=api_url, - auth=(self.username, self.password), - verify_ssl=self.verify_ssl, - headers=self._headers, - params=params, - json=payload) - - def get(self, *args, **kwargs): - return self._get(*args, **kwargs) - - def post(self, *args, **kwargs): - return self._post(*args, **kwargs) - - def put(self, *args, **kwargs): - return self._put(*args, **kwargs) - - -class ForemanHosts(ForemanAPI): - def __init__(self, config): - super(ForemanHosts, self).__init__(config=config) - - def hosts(self, endpoint, extended, running, params): - hosts_raw = self.get(endpoint, params=params, verify_ssl=self.verify_ssl).get('results') - if running: - hosts = [host for host in self.running_hosts(hosts_raw)] - else: - hosts = hosts_raw - - if not extended: - try: - return [host.get('name') for host in hosts] - except AttributeError: - return [host for host in hosts] - - return hosts diff --git a/stackstorm-foreman/actions/power_host.py b/stackstorm-foreman/actions/power_host.py deleted file mode 100644 index d5c1946..0000000 --- a/stackstorm-foreman/actions/power_host.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -from lib.foreman import ForemanAPI - - -class ForemanPowerHost(ForemanAPI): - def __init__(self, config): - super(ForemanPowerHost, self).__init__(config=config) - - def run(self, host, action): - return self.put(endpoint="{}/{}/power".format('hosts', host), params={"power_action": action}) diff --git a/stackstorm-foreman/actions/power_host.yaml b/stackstorm-foreman/actions/power_host.yaml deleted file mode 100644 index d0a70ae..0000000 --- a/stackstorm-foreman/actions/power_host.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- - -name: power_host -description: "Run power operation on host" - -runner_type: python-script -entry_point: power_host.py - -parameters: - host: - type: string - required: true - action: - type: string - enum: - - start - - stop - - reboot - - reset - - status - default: status diff --git a/stackstorm-foreman/actions/puppet_hosts.py b/stackstorm-foreman/actions/puppet_hosts.py deleted file mode 100644 index 4c7f112..0000000 --- a/stackstorm-foreman/actions/puppet_hosts.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python - -from lib.foreman import ForemanHosts - - -class PuppetHostSearch(ForemanHosts): - - def run(self, environment, extended, running, query_filter=None): - return True, dict(hosts=self.hosts('environments/{}/hosts'.format(environment), - extended, - running=running, - params=query_filter)) diff --git a/stackstorm-foreman/actions/puppet_hosts.yaml b/stackstorm-foreman/actions/puppet_hosts.yaml deleted file mode 100644 index 213afdc..0000000 --- a/stackstorm-foreman/actions/puppet_hosts.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- - -name: puppet.hosts -description: "List puppet hosts by environment" - -runner_type: python-script -entry_point: puppet_hosts.py - -parameters: - environment: - type: string - default: production - running: - type: boolean - default: True - description: "Show only running hosts" - extended: - type: boolean - default: False - description: "Returns the whole json object, instead of a list of hostnames" - query_filter: - type: object - description: "Foreman Query Syntax -- environment = production and domain = domain.tld" diff --git a/stackstorm-foreman/config.schema.yaml b/stackstorm-foreman/config.schema.yaml deleted file mode 100644 index 246f459..0000000 --- a/stackstorm-foreman/config.schema.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- - -url: - description: "Foreman Url" - type: string - required: true - -username: - type: string - required: true - -password: - type: string - required: true - -verify_ssl: - type: boolean - default: False diff --git a/stackstorm-foreman/foreman.example.yaml b/stackstorm-foreman/foreman.example.yaml deleted file mode 100644 index a10d650..0000000 --- a/stackstorm-foreman/foreman.example.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- - -url: https://example.com -username: foo -password: bar -verify_ssl: False - diff --git a/stackstorm-foreman/icon.png b/stackstorm-foreman/icon.png deleted file mode 100644 index f6bd64de03a1c4e7cc2824668d3301c616c36c58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6278 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 kbZHYp Date: Tue, 20 Jun 2017 18:09:45 -0700 Subject: [PATCH 11/45] Make lib exclusion more specific `lib/` exclusion too broad. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 72364f9..260ff8d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ dist/ downloads/ eggs/ .eggs/ -lib/ +./lib/ lib64/ parts/ sdist/ From e2e06eba1b6680db73b9dfb1f1fbfe522ec6c9e4 Mon Sep 17 00:00:00 2001 From: Lindsay Hill Date: Thu, 3 Aug 2017 10:39:01 -0700 Subject: [PATCH 12/45] Remove git submodule reference --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index bb1489d..f1199d7 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ This repository is a very special place where user-submitted packs get reviewed, If you want to submit your pack, it's simple! **Fork this repo, create a subdirectory with your pack, and open a Pull Request.** We'll take it from here. Even if your pack is work-in-progress, you can still submit it to get advice and early feedback from our engineers! Or ping us [on Slack](https://stackstorm.com/community-signup), which is generally the best place to get advice from the StackStorm Community. -**Pro-tip:** if you've been working on your pack for quite a while already, and want your git history and versioning preserved, add your pack repo as a submodule. - Before you submit a pack, make sure to read the [Create and Contribute a Pack](https://docs.stackstorm.com/reference/packs.html) section of our documentation. Here's N.E.P.T.R. the StackStorm Exchange Governor, giving you a thumbs-up: From b6c5af18171c41aa6c66a3ea01b469bde42caa7b Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 10:38:20 +0200 Subject: [PATCH 13/45] Add circle ci config. --- .circleci/config.yml | 73 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..8868810 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,73 @@ +version: 2 + +jobs: + build_and_test: + docker: + - image: circleci/python:2.7 + - image: rabbitmq:3 + - image: mongo:3.4 + + working_directory: ~/repo + + environment: + VIRTUALENV_DIR: "~/virtualenv" + + steps: + - checkout + - restore_cache: + key: v1-dependency-cache-{{ checksum "requirements.txt" }} + - run: + name: Download dependencies + command: | + git clone -b master git@github.com:stackstorm-exchange/ci.git ~/ci + ~/ci/.circle/dependencies + - run: + name: Run tests + command: ~/ci/.circle/test + - save_cache: + key: v1-dependency-cache-{{ checksum "requirements.txt" }} + paths: + - ~/.cache/pip + - ~/.apt-cache + - persist_to_workspace: + root: / + paths: + - home/circleci/ci + - home/circleci/virtualenv + - tmp/st2 + - home/circleci/repo + - home/circleci/.gitconfig + + deploy: + docker: + - image: circleci/python:2.7 + + working_directory: ~/repo + + environment: + VIRTUALENV_DIR: "~/virtualenv" + + steps: + - checkout + - restore_cache: + key: v1-dependency-cache-{{ checksum "requirements.txt" }} + - attach_workspace: + at: / + - run: + name: Install dependencies + command: sudo apt -y install gmic optipng + - run: + name: Update exchange.stackstorm.org + command: ~/ci/.circle/deployment + +workflows: + version: 2 + build_test_deploy: + jobs: + - build_and_test + - deploy: + requires: + - build_and_test + filters: + branches: + only: master From 6be721bc9a4b8030e043264a1bae19ae094b719f Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 10:42:03 +0200 Subject: [PATCH 14/45] Add dummy pack to test build process. --- jinja/.gitignore | 89 +++++++++++++++++++++++++++++++++ jinja/actions/render_file.py | 62 +++++++++++++++++++++++ jinja/actions/render_file.yaml | 25 +++++++++ jinja/icon.png | Bin 0 -> 2229 bytes jinja/pack.yaml | 9 ++++ jinja/requirements.txt | 0 6 files changed, 185 insertions(+) create mode 100644 jinja/.gitignore create mode 100644 jinja/actions/render_file.py create mode 100644 jinja/actions/render_file.yaml create mode 100644 jinja/icon.png create mode 100644 jinja/pack.yaml create mode 100644 jinja/requirements.txt diff --git a/jinja/.gitignore b/jinja/.gitignore new file mode 100644 index 0000000..260ff8d --- /dev/null +++ b/jinja/.gitignore @@ -0,0 +1,89 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +./lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject diff --git a/jinja/actions/render_file.py b/jinja/actions/render_file.py new file mode 100644 index 0000000..9b185c8 --- /dev/null +++ b/jinja/actions/render_file.py @@ -0,0 +1,62 @@ +# Licensed to the StackStorm, Inc ('StackStorm') under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import six +import os + +from st2common.runners.base_action import Action +from st2client.client import Client +from st2common.content import utils as content_utils +from st2common.util import jinja as jinja_utils + + +class FormatResultAction(Action): + def __init__(self, config=None, action_service=None): + super(FormatResultAction, self).__init__(config=config, action_service=action_service) + + api_url = os.environ.get('ST2_ACTION_API_URL', None) + token = os.environ.get('ST2_ACTION_AUTH_TOKEN', None) + + self.client = Client(api_url=api_url, token=token) + + self.jinja = jinja_utils.get_jinja_environment(allow_undefined=True) + self.jinja.tests['in'] = lambda item, list: item in list + + def run(self, template_pack, template_path, context, include_execution, include_six): + if include_six: + context['six'] = six + + if include_execution: + execution = self._get_execution(include_execution) + context['__execution'] = execution + + pack_path = content_utils.get_pack_base_path(template_pack) + abs_template_path = os.path.abspath(os.path.join(pack_path, template_path)) + + if not abs_template_path.startswith(pack_path): + raise ValueError('Template_path points to a file outside pack directory.') + + with open(abs_template_path, 'r') as f: + template = f.read() + + return self.jinja.from_string(template).render(context) + + def _get_execution(self, execution_id): + if not execution_id: + raise ValueError('Invalid execution_id provided.') + execution = self.client.liveactions.get_by_id(id=execution_id) + if not execution: + return None + return execution.to_dict() diff --git a/jinja/actions/render_file.yaml b/jinja/actions/render_file.yaml new file mode 100644 index 0000000..9f7b68e --- /dev/null +++ b/jinja/actions/render_file.yaml @@ -0,0 +1,25 @@ +--- +name: "render_file" +runner_type: "python-script" +description: "Render template" +enabled: true +entry_point: "render_file.py" +parameters: + template_pack: + type: "string" + description: "Path to the template" + required: true + template_path: + type: "string" + description: "Path to the template" + required: true + context: + type: object + description: "Context to render" + default: {} + include_execution: + type: string + description: "Include execution of the certain id to jinja context as `__execution` property" + include_six: + type: boolean + default: true diff --git a/jinja/icon.png b/jinja/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3eac885d5209567e30b57e420a4cf5a847f12b26 GIT binary patch literal 2229 zcmV;m2uk;fP)00009a7bBm000ie z000ie0hKEb8vpD(`dA;tgKl8 zpu4-9#bPm;%*e<{D=RCS$Y^hGpHTosMMZIOahaK!2&l8ObG$=;e}8jxb4f`_T3Q-| z!SMI@-@AA3x^?Re3=9+%6=~y!pP%210!T2C8fVa#+*5G6ciL_5)3$7TU+10 zeS1b#sJFM*+}xZdjq&>RYZ=HWR1X-yqGijL{c-4tgK$W`qHIK!NI|c7ca&%G&GdQ8IGc|vJ#nETU+bv>x=k; zf`XtYb#-+}RstY7IT@ZoBQ_d+w0e_)9G~C1AsC@g%F>cn;YV@v$I2R z#l^)dR;(ZZu!5i`WRbVGw~PTG`VAX4XlQ6iPJK8-On2_wX>V`;=+Pq?0~i<>z{VpW zcXxLi8ym!j1OS&%B2rURKY#uVwv-7+O-;>#0|y|lZEbCM>W6UrLH{$2mH5t`I{@(N z)vI4Q03;kHta`EmfCOl4Z0zXhAk&K%FCxCAq@+;?E|(h^7=g*&mHgG5{ zEybU({V3J41c2bc975|gYt~?24<9}Z`{~oCckkYHb#*;-=ulKt)bi!aNu3S}2_dx) z>;hC}Wo49V9UYzDoY=IVKz)5ZRNvIpl=NZF&d!)Vd-g0kIvRl*8yn~6=f}s#!^R=N zfe7n~6DMGMdV0dXdGn?$DHI+ajv%m?n>KA)zka>Cx;m!V`zu$jz(8`t$I;Odwu*`h zdS=oc&7VJi`}XaqZb;~yoE%vKXlQ6aK%fCAv|zykQhE^|Y*Mh`gBlDQ)f$ZhV31M` z?m?_zpqZ7i3awhT%E`$I6oOEqF9L?x*jQvX*s^u&RyZUkCL(AEC~+or07^=l+4S^u z83VvJ0|4Zl^bP<(RA}karEAx&g@MZe0^PT7A8bQIL)c(WQ&SWA3)t`8y^}Ej5Q7AV zYmL6XJ^;LY`4UqjBO?n73m7RWDF}4Wo;|QhGY0@wRaH<`*l*svktG215y(qWh1|I` zH8nAHadAOE2cB43T8>t?-Me@5`FvYjTLJ*6;3IngL@vhn4&aV#QS*j`><1VCP1o{x{u6z`K#0Dz_vR6(-0l-o4 zs;hq${gCj5|M+zr7r(1(LTBnD@m@?GKunAnfR>aLFrlZUgo;2QXnFCXE;6#8&F0nC z)?d3;e(F@&v14@+5q&Jy=p)#8?t=&L9FAKc=q@PWFc_77ex*l`mU?*91P8ZH=7Kf} z0NjTU#QgF&W+&dwCS)zwSg-P_XAcr`Vhxw%;e23V~0_a{EA zurN%q*~4#$%gbv+L)+8S;ml*Pu=n}fwo#Z33sK)VUmYAo0e~}@mYq5! z`czwLDi)bKI%L`yA5Wcti_33*=)H;xe0Y*ox=8@&=W@jWfC-`iYA#%$Haj3dtX5>s zo0p-aM8x->%uGtSwrmmg5uhPyYU;?&1{WH#>V(7OL%`6E);orI4-PD z3jiYXqtgN>C#*C?MGdQvrzfU)*4E=y2suCk0+F&7E<`Iq@YD)bmFQ-^ogFDGK#Nn7 zK81KyRg{FgyZ`Kt=yVjOR^dAcs?SME0*lyV|Krk?pI_nQQ#B$@6oqtkag2k)e=$LS z*fB8$j*i%uzc+3yadYFw$D?R`b9Lp9yfBs;fa>62im&(Yk7;0pW5TJJ8?k#zOR>SD zNjxm0d_F`LV1@<<$&?sU1AyIvenUNQvb~j+Q)wO>6B4is#Uri6^me1Hh=>Av`>#88 zpk<(n5sg-L?%b4KA{7>rHi`6q(+;5g^l9iOHlB!2bztBWe+-oyja^e>;tX9WL0qUF z8b*9j>Zkr={LW6nl>a3oztqbC$N|U!$N|U!h>ZULR*2XX&sQOk00000NkvXXu0mjf D$`1k% literal 0 HcmV?d00001 diff --git a/jinja/pack.yaml b/jinja/pack.yaml new file mode 100644 index 0000000..ac09d72 --- /dev/null +++ b/jinja/pack.yaml @@ -0,0 +1,9 @@ +name: jinja +description: Jinja template engine +keywords: + - jinja + - template + - templating +version: 0.1.1 +author: StackStorm, inc. +email: support@stackstorm.com diff --git a/jinja/requirements.txt b/jinja/requirements.txt new file mode 100644 index 0000000..e69de29 From 1dfb04c2798cf80d878cbb0f88a22b4adcc56ec1 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 10:45:02 +0200 Subject: [PATCH 15/45] Remove deploy step. --- .circleci/config.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8868810..f88a8ea 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -38,36 +38,8 @@ jobs: - home/circleci/repo - home/circleci/.gitconfig - deploy: - docker: - - image: circleci/python:2.7 - - working_directory: ~/repo - - environment: - VIRTUALENV_DIR: "~/virtualenv" - - steps: - - checkout - - restore_cache: - key: v1-dependency-cache-{{ checksum "requirements.txt" }} - - attach_workspace: - at: / - - run: - name: Install dependencies - command: sudo apt -y install gmic optipng - - run: - name: Update exchange.stackstorm.org - command: ~/ci/.circle/deployment - workflows: version: 2 build_test_deploy: jobs: - build_and_test - - deploy: - requires: - - build_and_test - filters: - branches: - only: master From 1b6d6c951450c4f0791b4e96860ef5a9d085d46c Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 11:00:56 +0200 Subject: [PATCH 16/45] Don't build master branch. --- .circleci/config.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f88a8ea..9655ec8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -42,4 +42,8 @@ workflows: version: 2 build_test_deploy: jobs: - - build_and_test + - build_and_test: + filters: + branches: + ignore: + - master From d6555a0389a2139e173b54134c193cc22c035148 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 11:17:19 +0200 Subject: [PATCH 17/45] Add a step which prepares the repo for CI. --- .circleci/config.yml | 4 ++++ .scripts/prepare-repo.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100755 .scripts/prepare-repo.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 9655ec8..d968753 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,6 +14,10 @@ jobs: steps: - checkout + - run: + name: Prepare repository + command: | + .scripts/prepare-repo.sh - restore_cache: key: v1-dependency-cache-{{ checksum "requirements.txt" }} - run: diff --git a/.scripts/prepare-repo.sh b/.scripts/prepare-repo.sh new file mode 100755 index 0000000..c68bb76 --- /dev/null +++ b/.scripts/prepare-repo.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +PACK_DIRECTORY=$(find . -maxdepth 1 -type d -not -path '*/\.*' -not -path '\.' | head -1 | sed -e 's/^\.\///') + +if [[ -z "${PACK_DIRECTORY}" ]]; then + echo "Unable to find pack directory" + exit 1 +fi + +echo "Found pack directory: ${PACK_DIRECTORY}" + +PACK_NAME=$(cat ${PACK_DIRECTORY}/pack.yaml | grep "name:" | sed -e 's/^name:[ \t]*//') + +if [[ -z "${PACK_NAME}" ]]; then + echo "Unable to retrieve pack name from ${PACK_DIRECTORY}/pack.yaml" + exit 1 +fi + +echo "Found pack name: ${PACK_NAME}" + + +# Copy pack files in root dir so the checks work +echo "Exporting PACK_NAME and removing pack directory" + +cp -r ${PACK_DIRECTORY}/* . +rm -rf ${PACK_DIRECTORY} + +echo "export PACK_NAME=$PACK_NAME" >> ~/.circlerc From 3ff1b188abe45fb328bc203548274dc18ce52a4f Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 11:19:50 +0200 Subject: [PATCH 18/45] Fix syntax error. --- .circleci/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d968753..01884ad 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,10 +14,10 @@ jobs: steps: - checkout - - run: - name: Prepare repository - command: | - .scripts/prepare-repo.sh + - run: + name: Prepare repository + command: | + .scripts/prepare-repo.sh - restore_cache: key: v1-dependency-cache-{{ checksum "requirements.txt" }} - run: From 1f0f2bcef984460837df1ba34f2a7945a30a2ef9 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 11:20:58 +0200 Subject: [PATCH 19/45] Fix syntax error. --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 01884ad..ff1ab5c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,9 +15,9 @@ jobs: steps: - checkout - run: - name: Prepare repository - command: | - .scripts/prepare-repo.sh + name: Prepare repository + command: | + .scripts/prepare-repo.sh - restore_cache: key: v1-dependency-cache-{{ checksum "requirements.txt" }} - run: From ad1663912a2745db4d57954aa3741d63c28875a6 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 11:24:33 +0200 Subject: [PATCH 20/45] Simplify circle ci config. --- .circleci/config.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ff1ab5c..e7ff1e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,10 +44,9 @@ jobs: workflows: version: 2 - build_test_deploy: - jobs: - - build_and_test: - filters: - branches: - ignore: - - master + jobs: + - build_and_test: + filters: + branches: + ignore: + - master From 01bd0679fe47447def3908aa55bef1e43c7e89e8 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 11:52:58 +0200 Subject: [PATCH 21/45] Fix syntax. --- .circleci/config.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e7ff1e9..ef5b4fc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -44,9 +44,10 @@ jobs: workflows: version: 2 - jobs: - - build_and_test: - filters: - branches: - ignore: - - master + build_and_test: + jobs: + - build_and_test: + filters: + branches: + ignore: + - master From 35c7e0779538ad4c5097dfb4832547fd0cb8e286 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 11:53:34 +0200 Subject: [PATCH 22/45] Remove config to get rid of build triggered twice issue: https://discuss.circleci.com/t/each-workflow-getting-triggered-twice-on-code-push/23963/4 --- .circleci/config.yml | 53 -------------------------------------------- 1 file changed, 53 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index ef5b4fc..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,53 +0,0 @@ -version: 2 - -jobs: - build_and_test: - docker: - - image: circleci/python:2.7 - - image: rabbitmq:3 - - image: mongo:3.4 - - working_directory: ~/repo - - environment: - VIRTUALENV_DIR: "~/virtualenv" - - steps: - - checkout - - run: - name: Prepare repository - command: | - .scripts/prepare-repo.sh - - restore_cache: - key: v1-dependency-cache-{{ checksum "requirements.txt" }} - - run: - name: Download dependencies - command: | - git clone -b master git@github.com:stackstorm-exchange/ci.git ~/ci - ~/ci/.circle/dependencies - - run: - name: Run tests - command: ~/ci/.circle/test - - save_cache: - key: v1-dependency-cache-{{ checksum "requirements.txt" }} - paths: - - ~/.cache/pip - - ~/.apt-cache - - persist_to_workspace: - root: / - paths: - - home/circleci/ci - - home/circleci/virtualenv - - tmp/st2 - - home/circleci/repo - - home/circleci/.gitconfig - -workflows: - version: 2 - build_and_test: - jobs: - - build_and_test: - filters: - branches: - ignore: - - master From 23fff8302a670df823d3d990a34c228caa97a224 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:12:49 +0200 Subject: [PATCH 23/45] Revert "Remove config to get rid of build triggered twice issue:" This reverts commit 35c7e0779538ad4c5097dfb4832547fd0cb8e286. --- .circleci/config.yml | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..ef5b4fc --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,53 @@ +version: 2 + +jobs: + build_and_test: + docker: + - image: circleci/python:2.7 + - image: rabbitmq:3 + - image: mongo:3.4 + + working_directory: ~/repo + + environment: + VIRTUALENV_DIR: "~/virtualenv" + + steps: + - checkout + - run: + name: Prepare repository + command: | + .scripts/prepare-repo.sh + - restore_cache: + key: v1-dependency-cache-{{ checksum "requirements.txt" }} + - run: + name: Download dependencies + command: | + git clone -b master git@github.com:stackstorm-exchange/ci.git ~/ci + ~/ci/.circle/dependencies + - run: + name: Run tests + command: ~/ci/.circle/test + - save_cache: + key: v1-dependency-cache-{{ checksum "requirements.txt" }} + paths: + - ~/.cache/pip + - ~/.apt-cache + - persist_to_workspace: + root: / + paths: + - home/circleci/ci + - home/circleci/virtualenv + - tmp/st2 + - home/circleci/repo + - home/circleci/.gitconfig + +workflows: + version: 2 + build_and_test: + jobs: + - build_and_test: + filters: + branches: + ignore: + - master From e596d195c8122e6b2b6d74e63182549182a7ce47 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:15:27 +0200 Subject: [PATCH 24/45] Print contents of the current directory. --- .scripts/prepare-repo.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.scripts/prepare-repo.sh b/.scripts/prepare-repo.sh index c68bb76..6eb0bb7 100755 --- a/.scripts/prepare-repo.sh +++ b/.scripts/prepare-repo.sh @@ -25,4 +25,6 @@ echo "Exporting PACK_NAME and removing pack directory" cp -r ${PACK_DIRECTORY}/* . rm -rf ${PACK_DIRECTORY} +ls -la . + echo "export PACK_NAME=$PACK_NAME" >> ~/.circlerc From 49ccb8f8e074d81cb2474a41d673e1ea6af9bf5d Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:17:06 +0200 Subject: [PATCH 25/45] Force check all the files. --- .scripts/prepare-repo.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.scripts/prepare-repo.sh b/.scripts/prepare-repo.sh index 6eb0bb7..c650b72 100755 --- a/.scripts/prepare-repo.sh +++ b/.scripts/prepare-repo.sh @@ -28,3 +28,4 @@ rm -rf ${PACK_DIRECTORY} ls -la . echo "export PACK_NAME=$PACK_NAME" >> ~/.circlerc +echo "export FORCE_CHECK_ALL_FILES=true" >> ~/.circlerc From c3a56909edbb473b4d4334e7279940e1b40ec77a Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:29:46 +0200 Subject: [PATCH 26/45] Set FORCE_CHECK_ALL_FILES env varible. --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ef5b4fc..ea1a4dd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,6 +11,7 @@ jobs: environment: VIRTUALENV_DIR: "~/virtualenv" + FORCE_CHECK_ALL_FILES: "true" steps: - checkout From 0f5e99e93c542c319f8808dcd819b56b47078757 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:43:05 +0200 Subject: [PATCH 27/45] Dummy isssue to test the build. --- jinja/actions/render_file.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jinja/actions/render_file.yaml b/jinja/actions/render_file.yaml index 9f7b68e..ffd7c4a 100644 --- a/jinja/actions/render_file.yaml +++ b/jinja/actions/render_file.yaml @@ -9,8 +9,7 @@ parameters: type: "string" description: "Path to the template" required: true - template_path: - type: "string" +type: "string" description: "Path to the template" required: true context: From fc54d34b813b4e8d2e872a34d5aa246283426576 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:47:08 +0200 Subject: [PATCH 28/45] Revert "Dummy isssue to test the build." This reverts commit 0f5e99e93c542c319f8808dcd819b56b47078757. --- jinja/actions/render_file.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jinja/actions/render_file.yaml b/jinja/actions/render_file.yaml index ffd7c4a..9f7b68e 100644 --- a/jinja/actions/render_file.yaml +++ b/jinja/actions/render_file.yaml @@ -9,7 +9,8 @@ parameters: type: "string" description: "Path to the template" required: true -type: "string" + template_path: + type: "string" description: "Path to the template" required: true context: From 7ce31afdbf79ef967140523ab83cb0bd13fec217 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:47:35 +0200 Subject: [PATCH 29/45] Test lint build failure. --- jinja/actions/render_file.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jinja/actions/render_file.py b/jinja/actions/render_file.py index 9b185c8..bdf2114 100644 --- a/jinja/actions/render_file.py +++ b/jinja/actions/render_file.py @@ -16,6 +16,8 @@ import six import os +import foo + from st2common.runners.base_action import Action from st2client.client import Client from st2common.content import utils as content_utils @@ -23,7 +25,7 @@ class FormatResultAction(Action): - def __init__(self, config=None, action_service=None): + def __init__(self, config=None, action_service = None): super(FormatResultAction, self).__init__(config=config, action_service=action_service) api_url = os.environ.get('ST2_ACTION_API_URL', None) From bf1518010e7918a38f31a2c926c524fd3883edab Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 12:49:28 +0200 Subject: [PATCH 30/45] Remove test pack. --- jinja/.gitignore | 89 --------------------------------- jinja/actions/render_file.py | 64 ------------------------ jinja/actions/render_file.yaml | 25 --------- jinja/icon.png | Bin 2229 -> 0 bytes jinja/pack.yaml | 9 ---- jinja/requirements.txt | 0 6 files changed, 187 deletions(-) delete mode 100644 jinja/.gitignore delete mode 100644 jinja/actions/render_file.py delete mode 100644 jinja/actions/render_file.yaml delete mode 100644 jinja/icon.png delete mode 100644 jinja/pack.yaml delete mode 100644 jinja/requirements.txt diff --git a/jinja/.gitignore b/jinja/.gitignore deleted file mode 100644 index 260ff8d..0000000 --- a/jinja/.gitignore +++ /dev/null @@ -1,89 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -./lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# IPython Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# dotenv -.env - -# virtualenv -venv/ -ENV/ - -# Spyder project settings -.spyderproject - -# Rope project settings -.ropeproject diff --git a/jinja/actions/render_file.py b/jinja/actions/render_file.py deleted file mode 100644 index bdf2114..0000000 --- a/jinja/actions/render_file.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed to the StackStorm, Inc ('StackStorm') under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import six -import os - -import foo - -from st2common.runners.base_action import Action -from st2client.client import Client -from st2common.content import utils as content_utils -from st2common.util import jinja as jinja_utils - - -class FormatResultAction(Action): - def __init__(self, config=None, action_service = None): - super(FormatResultAction, self).__init__(config=config, action_service=action_service) - - api_url = os.environ.get('ST2_ACTION_API_URL', None) - token = os.environ.get('ST2_ACTION_AUTH_TOKEN', None) - - self.client = Client(api_url=api_url, token=token) - - self.jinja = jinja_utils.get_jinja_environment(allow_undefined=True) - self.jinja.tests['in'] = lambda item, list: item in list - - def run(self, template_pack, template_path, context, include_execution, include_six): - if include_six: - context['six'] = six - - if include_execution: - execution = self._get_execution(include_execution) - context['__execution'] = execution - - pack_path = content_utils.get_pack_base_path(template_pack) - abs_template_path = os.path.abspath(os.path.join(pack_path, template_path)) - - if not abs_template_path.startswith(pack_path): - raise ValueError('Template_path points to a file outside pack directory.') - - with open(abs_template_path, 'r') as f: - template = f.read() - - return self.jinja.from_string(template).render(context) - - def _get_execution(self, execution_id): - if not execution_id: - raise ValueError('Invalid execution_id provided.') - execution = self.client.liveactions.get_by_id(id=execution_id) - if not execution: - return None - return execution.to_dict() diff --git a/jinja/actions/render_file.yaml b/jinja/actions/render_file.yaml deleted file mode 100644 index 9f7b68e..0000000 --- a/jinja/actions/render_file.yaml +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: "render_file" -runner_type: "python-script" -description: "Render template" -enabled: true -entry_point: "render_file.py" -parameters: - template_pack: - type: "string" - description: "Path to the template" - required: true - template_path: - type: "string" - description: "Path to the template" - required: true - context: - type: object - description: "Context to render" - default: {} - include_execution: - type: string - description: "Include execution of the certain id to jinja context as `__execution` property" - include_six: - type: boolean - default: true diff --git a/jinja/icon.png b/jinja/icon.png deleted file mode 100644 index 3eac885d5209567e30b57e420a4cf5a847f12b26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2229 zcmV;m2uk;fP)00009a7bBm000ie z000ie0hKEb8vpD(`dA;tgKl8 zpu4-9#bPm;%*e<{D=RCS$Y^hGpHTosMMZIOahaK!2&l8ObG$=;e}8jxb4f`_T3Q-| z!SMI@-@AA3x^?Re3=9+%6=~y!pP%210!T2C8fVa#+*5G6ciL_5)3$7TU+10 zeS1b#sJFM*+}xZdjq&>RYZ=HWR1X-yqGijL{c-4tgK$W`qHIK!NI|c7ca&%G&GdQ8IGc|vJ#nETU+bv>x=k; zf`XtYb#-+}RstY7IT@ZoBQ_d+w0e_)9G~C1AsC@g%F>cn;YV@v$I2R z#l^)dR;(ZZu!5i`WRbVGw~PTG`VAX4XlQ6iPJK8-On2_wX>V`;=+Pq?0~i<>z{VpW zcXxLi8ym!j1OS&%B2rURKY#uVwv-7+O-;>#0|y|lZEbCM>W6UrLH{$2mH5t`I{@(N z)vI4Q03;kHta`EmfCOl4Z0zXhAk&K%FCxCAq@+;?E|(h^7=g*&mHgG5{ zEybU({V3J41c2bc975|gYt~?24<9}Z`{~oCckkYHb#*;-=ulKt)bi!aNu3S}2_dx) z>;hC}Wo49V9UYzDoY=IVKz)5ZRNvIpl=NZF&d!)Vd-g0kIvRl*8yn~6=f}s#!^R=N zfe7n~6DMGMdV0dXdGn?$DHI+ajv%m?n>KA)zka>Cx;m!V`zu$jz(8`t$I;Odwu*`h zdS=oc&7VJi`}XaqZb;~yoE%vKXlQ6aK%fCAv|zykQhE^|Y*Mh`gBlDQ)f$ZhV31M` z?m?_zpqZ7i3awhT%E`$I6oOEqF9L?x*jQvX*s^u&RyZUkCL(AEC~+or07^=l+4S^u z83VvJ0|4Zl^bP<(RA}karEAx&g@MZe0^PT7A8bQIL)c(WQ&SWA3)t`8y^}Ej5Q7AV zYmL6XJ^;LY`4UqjBO?n73m7RWDF}4Wo;|QhGY0@wRaH<`*l*svktG215y(qWh1|I` zH8nAHadAOE2cB43T8>t?-Me@5`FvYjTLJ*6;3IngL@vhn4&aV#QS*j`><1VCP1o{x{u6z`K#0Dz_vR6(-0l-o4 zs;hq${gCj5|M+zr7r(1(LTBnD@m@?GKunAnfR>aLFrlZUgo;2QXnFCXE;6#8&F0nC z)?d3;e(F@&v14@+5q&Jy=p)#8?t=&L9FAKc=q@PWFc_77ex*l`mU?*91P8ZH=7Kf} z0NjTU#QgF&W+&dwCS)zwSg-P_XAcr`Vhxw%;e23V~0_a{EA zurN%q*~4#$%gbv+L)+8S;ml*Pu=n}fwo#Z33sK)VUmYAo0e~}@mYq5! z`czwLDi)bKI%L`yA5Wcti_33*=)H;xe0Y*ox=8@&=W@jWfC-`iYA#%$Haj3dtX5>s zo0p-aM8x->%uGtSwrmmg5uhPyYU;?&1{WH#>V(7OL%`6E);orI4-PD z3jiYXqtgN>C#*C?MGdQvrzfU)*4E=y2suCk0+F&7E<`Iq@YD)bmFQ-^ogFDGK#Nn7 zK81KyRg{FgyZ`Kt=yVjOR^dAcs?SME0*lyV|Krk?pI_nQQ#B$@6oqtkag2k)e=$LS z*fB8$j*i%uzc+3yadYFw$D?R`b9Lp9yfBs;fa>62im&(Yk7;0pW5TJJ8?k#zOR>SD zNjxm0d_F`LV1@<<$&?sU1AyIvenUNQvb~j+Q)wO>6B4is#Uri6^me1Hh=>Av`>#88 zpk<(n5sg-L?%b4KA{7>rHi`6q(+;5g^l9iOHlB!2bztBWe+-oyja^e>;tX9WL0qUF z8b*9j>Zkr={LW6nl>a3oztqbC$N|U!$N|U!h>ZULR*2XX&sQOk00000NkvXXu0mjf D$`1k% diff --git a/jinja/pack.yaml b/jinja/pack.yaml deleted file mode 100644 index ac09d72..0000000 --- a/jinja/pack.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: jinja -description: Jinja template engine -keywords: - - jinja - - template - - templating -version: 0.1.1 -author: StackStorm, inc. -email: support@stackstorm.com diff --git a/jinja/requirements.txt b/jinja/requirements.txt deleted file mode 100644 index e69de29..0000000 From b3e67e8ddeebfbba4cec0ebd9ccdee28d1d13861 Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 14:32:24 +0200 Subject: [PATCH 31/45] Update Circle CI config to check submodules. --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea1a4dd..50250d1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,6 +15,12 @@ jobs: steps: - checkout + # Download submodules for any PR which might add pack as a submodule + - run: + name: Checkout submodules + command: | + git submodule init + git submodule update --remote - run: name: Prepare repository command: | From 705632eba832454370205c3f560720a6c6d1604f Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 14:33:27 +0200 Subject: [PATCH 32/45] Add test submodule. --- .gitmodules | 3 +++ stackstorm-influxdb | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 stackstorm-influxdb diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1ff5444 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "stackstorm-influxdb"] + path = stackstorm-influxdb + url = https://github.com/EncoreTechnologies/stackstorm-influxdb.git diff --git a/stackstorm-influxdb b/stackstorm-influxdb new file mode 160000 index 0000000..1e32cf3 --- /dev/null +++ b/stackstorm-influxdb @@ -0,0 +1 @@ +Subproject commit 1e32cf32a6e8b6ce7e3b2ed74a368c1fbc667491 From 3d0c92acc03fdd1a26bffd19868a7474e5f5658d Mon Sep 17 00:00:00 2001 From: Tomaz Muraus Date: Thu, 25 Oct 2018 14:39:25 +0200 Subject: [PATCH 33/45] Remove test submodule. --- .gitmodules | 3 --- stackstorm-influxdb | 1 - 2 files changed, 4 deletions(-) delete mode 160000 stackstorm-influxdb diff --git a/.gitmodules b/.gitmodules index 1ff5444..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "stackstorm-influxdb"] - path = stackstorm-influxdb - url = https://github.com/EncoreTechnologies/stackstorm-influxdb.git diff --git a/stackstorm-influxdb b/stackstorm-influxdb deleted file mode 160000 index 1e32cf3..0000000 --- a/stackstorm-influxdb +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1e32cf32a6e8b6ce7e3b2ed74a368c1fbc667491 From 58046ff28e1a83fb011aee86c36451133923deae Mon Sep 17 00:00:00 2001 From: sonu kumar meena Date: Fri, 22 Feb 2019 12:59:38 +0530 Subject: [PATCH 34/45] added nexus3 --- stackstorm-nexus3/.gitignore | 89 +++++++++ stackstorm-nexus3/.yo-rc.json | 90 +++++++++ stackstorm-nexus3/README-test.md | 97 ++++++++++ stackstorm-nexus3/README.md | 80 ++++++++ .../actions/create_repositories.yaml | 77 ++++++++ stackstorm-nexus3/actions/create_scripts.yaml | 19 ++ .../actions/delete_repositories.yaml | 19 ++ stackstorm-nexus3/actions/delete_scripts.yaml | 19 ++ .../actions/get_repositories.yaml | 19 ++ stackstorm-nexus3/actions/get_scripts.yaml | 19 ++ stackstorm-nexus3/actions/lib/__init__.py | 0 stackstorm-nexus3/actions/lib/base.py | 178 ++++++++++++++++++ stackstorm-nexus3/actions/lib/exception.py | 38 ++++ .../actions/list_repositories.yaml | 15 ++ stackstorm-nexus3/actions/list_scripts.yaml | 15 ++ stackstorm-nexus3/actions/run.py | 34 ++++ stackstorm-nexus3/actions/run_scripts.yaml | 23 +++ stackstorm-nexus3/config.schema.yaml | 31 +++ stackstorm-nexus3/icon.png | Bin 0 -> 1521 bytes stackstorm-nexus3/nexus3.yaml.example | 12 ++ stackstorm-nexus3/pack.yaml | 13 ++ .../policies/retry_core_http_on_timeout.yaml | 10 + stackstorm-nexus3/requirements.txt | 2 + stackstorm-nexus3/tests/Makefile | 40 ++++ .../tests/fixtures/get_repositories.json | 0 .../tests/fixtures/list_repositories.json | 0 stackstorm-nexus3/tests/test_run.py | 12 ++ 27 files changed, 951 insertions(+) create mode 100644 stackstorm-nexus3/.gitignore create mode 100644 stackstorm-nexus3/.yo-rc.json create mode 100644 stackstorm-nexus3/README-test.md create mode 100644 stackstorm-nexus3/README.md create mode 100644 stackstorm-nexus3/actions/create_repositories.yaml create mode 100644 stackstorm-nexus3/actions/create_scripts.yaml create mode 100644 stackstorm-nexus3/actions/delete_repositories.yaml create mode 100644 stackstorm-nexus3/actions/delete_scripts.yaml create mode 100644 stackstorm-nexus3/actions/get_repositories.yaml create mode 100644 stackstorm-nexus3/actions/get_scripts.yaml create mode 100644 stackstorm-nexus3/actions/lib/__init__.py create mode 100644 stackstorm-nexus3/actions/lib/base.py create mode 100644 stackstorm-nexus3/actions/lib/exception.py create mode 100644 stackstorm-nexus3/actions/list_repositories.yaml create mode 100644 stackstorm-nexus3/actions/list_scripts.yaml create mode 100644 stackstorm-nexus3/actions/run.py create mode 100644 stackstorm-nexus3/actions/run_scripts.yaml create mode 100644 stackstorm-nexus3/config.schema.yaml create mode 100644 stackstorm-nexus3/icon.png create mode 100644 stackstorm-nexus3/nexus3.yaml.example create mode 100644 stackstorm-nexus3/pack.yaml create mode 100644 stackstorm-nexus3/policies/retry_core_http_on_timeout.yaml create mode 100644 stackstorm-nexus3/requirements.txt create mode 100644 stackstorm-nexus3/tests/Makefile create mode 100644 stackstorm-nexus3/tests/fixtures/get_repositories.json create mode 100644 stackstorm-nexus3/tests/fixtures/list_repositories.json create mode 100644 stackstorm-nexus3/tests/test_run.py diff --git a/stackstorm-nexus3/.gitignore b/stackstorm-nexus3/.gitignore new file mode 100644 index 0000000..bf2c63a --- /dev/null +++ b/stackstorm-nexus3/.gitignore @@ -0,0 +1,89 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +./lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject \ No newline at end of file diff --git a/stackstorm-nexus3/.yo-rc.json b/stackstorm-nexus3/.yo-rc.json new file mode 100644 index 0000000..71f3aee --- /dev/null +++ b/stackstorm-nexus3/.yo-rc.json @@ -0,0 +1,90 @@ +{ + "generator-st2pack": { + "promptValues": { + "features": [ + "Sensors", + "Rules", + "Policies", + "Aliases" + ], + "pack_ref": "nexus3", + "pack_name": "Sontatype Nexus3", + "pack_desc": "Sontatype nexus3 stackstorm pack" + }, + "actions": {}, + "aliases": { + "greet": { + "name": "greet", + "pack": "nexus3", + "description": "Greet StackStorm", + "action_ref": "nexus3.greet", + "formats": [ + "greet {{greeting}}" + ] + } + }, + "rules": { + "on_hello_event1": { + "name": "on_hello_event1", + "pack": "nexus3", + "description": "Sample rule firing on nexus3.event1.", + "enabled": true, + "trigger": { + "type": "nexus3.event1" + }, + "action": { + "ref": "nexus3.greet", + "parameters": { + "greeting": "Yo" + } + } + } + }, + "sensors": { + "HelloSensor": { + "class_name": "HelloSensor", + "entry_point": "sensor1.py", + "description": "Test sensor that emits triggers.", + "trigger_types": [ + { + "name": "event1", + "description": "An example trigger.", + "payload_schema": { + "type": "object" + } + } + ] + } + }, + "policies": { + "http.retry": { + "name": "http.retry", + "description": "Retry core.http action on timeout.", + "enabled": true, + "resource_ref": "core.http", + "policy_type": "action.retry", + "parameters": { + "retry_on": "timeout", + "max_retry_count": 2, + "delay": 2 + } + }, + "greet.concurrency": { + "name": "greet.concurrency", + "pack": "nexus3", + "description": "Limits the concurrent executions of the greet action.", + "enabled": true, + "resource_ref": "nexus3.greet", + "policy_type": "action.concurrency", + "parameters": { + "threshold": 10 + } + } + }, + "pack": { + "ref": "nexus3", + "name": "Sontatype Nexus3", + "description": "Sontatype nexus3 stackstorm pack" + } + } +} \ No newline at end of file diff --git a/stackstorm-nexus3/README-test.md b/stackstorm-nexus3/README-test.md new file mode 100644 index 0000000..47b8a59 --- /dev/null +++ b/stackstorm-nexus3/README-test.md @@ -0,0 +1,97 @@ +## Testing locally + + +Copy component files + + cp -rf actions/* /opt/stackstorm/packs/nexus3/actions/ + +If any *.yaml file is changed, run reload accordingly. + + st2ctl reload --register-configs + st2ctl reload --register-actions + st2ctl reload --register-rules + + +trigger Execution + + List Repository: + + ST2_ACTION_CMD='st2 action execute nexus3.list_repositories config_profile=dev' + + Create Repository + + ST2_ACTION_CMD='st2 action execute nexus3.create_repositories config_profile=dev type=hosted name=maven2-dumy format=maven write_policy=ALLOW' + + Get Repository + + ST2_ACTION_CMD='st2 action execute nexus3.get_repositories config_profile=dev name=maven2-dumy' + + Delete Repository + + ST2_ACTION_CMD='st2 action execute nexus3.delete_repositories config_profile=dev name=maven2-dumy' + + List Scripts: + + ST2_ACTION_CMD='st2 action execute nexus3.list_scripts config_profile=dev' + + Get scripts + + ST2_ACTION_CMD='st2 action execute nexus3.get_scripts config_profile=dev name=nexus3-cli-repository-create' + + Delete Scripts + + ST2_ACTION_CMD='st2 action execute nexus3.delete_scripts config_profile=dev name=nexus3-cli-repository-delete' + + Excecute it: + + $ST2_ACTION_CMD | grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}"; + + Running them continuously: + + while true; do mkdir -p /opt/stackstorm/packs/nexus3; cp -rf ./* /opt/stackstorm/packs/nexus3/; chmod -R --reference /opt/stackstorm/packs/linux /opt/stackstorm/packs/nexus3; chown -R --reference /opt/stackstorm/packs/linux/pack.yaml /opt/stackstorm/packs/nexus3/*; $ST2_ACTION_CMD | grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}" sleep 2; done; + + + +If any `yaml` file is updated , update it: + + #eg. updating action list_repositories.yaml + st2 action update nexus3.list_repositories ./actions/list_repositories.yaml + +Get executions + + st2 execution list -n 1 + + +``` json +{ + "success": true, + "data": { + "name": "dummy1", + "type": "hosted", + "format": "maven2", + "recipe": "maven2-hosted", + "online": true, + "attributes": { + "cleanup": { + "policyName": "None" + }, + "maven": { + "versionPolicy": "RELEASE", + "layoutPolicy": "STRICT" + }, + "storage": { + "strictContentTypeValidation": true, + "writePolicy": "ALLOW_ONCE", + "blobStoreName": "default" + } + }, + "url": "http://localhost:8081/repository/dummy1/", + "status": { + "repositoryName": "dummy1", + "online": true, + "description": null, + "reason": null + } + } +} +`` \ No newline at end of file diff --git a/stackstorm-nexus3/README.md b/stackstorm-nexus3/README.md new file mode 100644 index 0000000..404b01a --- /dev/null +++ b/stackstorm-nexus3/README.md @@ -0,0 +1,80 @@ +# Stackstorm-Sontatype Nexus3 + + +Sontatype nexus3 stackstorm pack + +## Installation + + +Install this pack with: `st2 pack install file:///$PWD` + +Or if in remote repository: `st2 pack install https://github.com/MY/PACK` + +## Configuration + +Copy the example configuration in [nexus3.yaml.example](./nexus3.yaml.example) +to `/opt/stackstorm/configs/nexus3.yaml` and edit as required. + +add nexus3 server connection profile: + +* ``url`` - URL of the nexus3 server (e.g. ``http://localhost:8081``) +* ``user`` - username +* ``password`` - Password +* ``verify`` - https tls verify + +You can also add multiple profiles: + +When you add multiple profile, above parameters becomes defaults for any key missing in the profile. + +``` yaml +--- +url: "http://localhost:8081" +user: "admin" +password: "admin123" +verify: True +default_profile: "dev" # use this to make for missing config_profile parameter when calling any action +profiles: + "dev": + url: "http://localhost:8081" + user: "dev-user" + password: "mypas" + verify: True + "dev-2": + user: "dev2-user" + password: "mypass2" + # url : fallback to url: "http://localhost:8081" + # verify: fallback to verify: True +``` + + +**Note** : When modifying the configuration in `/opt/stackstorm/configs/` please + remember to tell StackStorm to load these new values by running + `st2ctl reload --register-configs` + + +## Actions + +* **list_repositories** : List nexus3 repositories +* **get_repositories** : get nexus3 repositories +* **create_repositories** : create nexus3 repository +* **delete_repositories** : delete nexus3 repository + +* **list_scripts** : List nexus3 scripts +* **get_scripts** : get nexus3 scripts +* **create_scripts** : create(& upload) if missing, groovy script +* **delete_scripts** : delete nexus3 script + +## Aliases + + +## Rules + + +## Sensors + + +## Policies + +* **http.retry** : Retry core.http action on timeout. + + diff --git a/stackstorm-nexus3/actions/create_repositories.yaml b/stackstorm-nexus3/actions/create_repositories.yaml new file mode 100644 index 0000000..b73f5f3 --- /dev/null +++ b/stackstorm-nexus3/actions/create_repositories.yaml @@ -0,0 +1,77 @@ +--- +name: create_repositories +runner_type: python-script +description: Create a repository +enabled: true +entry_point: run.py +parameters: + action: + default: create_repositories + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false + name: + type: string + description: A unique identifier for this repository + required: true + format: + type: string + description: The format of the repository (i.e. maven2, docker, raw, nuget...) + required: true + enum: + - bower + - docker + - gitlfs + - maven + - npm + - nuget + - pypi + - raw + - rubygems + - yum + type: + type: string + description: The type of repository (i.e. group, hosted, or proxy) + required: true + enum: + - hosted + - proxy + version_policy: + type: string + description: What type of artifacts does this repository store? + required: false + default: RELEASE + enum: + - RELEASE + - SNAPSHOT + - MIXED + layout_policy: + type: string + description: Validate that all paths are maven artifact or metadata paths + required: false + default: STRICT + enum: + - STRICT + - PERMISSIVE + blob_store_name: + type: string + description: Blob store used to store asset contents + required: true + default: "default" + strict_content_type_validation: + type: boolean + description: Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format + required: true + default: false + write_policy: + type: string + description: Controls if deployments of and updates to artifacts are allowed + required: true + default: ALLOW + enum: + - ALLOW_ONCE + - ALLOW + - DENY \ No newline at end of file diff --git a/stackstorm-nexus3/actions/create_scripts.yaml b/stackstorm-nexus3/actions/create_scripts.yaml new file mode 100644 index 0000000..5e80f3e --- /dev/null +++ b/stackstorm-nexus3/actions/create_scripts.yaml @@ -0,0 +1,19 @@ +--- +name: create_scripts +runner_type: python-script +description: create a script +enabled: true +entry_point: run.py +parameters: + action: + default: create_scripts + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false + data: + type: object + description: instance of script to be created. + required: false \ No newline at end of file diff --git a/stackstorm-nexus3/actions/delete_repositories.yaml b/stackstorm-nexus3/actions/delete_repositories.yaml new file mode 100644 index 0000000..43ef39f --- /dev/null +++ b/stackstorm-nexus3/actions/delete_repositories.yaml @@ -0,0 +1,19 @@ +--- +name: delete_repositories +runner_type: python-script +description: delete all repositories of nexus3 +enabled: true +entry_point: run.py +parameters: + action: + default: delete_repositories + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false + name: + type: string + description: A unique identifier of the repository to delete + required: true \ No newline at end of file diff --git a/stackstorm-nexus3/actions/delete_scripts.yaml b/stackstorm-nexus3/actions/delete_scripts.yaml new file mode 100644 index 0000000..f3e5655 --- /dev/null +++ b/stackstorm-nexus3/actions/delete_scripts.yaml @@ -0,0 +1,19 @@ +--- +name: delete_scripts +runner_type: python-script +description: delete a script +enabled: true +entry_point: run.py +parameters: + action: + default: delete_scripts + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false + name: + type: string + description: name of script to be deleted + required: true \ No newline at end of file diff --git a/stackstorm-nexus3/actions/get_repositories.yaml b/stackstorm-nexus3/actions/get_repositories.yaml new file mode 100644 index 0000000..d9d630a --- /dev/null +++ b/stackstorm-nexus3/actions/get_repositories.yaml @@ -0,0 +1,19 @@ +--- +name: get_repositories +runner_type: python-script +description: get repository identified by a unique identifier +enabled: true +entry_point: run.py +parameters: + action: + default: get_repositories + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false + name: + type: string + description: A unique identifier of the repository to fetch + required: true \ No newline at end of file diff --git a/stackstorm-nexus3/actions/get_scripts.yaml b/stackstorm-nexus3/actions/get_scripts.yaml new file mode 100644 index 0000000..d527cb1 --- /dev/null +++ b/stackstorm-nexus3/actions/get_scripts.yaml @@ -0,0 +1,19 @@ +--- +name: get_scripts +runner_type: python-script +description: Fetch script specified by name +enabled: true +entry_point: run.py +parameters: + action: + default: get_scripts + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false + name: + type: string + description: name of script to be fetched. + required: true \ No newline at end of file diff --git a/stackstorm-nexus3/actions/lib/__init__.py b/stackstorm-nexus3/actions/lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stackstorm-nexus3/actions/lib/base.py b/stackstorm-nexus3/actions/lib/base.py new file mode 100644 index 0000000..03d871a --- /dev/null +++ b/stackstorm-nexus3/actions/lib/base.py @@ -0,0 +1,178 @@ +import sys +from exception import * +from nexuscli.repository import Repository +from nexuscli.nexus_client import NexusClient +from nexuscli.exception import * + +from st2common.runners.base_action import Action + +__all__ = [ + 'BaseAction' +] + +REQUIRED_FIELDS = ['url', 'user', 'password'] + + +class BaseAction(Action): + + def __init__(self, config): + super(BaseAction, self).__init__(config) + self.nexus_profiles = self.config.get('profiles', {}) + self.nexus_client = None + self.dial_config = None + + def validate_config(self, c_profile): + """ Validate connection configuration + + """ + validation_errors = [] + is_valid = True + for field in REQUIRED_FIELDS: + if c_profile.get(field, None) == None: + validation_errors.push("%s if missing" % field) + is_valid = False + + return (is_valid, validation_errors) + + def get_connection_defaults(self): + """ default properties + + """ + return { + "url": self.config.get('url', None), + "verify": self.config.get('verify', True), + "user": self.config.get('user', None), + "password": self.config.get('password', None) + } + + def init_config(self, profile=None): + """ Get nexus3 server connection string + + """ + self.dial_config = self.get_connection_defaults() + if profile is not None: + profile = profile.strip() + if len(profile) == 0: + profile = None + + # use 'default_profile' if 'config_profile' is empty + if profile is None: + profile = self.config.get('default_profile', None) + + # Use defaults options, if neither config_profile nor default_profile is provided + if profile is None: + self.logger.info("using defaults connection values") + else: + c_profile = self.nexus_profiles.get(profile, None) + if c_profile is None: + raise MissingProfileError( + "connection profile not found: '%s'" % profile) + + self.dial_config.update(c_profile) + + # Validate configuration + (is_valid, errors) = self.validate_config(self.dial_config) + if not is_valid: + raise ValidationFailError( + "Validation failed: %s" % errors) + + return self.dial_config + + def init_dialer(self): + try: + self.logger.debug("connection string: %s \n" % self.dial_config) + self.nexus_client = NexusClient(**self.dial_config) + except Exception as error: + self.logger.error("Couldn't instantiate nexus client %s" % error) + + def get_resource_dialer(self, resource): + """ return nexus_client + + """ + if self.nexus_client is None: + raise NexusClientNotInstantiatedError( + "Instantiate nexus_client by calling init_dialer() method first") + return getattr(self.nexus_client, resource) + + def intent_list(self, resource, **kwargs): + """ Intent: List + + """ + dialer = self.get_resource_dialer(resource) + is_success = True + response = {} + if resource == "repositories": + response = dialer.raw_list() + else: + response = dialer.list() + + return (is_success, response) + + def intent_get(self, resource, **kwargs): + """ Intent: GET + + """ + dialer = self.get_resource_dialer(resource) + is_success = True + response = {} + if resource == "repositories": + response = dialer.get_raw_by_name(kwargs.pop('name')) + else: + response = dialer.get(kwargs.pop('name')) + + return (is_success, response) + + def intent_create(self, resource, **kwargs): + """ Intent: CREATE + + """ + dialer = self.get_resource_dialer(resource) + is_success = True + response = {} + payload = kwargs.get('data', '') + + if resource == "repositories": + repo_type = kwargs.pop('type') + payload = Repository(repo_type, **kwargs) + + try: + if resource == "scripts": + response = dialer.create_if_missing(payload) + else: + response = dialer.create(payload) + except NexusClientCreateRepositoryError as error: + response = "Failed to create %s. Most likely reason, same name resource already exist." % ( + resource) + is_success = False + + return (is_success, response) + + def intent_run(self, resource, **kwargs): + """ Intent: RUN + + """ + dialer = self.get_resource_dialer(resource) + is_success = True + response = {} + if resource == "scripts": + response = dialer.run(kwargs.pop('name'), kwargs.pop('data')) + else: + is_success = False + response = "Invalid resource: %s(supported only scripts)" % resource + + return (is_success, response) + + def intent_delete(self, resource, **kwargs): + """ Intent: DELETE + + """ + dialer = self.get_resource_dialer(resource) + is_success = True + response = {} + try: + response = dialer.delete(kwargs.pop('name')) + except NexusClientAPIError as error: + is_success = False + response = error + + return (is_success, response) diff --git a/stackstorm-nexus3/actions/lib/exception.py b/stackstorm-nexus3/actions/lib/exception.py new file mode 100644 index 0000000..2cae8b5 --- /dev/null +++ b/stackstorm-nexus3/actions/lib/exception.py @@ -0,0 +1,38 @@ + +__all__ = [ + "InvalidParameterError", + "MissingParameterError", + "MissingProfileError", + "ValidationFailError", + "NexusClientNotInstantiatedError" +] + + +class Error(Exception): + """Base class for other exceptions""" + pass + + +class InvalidParameterError(Error): + """Raised when input parameter is not valid""" + pass + + +class MissingParameterError(Error): + """Raised when required parameter is missing""" + pass + + +class MissingProfileError(Error): + """Raised when connection profile is missing""" + pass + + +class ValidationFailError(Error): + """Raised when connection profile has missing required fields""" + pass + + +class NexusClientNotInstantiatedError(Error): + """Raised when nexus_client is not instantiated""" + pass diff --git a/stackstorm-nexus3/actions/list_repositories.yaml b/stackstorm-nexus3/actions/list_repositories.yaml new file mode 100644 index 0000000..3d9d287 --- /dev/null +++ b/stackstorm-nexus3/actions/list_repositories.yaml @@ -0,0 +1,15 @@ +--- +name: list_repositories +runner_type: python-script +description: List all repositories of nexus3 +enabled: true +entry_point: run.py +parameters: + action: + default: list_repositories + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false \ No newline at end of file diff --git a/stackstorm-nexus3/actions/list_scripts.yaml b/stackstorm-nexus3/actions/list_scripts.yaml new file mode 100644 index 0000000..6623771 --- /dev/null +++ b/stackstorm-nexus3/actions/list_scripts.yaml @@ -0,0 +1,15 @@ +--- +name: list_scripts +runner_type: python-script +description: List all scripts +enabled: true +entry_point: run.py +parameters: + action: + default: list_scripts + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false \ No newline at end of file diff --git a/stackstorm-nexus3/actions/run.py b/stackstorm-nexus3/actions/run.py new file mode 100644 index 0000000..f583905 --- /dev/null +++ b/stackstorm-nexus3/actions/run.py @@ -0,0 +1,34 @@ +import sys +from lib import base +from st2common.runners.base_action import Action +from nexuscli.repository import Repository +from nexuscli.nexus_client import NexusClient +from nexuscli.exception import * +from lib.exception import * + + +class ActionManager(base.BaseAction): + + def run(self, **kwargs): + self.logger.debug(kwargs) + self.logger.debug(self.config) + try: + requested_action = kwargs.pop('action') + except KeyError as error: + raise MissingParameterError( + "'%s' required parameter is missing" % error) + + # Resolve connection config + self.init_config( + kwargs.pop('config_profile')) + + # Instantiating dialer + self.init_dialer() + + # Serve Request + [intent, resource] = requested_action.split('_') + intent_method_name = "intent_%s" % intent + (is_success, response) = getattr( + self, intent_method_name)(resource, **kwargs) + + return (is_success, response) diff --git a/stackstorm-nexus3/actions/run_scripts.yaml b/stackstorm-nexus3/actions/run_scripts.yaml new file mode 100644 index 0000000..9f7f604 --- /dev/null +++ b/stackstorm-nexus3/actions/run_scripts.yaml @@ -0,0 +1,23 @@ +--- +name: run_scripts +runner_type: python-script +description: Run script +enabled: true +entry_point: run.py +parameters: + action: + default: run_scripts + immutable: true + type: string + config_profile: + type: string + description: Select which nexus config profile to use. + required: false + name: + type: string + description: name of script to be run + required: true + data: + type: string + description: parameters to be passed to the script, via HTTP POST + required: false \ No newline at end of file diff --git a/stackstorm-nexus3/config.schema.yaml b/stackstorm-nexus3/config.schema.yaml new file mode 100644 index 0000000..4f5b400 --- /dev/null +++ b/stackstorm-nexus3/config.schema.yaml @@ -0,0 +1,31 @@ +--- +<<: &profile_options + url: + description: "URL of the JIRA instance (e.g. ``https://myproject.atlassian.net``)" + type: "string" + secret: false + required: true + verify: + description: "Verify SSL certificate. Set to False to disable verification. Default True" + type: boolean + default: True + user: + description: "username" + type: "string" + secret: false + required: false + password: + description: "Password" + type: "string" + secret: true + required: false +profiles: + description: "Nexus3 Connection profile." + type: object + required: false + properties: {} + additionalProperties: + type: object + additionalProperties: false + properties: + <<: *profile_options \ No newline at end of file diff --git a/stackstorm-nexus3/icon.png b/stackstorm-nexus3/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e9ebf2e735d416c14a808b18454f41d97f51fde8 GIT binary patch literal 1521 zcmVL z!-2GVdYNf`Z-4#d*WY|D75t>ahbJCrD}{Stpr31&25dayWMDD^CjMCikI)HpTrspG zCZkb03ecnj$BA%pBxtLc4xBIw76#53!wkEQB%pab;Q}9z7M={c;o5Jty; zjBF;QCzI;c>>z<3{`BqRgU0d9(#Y~>mmRwMTjWbZv<^>TnwqN$+@Z&y|Db09?*@3^ zSlzw<{qyq0?47S}phbv(0mF-jZ(2wG2Op1rvb>x!Y0^^66d8ilQtHczM1!};iDsb@ zESJq*TbcI#Fm`X2KxT{S@^Eo{v^p_7wqt9)I#x`>lQMw_ytmt@;%q}6(V!Rx3s+~F zl~a*HrqM1|c(=b?gmq=O1eQri7EgVl@u{bkrf06tyazIt;iSImS#h@1n%n?`)I3m!lI;7dTPE}EN5*md5{wu3WS8kq+sWuCzaNq@mxOr zY_0ZRy>n|ePagcTo-jItAb^bUG;cYR(JOZ}PMpnpJ5xxf3#oJH{&BFs+YY-Xfgex3 z%&5hCG{4>H`a!Oo0V7e0w9S7`TKoR{{8v-?;|J4j#G0y#+9Jo|A z0U0;E?C92mL)UN56^hw+f)lTQN#5U326H=bbe zc5^yTe1HD>Hy~ZUJ`T}Jmp&v`8}sVj`eGp}8-$x^4?Bow2vJCs9Ea(&9vZ7;bLoW} zlbLLaRSY1Nfzr-ae$`f-`hGI8ma^bHY~th3l=gG6-YVV z^!zsRWF*6!UYf6h4ZJXwZe>>gT6?p7aOKu$sghGn$50=fya4I$>7!chsK!Ra7Ge*v zhhbo%?$-PjzmbhE$jYVR*>a%(4s!3ibrVTo=(+%r&7Hf~xugLjODY!P+{@;XXC)w) zGwgWq_h+?@=iL`O^@iW>HXFyzi$F|;mnvEluU4xJdIMca(v7`LDbJ<@E*G6u%|WZV zxmG_t>NNM-lM4fA19%Um43!%Z4XAJg`0F_W@YrN_ic3cqRWyywRQy(F>v4T{X&5?? zL=|B<5Yxay#$D)GtD%W|#jkZrvXKxrS^qMP$;Ijf@s28kD-+{6K?5QTG!9Zh&Eyo% zKIF7>F1JO4IY)-;Ye6c)0$4E(FgDs6OF%4^$*N9GPDSyxVq*$tiuhO#b{R0wzXA*Z XLY+8vR`f==00000NkvXXu0mjfwYI|U literal 0 HcmV?d00001 diff --git a/stackstorm-nexus3/nexus3.yaml.example b/stackstorm-nexus3/nexus3.yaml.example new file mode 100644 index 0000000..762ab48 --- /dev/null +++ b/stackstorm-nexus3/nexus3.yaml.example @@ -0,0 +1,12 @@ +--- +url: "http://localhost:8081" +user: "admin" +password: "admin123" +verify: True +default_profile: "dev" +profiles: + "dev": + url: "http://localhost:8081" + user: "dev-user" + password: "mypas" + verify: True \ No newline at end of file diff --git a/stackstorm-nexus3/pack.yaml b/stackstorm-nexus3/pack.yaml new file mode 100644 index 0000000..0ff4e68 --- /dev/null +++ b/stackstorm-nexus3/pack.yaml @@ -0,0 +1,13 @@ +--- +ref: nexus3 +name: Sontatype nexus3 +description: Sontatype nexus3 stackstorm pack +keywords: + - example + - test +version: 0.1.0 +python_versions: + - "2" + - "3" +author: Sonu K. Meena +email: sonu.meena@example.com diff --git a/stackstorm-nexus3/policies/retry_core_http_on_timeout.yaml b/stackstorm-nexus3/policies/retry_core_http_on_timeout.yaml new file mode 100644 index 0000000..47116d0 --- /dev/null +++ b/stackstorm-nexus3/policies/retry_core_http_on_timeout.yaml @@ -0,0 +1,10 @@ +--- +name: http.retry +description: Retry core.http action on timeout. +enabled: true +resource_ref: core.http +policy_type: action.retry +parameters: + retry_on: timeout + max_retry_count: 2 + delay: 2 diff --git a/stackstorm-nexus3/requirements.txt b/stackstorm-nexus3/requirements.txt new file mode 100644 index 0000000..21bde5b --- /dev/null +++ b/stackstorm-nexus3/requirements.txt @@ -0,0 +1,2 @@ +eventlet +nexus3-cli \ No newline at end of file diff --git a/stackstorm-nexus3/tests/Makefile b/stackstorm-nexus3/tests/Makefile new file mode 100644 index 0000000..20919ec --- /dev/null +++ b/stackstorm-nexus3/tests/Makefile @@ -0,0 +1,40 @@ + +ST2_EXEC_CMD = grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}"; + +run: list_repo create_repo get_repo del_repo get_repo list_scripts get_script run_script delete_script get_script + +list_repo: + echo "=================== List repository" + st2 action execute nexus3.list_repositories config_profile=dev | grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}"; + +create_repo: + echo "=================== Create repository" + st2 action execute nexus3.create_repositories config_profile=dev type=hosted name=maven2-dumy format=maven write_policy=ALLOW | $(ST2_EXEC_CMD) + +get_repo: + echo "=================== Get repository" + st2 action execute nexus3.get_repositories config_profile=dev name=maven2-dumy | $(ST2_EXEC_CMD) + +del_repo: + echo "=================== Delete repository" + st2 action execute nexus3.delete_repositories config_profile=dev name=maven2-dumy | $(ST2_EXEC_CMD) + +list_scripts: + echo "=================== List scripts" + st2 action execute nexus3.list_scripts config_profile=dev | $(ST2_EXEC_CMD) + +get_script: + echo "=================== Get script" + st2 action execute nexus3.get_scripts config_profile=dev name=nexus3-cli-repository-create | $(ST2_EXEC_CMD) + +run_script: + echo "=================== Run script" + st2 action execute nexus3.run_scripts config_profile=dev name=nexus3-cli-repository-create | $(ST2_EXEC_CMD) + +delete_script: + echo "=================== Delete script" + st2 action execute nexus3.delete_scripts config_profile=dev name=nexus3-cli-repository-create | $(ST2_EXEC_CMD) + +test: + st2-run-pack-tests -p ./ + diff --git a/stackstorm-nexus3/tests/fixtures/get_repositories.json b/stackstorm-nexus3/tests/fixtures/get_repositories.json new file mode 100644 index 0000000..e69de29 diff --git a/stackstorm-nexus3/tests/fixtures/list_repositories.json b/stackstorm-nexus3/tests/fixtures/list_repositories.json new file mode 100644 index 0000000..e69de29 diff --git a/stackstorm-nexus3/tests/test_run.py b/stackstorm-nexus3/tests/test_run.py new file mode 100644 index 0000000..474b449 --- /dev/null +++ b/stackstorm-nexus3/tests/test_run.py @@ -0,0 +1,12 @@ +from st2tests.base import BaseActionTestCase + +from run import ActionManager +from lib.exception import * + +class RunTestCase(BaseActionTestCase): + action_cls = ActionManager + + def test_run_required_params(self): + action = self.get_action_instance(config={'config_profile': 'dev'}) + #self.assertRaises(MissingParameterError,action.run) + \ No newline at end of file From dade6a2b8e215f0c3b9c0f863f7cfd8d243e0833 Mon Sep 17 00:00:00 2001 From: sonu kumar meena Date: Sat, 23 Feb 2019 20:04:17 +0530 Subject: [PATCH 35/45] added tests --- stackstorm-nexus3/README-test.md | 97 ------------------- stackstorm-nexus3/README.md | 30 ++++-- stackstorm-nexus3/actions/lib/base.py | 39 ++++---- stackstorm-nexus3/actions/run.py | 5 +- .../aliases/get_nexus_repository.yaml | 8 ++ stackstorm-nexus3/tests/Makefile | 21 +++- .../tests/fixtures/get_repositories.json | 6 ++ .../tests/fixtures/get_scripts.json | 76 +++++++++++++++ .../tests/fixtures/list_repositories.json | 44 +++++++++ .../tests/fixtures/list_scripts.json | 86 ++++++++++++++++ .../tests/nexus_base_test_case.py | 39 ++++++++ .../tests/test_resource_repositories.py | 92 ++++++++++++++++++ .../tests/test_resource_scripts.py | 92 ++++++++++++++++++ stackstorm-nexus3/tests/test_run.py | 43 +++++++- 14 files changed, 548 insertions(+), 130 deletions(-) delete mode 100644 stackstorm-nexus3/README-test.md create mode 100644 stackstorm-nexus3/aliases/get_nexus_repository.yaml create mode 100644 stackstorm-nexus3/tests/fixtures/get_scripts.json create mode 100644 stackstorm-nexus3/tests/fixtures/list_scripts.json create mode 100644 stackstorm-nexus3/tests/nexus_base_test_case.py create mode 100644 stackstorm-nexus3/tests/test_resource_repositories.py create mode 100644 stackstorm-nexus3/tests/test_resource_scripts.py diff --git a/stackstorm-nexus3/README-test.md b/stackstorm-nexus3/README-test.md deleted file mode 100644 index 47b8a59..0000000 --- a/stackstorm-nexus3/README-test.md +++ /dev/null @@ -1,97 +0,0 @@ -## Testing locally - - -Copy component files - - cp -rf actions/* /opt/stackstorm/packs/nexus3/actions/ - -If any *.yaml file is changed, run reload accordingly. - - st2ctl reload --register-configs - st2ctl reload --register-actions - st2ctl reload --register-rules - - -trigger Execution - - List Repository: - - ST2_ACTION_CMD='st2 action execute nexus3.list_repositories config_profile=dev' - - Create Repository - - ST2_ACTION_CMD='st2 action execute nexus3.create_repositories config_profile=dev type=hosted name=maven2-dumy format=maven write_policy=ALLOW' - - Get Repository - - ST2_ACTION_CMD='st2 action execute nexus3.get_repositories config_profile=dev name=maven2-dumy' - - Delete Repository - - ST2_ACTION_CMD='st2 action execute nexus3.delete_repositories config_profile=dev name=maven2-dumy' - - List Scripts: - - ST2_ACTION_CMD='st2 action execute nexus3.list_scripts config_profile=dev' - - Get scripts - - ST2_ACTION_CMD='st2 action execute nexus3.get_scripts config_profile=dev name=nexus3-cli-repository-create' - - Delete Scripts - - ST2_ACTION_CMD='st2 action execute nexus3.delete_scripts config_profile=dev name=nexus3-cli-repository-delete' - - Excecute it: - - $ST2_ACTION_CMD | grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}"; - - Running them continuously: - - while true; do mkdir -p /opt/stackstorm/packs/nexus3; cp -rf ./* /opt/stackstorm/packs/nexus3/; chmod -R --reference /opt/stackstorm/packs/linux /opt/stackstorm/packs/nexus3; chown -R --reference /opt/stackstorm/packs/linux/pack.yaml /opt/stackstorm/packs/nexus3/*; $ST2_ACTION_CMD | grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}" sleep 2; done; - - - -If any `yaml` file is updated , update it: - - #eg. updating action list_repositories.yaml - st2 action update nexus3.list_repositories ./actions/list_repositories.yaml - -Get executions - - st2 execution list -n 1 - - -``` json -{ - "success": true, - "data": { - "name": "dummy1", - "type": "hosted", - "format": "maven2", - "recipe": "maven2-hosted", - "online": true, - "attributes": { - "cleanup": { - "policyName": "None" - }, - "maven": { - "versionPolicy": "RELEASE", - "layoutPolicy": "STRICT" - }, - "storage": { - "strictContentTypeValidation": true, - "writePolicy": "ALLOW_ONCE", - "blobStoreName": "default" - } - }, - "url": "http://localhost:8081/repository/dummy1/", - "status": { - "repositoryName": "dummy1", - "online": true, - "description": null, - "reason": null - } - } -} -`` \ No newline at end of file diff --git a/stackstorm-nexus3/README.md b/stackstorm-nexus3/README.md index 404b01a..65a14a6 100644 --- a/stackstorm-nexus3/README.md +++ b/stackstorm-nexus3/README.md @@ -1,7 +1,6 @@ -# Stackstorm-Sontatype Nexus3 +# Stackstorm-Nexus3 - -Sontatype nexus3 stackstorm pack +[Sontatype nexus3](https://www.sonatype.com/nexus-repository-oss) stackstorm pack ## Installation @@ -20,7 +19,7 @@ add nexus3 server connection profile: * ``url`` - URL of the nexus3 server (e.g. ``http://localhost:8081``) * ``user`` - username * ``password`` - Password -* ``verify`` - https tls verify +* ``verify`` - https tls verify, only used if the `url` option specifies an `https` connection You can also add multiple profiles: @@ -54,6 +53,18 @@ profiles: ## Actions +While naming actions following convention is used: + +**< VERB >_< RESOURCE(plural) >** + + +Supported Resources + +- Repositories +- Scripts + +### Available actions: + * **list_repositories** : List nexus3 repositories * **get_repositories** : get nexus3 repositories * **create_repositories** : create nexus3 repository @@ -64,17 +75,24 @@ profiles: * **create_scripts** : create(& upload) if missing, groovy script * **delete_scripts** : delete nexus3 script +## Policies + +* **http.retry** : Retry core.http action on timeout. + ## Aliases +--NIL-- ## Rules +--NIL-- ## Sensors +--NIL-- -## Policies -* **http.retry** : Retry core.http action on timeout. +# Testing +While testing you can leverage [Makefile](./tests/Makefile) to ease writing and testing actions. Read the Makefile for the list of useful commands. \ No newline at end of file diff --git a/stackstorm-nexus3/actions/lib/base.py b/stackstorm-nexus3/actions/lib/base.py index 03d871a..4601031 100644 --- a/stackstorm-nexus3/actions/lib/base.py +++ b/stackstorm-nexus3/actions/lib/base.py @@ -1,10 +1,14 @@ +from st2common.runners.base_action import Action import sys -from exception import * +from exception import Error +from exception import MissingProfileError +from exception import ValidationFailError +from exception import NexusClientNotInstantiatedError from nexuscli.repository import Repository from nexuscli.nexus_client import NexusClient -from nexuscli.exception import * +from nexuscli.exception import NexusClientAPIError +from nexuscli.exception import NexusClientCreateRepositoryError -from st2common.runners.base_action import Action __all__ = [ 'BaseAction' @@ -18,24 +22,27 @@ class BaseAction(Action): def __init__(self, config): super(BaseAction, self).__init__(config) self.nexus_profiles = self.config.get('profiles', {}) - self.nexus_client = None + self._client = None self.dial_config = None def validate_config(self, c_profile): """ Validate connection configuration - + This function returns a tuple of (is_valid, errors), where errors is + a list of all of the missing fields in a profile. This is avoid + making users having to correct each missing field at a time. """ validation_errors = [] is_valid = True for field in REQUIRED_FIELDS: if c_profile.get(field, None) == None: - validation_errors.push("%s if missing" % field) + validation_errors.append( + "Required parameter %s is missing" % field) is_valid = False return (is_valid, validation_errors) def get_connection_defaults(self): - """ default properties + """ Default properties """ return { @@ -46,14 +53,11 @@ def get_connection_defaults(self): } def init_config(self, profile=None): - """ Get nexus3 server connection string + """ Generate connection config and validate it """ self.dial_config = self.get_connection_defaults() - if profile is not None: - profile = profile.strip() - if len(profile) == 0: - profile = None + profile = profile if profile and len(profile.strip()) > 0 else None # use 'default_profile' if 'config_profile' is empty if profile is None: @@ -81,21 +85,22 @@ def init_config(self, profile=None): def init_dialer(self): try: self.logger.debug("connection string: %s \n" % self.dial_config) - self.nexus_client = NexusClient(**self.dial_config) + self._client = NexusClient(**self.dial_config) except Exception as error: self.logger.error("Couldn't instantiate nexus client %s" % error) + raise error def get_resource_dialer(self, resource): - """ return nexus_client + """ return nexus client """ - if self.nexus_client is None: + if self._client is None: raise NexusClientNotInstantiatedError( "Instantiate nexus_client by calling init_dialer() method first") - return getattr(self.nexus_client, resource) + return getattr(self._client, resource) def intent_list(self, resource, **kwargs): - """ Intent: List + """ Intent: LIST """ dialer = self.get_resource_dialer(resource) diff --git a/stackstorm-nexus3/actions/run.py b/stackstorm-nexus3/actions/run.py index f583905..f4e00fd 100644 --- a/stackstorm-nexus3/actions/run.py +++ b/stackstorm-nexus3/actions/run.py @@ -1,9 +1,6 @@ import sys from lib import base from st2common.runners.base_action import Action -from nexuscli.repository import Repository -from nexuscli.nexus_client import NexusClient -from nexuscli.exception import * from lib.exception import * @@ -20,7 +17,7 @@ def run(self, **kwargs): # Resolve connection config self.init_config( - kwargs.pop('config_profile')) + kwargs.pop('config_profile', None)) # Instantiating dialer self.init_dialer() diff --git a/stackstorm-nexus3/aliases/get_nexus_repository.yaml b/stackstorm-nexus3/aliases/get_nexus_repository.yaml new file mode 100644 index 0000000..95b1261 --- /dev/null +++ b/stackstorm-nexus3/aliases/get_nexus_repository.yaml @@ -0,0 +1,8 @@ +--- +name: "nexus_get_repository" +pack: "nexus3" +action_ref: "nexus3.get_repositories" +description: "alias to nexus3.get_repositories" +formats: + - "get repository from {{name}}" + - "retrieve comments for {{issue_key}}" \ No newline at end of file diff --git a/stackstorm-nexus3/tests/Makefile b/stackstorm-nexus3/tests/Makefile index 20919ec..9afe0d2 100644 --- a/stackstorm-nexus3/tests/Makefile +++ b/stackstorm-nexus3/tests/Makefile @@ -1,7 +1,7 @@ ST2_EXEC_CMD = grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}"; -run: list_repo create_repo get_repo del_repo get_repo list_scripts get_script run_script delete_script get_script +run: sync list_repo create_repo get_repo del_repo get_repo list_scripts get_script run_script delete_script get_script test list_repo: echo "=================== List repository" @@ -35,6 +35,23 @@ delete_script: echo "=================== Delete script" st2 action execute nexus3.delete_scripts config_profile=dev name=nexus3-cli-repository-create | $(ST2_EXEC_CMD) +install: + echo "=================== Running st2 pack install" + st2 pack install file:///$$PWD + +reload: + echo "=================== Running st2ctl reload" + st2ctl reload --register-all + +sync: + LOCAL_NEXUS_DIR=$$PWD; \ + ST2_PACK_DIR='/opt/stackstorm/packs'; \ + mkdir -p /opt/stackstorm/packs/nexus3; \ + cp -rf $$LOCAL_NEXUS_DIR/* $$ST2_PACK_DIR/nexus3/; \ + chmod -R --reference $$ST2_PACK_DIR/linux $$ST2_PACK_DIR/nexus3;\ + chown -R --reference $$ST2_PACK_DIR/linux/pack.yaml $$ST2_PACK_DIR/nexus3/*; + + test: - st2-run-pack-tests -p ./ + st2-run-pack-tests -cjtp ./ diff --git a/stackstorm-nexus3/tests/fixtures/get_repositories.json b/stackstorm-nexus3/tests/fixtures/get_repositories.json index e69de29..06a6c6b 100644 --- a/stackstorm-nexus3/tests/fixtures/get_repositories.json +++ b/stackstorm-nexus3/tests/fixtures/get_repositories.json @@ -0,0 +1,6 @@ +{ + "url": "http://nexus:8081/repository/maven2-dumy", + "type": "hosted", + "name": "maven2-repo", + "format": "maven2" +} \ No newline at end of file diff --git a/stackstorm-nexus3/tests/fixtures/get_scripts.json b/stackstorm-nexus3/tests/fixtures/get_scripts.json new file mode 100644 index 0000000..a5af882 --- /dev/null +++ b/stackstorm-nexus3/tests/fixtures/get_scripts.json @@ -0,0 +1,76 @@ +{ + "content": " + import groovy.json.JsonSlurper + import org.sonatype.nexus.blobstore.api.BlobStoreManager + import org.sonatype.nexus.repository.config.Configuration + import org.sonatype.nexus.repository.storage.WritePolicy + + class Repository { + Map> properties = new HashMap() + } + + if (args != \"\") { + log.info(\"Creating repository with args [${args}]\") + def rep = convertJsonFileToRepo(args) + def output = createRepository(rep) + + return output + } + + def createRepository(Repository repo) { + def conf = createConfiguration(repo) + + try { + repository.createRepository(conf) + } + catch (Exception e){ + return e + } + + return null + } + + def convertJsonFileToRepo(String jsonData) { + def inputJson = new JsonSlurper().parseText(jsonData) + Repository repo = new Repository() + inputJson.each { + repo.properties.put(it.key, it.value) + } + + return repo + } + + def createConfiguration(Repository repo){ + def name = getName(repo) + def recipeName = getRecipeName(repo) + def online = getOnline(repo) + def attributes = repo.properties.get(\"attributes\") + + Configuration conf = new Configuration( + repositoryName: name, + recipeName: recipeName, + online: online, + attributes: attributes + ) + + return conf + } + + def getName(Repository repo){ + String name = repo.getProperties().get(\"name\") + return name + } + + def getRecipeName(Repository repo){ + String recipeName = repo.getProperties().get(\"recipeName\") + return recipeName + } + + def getOnline(Repository repo){ + String online = repo.getProperties().get(\"online\") + return online + } + ", + "type": "groovy", + "name": "nexus3-cli-repository-create" + } \ No newline at end of file diff --git a/stackstorm-nexus3/tests/fixtures/list_repositories.json b/stackstorm-nexus3/tests/fixtures/list_repositories.json index e69de29..af18145 100644 --- a/stackstorm-nexus3/tests/fixtures/list_repositories.json +++ b/stackstorm-nexus3/tests/fixtures/list_repositories.json @@ -0,0 +1,44 @@ +[ + { + "url": "http://nexus:8081/repository/nuget-group", + "type": "group", + "name": "nuget-group", + "format": "nuget" + }, + { + "url": "http://nexus:8081/repository/maven-snapshots", + "type": "hosted", + "name": "maven-snapshots", + "format": "maven2" + }, + { + "url": "http://nexus:8081/repository/maven-central", + "type": "proxy", + "name": "maven-central", + "format": "maven2" + }, + { + "url": "http://nexus:8081/repository/nuget.org-proxy", + "type": "proxy", + "name": "nuget.org-proxy", + "format": "nuget" + }, + { + "url": "http://nexus:8081/repository/maven-releases", + "type": "hosted", + "name": "maven-releases", + "format": "maven2" + }, + { + "url": "http://nexus:8081/repository/nuget-hosted", + "type": "hosted", + "name": "nuget-hosted", + "format": "nuget" + }, + { + "url": "http://nexus:8081/repository/maven-public", + "type": "group", + "name": "maven-public", + "format": "maven2" + } + ] \ No newline at end of file diff --git a/stackstorm-nexus3/tests/fixtures/list_scripts.json b/stackstorm-nexus3/tests/fixtures/list_scripts.json new file mode 100644 index 0000000..0964fa9 --- /dev/null +++ b/stackstorm-nexus3/tests/fixtures/list_scripts.json @@ -0,0 +1,86 @@ +[ + { + "content": """ + log.info(\"Deleting repository[${args}]\") + repository.repositoryManager.delete(args) + """, + "type": "groovy", + "name": "nexus3-cli-repository-delete" + }, + { + "content": """ + import groovy.json.JsonSlurper + import org.sonatype.nexus.blobstore.api.BlobStoreManager + import org.sonatype.nexus.repository.config.Configuration + import org.sonatype.nexus.repository.storage.WritePolicy + + class Repository { + Map < String, Map < String, Object >> properties = new HashMap < String, Object > () + } + + if (args != \"\") { + log.info(\"Creating repository with args[${args}]\") + def rep= convertJsonFileToRepo(args) + def output= createRepository(rep) + + return output + } + + def createRepository(Repository repo) { + def conf = createConfiguration(repo) + + try { + repository.createRepository(conf) + } + catch(Exception e){ + return e + } + + return null + } + + def convertJsonFileToRepo(String jsonData) { + def inputJson = new JsonSlurper().parseText(jsonData) + Repository repo= new Repository() + inputJson.each { + repo.properties.put(it.key, it.value) + } + + return repo + } + + def createConfiguration(Repository repo){ + def name = getName(repo) + def recipeName= getRecipeName(repo) + def online= getOnline(repo) + def attributes= repo.properties.get(\"attributes\") + + Configuration conf= new Configuration( + repositoryName: name, + recipeName: recipeName, + online: online, + attributes: attributes + ) + + return conf + } + + def getName(Repository repo){ + String name = repo.getProperties().get(\"name\") + return name + } + + def getRecipeName(Repository repo){ + String recipeName = repo.getProperties().get(\"recipeName\") + return recipeName + } + + def getOnline(Repository repo){ + String online = repo.getProperties().get(\"online\") + return online + } + """, + "type": "groovy", + "name": "nexus3-cli-repository-create" + } +] diff --git a/stackstorm-nexus3/tests/nexus_base_test_case.py b/stackstorm-nexus3/tests/nexus_base_test_case.py new file mode 100644 index 0000000..690b29d --- /dev/null +++ b/stackstorm-nexus3/tests/nexus_base_test_case.py @@ -0,0 +1,39 @@ +from st2tests.base import BaseActionTestCase +import json + +__all__ = [ + 'NexusBaseTestCase' +] + + +class NexusBaseTestCase(BaseActionTestCase): + __test__ = False + action_cls = None + + def setUp(self): + super(NexusBaseTestCase, self).setUp() + + self._configs = { + "action_config": { + "config_profile": None + }, + "pack_config": { + "url": "http://localhost:8081", + "user": "user", + "password": "supersecret" + } + } + + def get_action_config(self, action_name): + self._configs["action_config"]["action"] = action_name + + if action_name in ["get_repositories", "delete_repositories", "get_scripts", "delete_scripts"]: + self._configs["action_config"]["name"] = "maven2-repo" + elif action_name == "create_repositories": + self._configs["action_config"].update(json.loads( + self.get_fixture_content('get_repositories.json'))) + + return self._configs["action_config"] + + def get_pack_config(self): + return self._configs['pack_config'] diff --git a/stackstorm-nexus3/tests/test_resource_repositories.py b/stackstorm-nexus3/tests/test_resource_repositories.py new file mode 100644 index 0000000..5bd7fb8 --- /dev/null +++ b/stackstorm-nexus3/tests/test_resource_repositories.py @@ -0,0 +1,92 @@ +from st2tests.base import BaseActionTestCase + +from run import ActionManager +from lib.exception import * +from lib.base import BaseAction +import mock +import json +from nexus_base_test_case import NexusBaseTestCase + +@mock.patch('lib.base.NexusClient' ) +class ResourceRepositoriesTest(NexusBaseTestCase): + action_cls = ActionManager + __test__ = True + + def test_action_list_repositories(self, mock_nexus): + """ (A)List Repositories: Should fetch an array of repositories + """ + + action_config = self.get_action_config("list_repositories") + pack_config = self._configs["pack_config"] + repo_list_fixture = json.loads(self.get_fixture_content('list_repositories.json')) + + mock_client = mock_nexus.return_value + mock_client.repositories.raw_list.return_value = repo_list_fixture + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.repositories.raw_list.assert_called_once() + self.assertEqual(response, repo_list_fixture) + + def test_action_get_repositories(self, mock_nexus): + """ (A)Get Repositories: Should fetch a repository identified by a name + """ + + action_config = self.get_action_config("get_repositories") + pack_config = self._configs["pack_config"] + repository_fixture = json.loads(self.get_fixture_content('get_repositories.json')) + + def mock_get_raw_by_name(name): + return repository_fixture + + mock_client = mock_nexus.return_value + mock_client.repositories.get_raw_by_name = mock.Mock(side_effect=mock_get_raw_by_name) + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.repositories.get_raw_by_name.assert_called_once() + self.assertEqual((is_success, response), (True, repository_fixture)) + + + def test_action_create_repositories(self, mock_nexus): + """ (A)Create Repositories: Should create a repository + """ + + action_config = self.get_action_config("create_repositories") + pack_config = self._configs["pack_config"] + + def mock_create(payload): + return None + + mock_client = mock_nexus.return_value + mock_client.repositories.create = mock.Mock(side_effect=mock_create) + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.repositories.create.assert_called_once() + self.assertEqual((is_success, response), (True, None)) + + + def test_action_delete_repositories(self, mock_nexus): + """ (A)Delete Repositories: Should delete a repository + """ + + action_config = self.get_action_config("delete_repositories") + pack_config = self._configs["pack_config"] + + def mock_delete(name): + return None + + mock_client = mock_nexus.return_value + mock_client.repositories.delete = mock.Mock(side_effect=mock_delete) + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.repositories.delete.assert_called_once() + self.assertEqual((is_success, response), (True, None)) + + \ No newline at end of file diff --git a/stackstorm-nexus3/tests/test_resource_scripts.py b/stackstorm-nexus3/tests/test_resource_scripts.py new file mode 100644 index 0000000..852d3b6 --- /dev/null +++ b/stackstorm-nexus3/tests/test_resource_scripts.py @@ -0,0 +1,92 @@ +from st2tests.base import BaseActionTestCase + +from run import ActionManager +from lib.exception import * +from lib.base import BaseAction +import mock +import json +from nexus_base_test_case import NexusBaseTestCase + +@mock.patch('lib.base.NexusClient' ) +class ResourceScriptsTest(NexusBaseTestCase): + action_cls = ActionManager + __test__ = True + + def test_action_list_scripts(self, mock_nexus): + """ (A)List scripts: Should fetch an array of scripts + """ + + action_config = self.get_action_config("list_scripts") + pack_config = self._configs["pack_config"] + script_list_fixture = self.get_fixture_content('list_scripts.json') + + mock_client = mock_nexus.return_value + mock_client.scripts.list.return_value = script_list_fixture + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.scripts.list.assert_called_once() + self.assertEqual(response, script_list_fixture) + + def test_action_get_scripts(self, mock_nexus): + """ (A)Get scripts: Should fetch a script identified by name + """ + + action_config = self.get_action_config("get_scripts") + pack_config = self._configs["pack_config"] + script_fixture = self.get_fixture_content('get_scripts.json') + + def mock_get(name): + return script_fixture + + mock_client = mock_nexus.return_value + mock_client.scripts.get = mock.Mock(side_effect=mock_get) + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.scripts.get.assert_called_once() + self.assertEqual((is_success, response), (True, script_fixture)) + + + def test_action_create_scripts(self, mock_nexus): + """ (A)Create scripts: Should create a script + """ + + action_config = self.get_action_config("create_scripts") + pack_config = self._configs["pack_config"] + + def mock_create_if_missing(payload): + return None + + mock_client = mock_nexus.return_value + mock_client.scripts.create_if_missing = mock.Mock(side_effect=mock_create_if_missing) + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.scripts.create_if_missing.assert_called_once() + self.assertEqual((is_success, response), (True, None)) + + + def test_action_delete_scripts(self, mock_nexus): + """ (A)delete scripts: Should delete a script + """ + + action_config = self.get_action_config("delete_scripts") + pack_config = self._configs["pack_config"] + + def mock_delete(name): + return None + + mock_client = mock_nexus.return_value + mock_client.scripts.delete = mock.Mock(side_effect=mock_delete) + + action = self.get_action_instance(pack_config) + (is_success, response) = action.run(**action_config) + + mock_client.scripts.delete.assert_called_once() + self.assertEqual((is_success, response), (True, None)) + + \ No newline at end of file diff --git a/stackstorm-nexus3/tests/test_run.py b/stackstorm-nexus3/tests/test_run.py index 474b449..ccaf544 100644 --- a/stackstorm-nexus3/tests/test_run.py +++ b/stackstorm-nexus3/tests/test_run.py @@ -3,10 +3,45 @@ from run import ActionManager from lib.exception import * + class RunTestCase(BaseActionTestCase): action_cls = ActionManager - def test_run_required_params(self): - action = self.get_action_instance(config={'config_profile': 'dev'}) - #self.assertRaises(MissingParameterError,action.run) - \ No newline at end of file + def test_configuration(self): + """ This tests action and pack configuration + """ + configs = { + "action_config": { + "config_profile": None + }, + "pack_config": {} + } + # Action should have required 'action' parameter + action = self.get_action_instance(config=configs["pack_config"]) + with self.assertRaises(MissingParameterError): + action.run(**configs["action_config"]) + + # Profile should exist, if defined in action + configs = { + "action_config": { + "action": "some_action", + "url": "http://localhost:8080", + "config_profile": "dev" + }, + "pack_config": {} + } + action = self.get_action_instance(config=configs["pack_config"]) + with self.assertRaises(MissingProfileError): + action.run(**configs["action_config"]) + + # Required connection parameters should exist: url, user, password + configs = { + "action_config": { + "action": "some_action", + "url": "http://localhost:8080" + }, + "pack_config": {} + } + action = self.get_action_instance(config=configs["pack_config"]) + with self.assertRaises(ValidationFailError): + action.run(**configs["action_config"]) From c7557afd84b39325a6001243d17baf4b58b0e7d6 Mon Sep 17 00:00:00 2001 From: sonu kumar meena Date: Sat, 23 Feb 2019 21:00:49 +0530 Subject: [PATCH 36/45] flake8 passed added more tests --- stackstorm-nexus3/.gitignore | 3 +++ stackstorm-nexus3/README.md | 14 +++++++++- stackstorm-nexus3/actions/lib/base.py | 16 +++++------ stackstorm-nexus3/actions/lib/exception.py | 5 ++++ stackstorm-nexus3/actions/run.py | 21 ++++++++++----- stackstorm-nexus3/tests/Makefile | 4 +++ .../tests/nexus_base_test_case.py | 3 ++- .../tests/test_resource_repositories.py | 24 +++++++---------- .../tests/test_resource_scripts.py | 19 +++++-------- .../tests/test_resource_unsupported.py | 27 +++++++++++++++++++ stackstorm-nexus3/tests/test_run.py | 4 ++- 11 files changed, 96 insertions(+), 44 deletions(-) create mode 100644 stackstorm-nexus3/tests/test_resource_unsupported.py diff --git a/stackstorm-nexus3/.gitignore b/stackstorm-nexus3/.gitignore index bf2c63a..0f363e1 100644 --- a/stackstorm-nexus3/.gitignore +++ b/stackstorm-nexus3/.gitignore @@ -1,3 +1,6 @@ +#visual studio +.vscode + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/stackstorm-nexus3/README.md b/stackstorm-nexus3/README.md index 65a14a6..80a3cff 100644 --- a/stackstorm-nexus3/README.md +++ b/stackstorm-nexus3/README.md @@ -95,4 +95,16 @@ Supported Resources # Testing -While testing you can leverage [Makefile](./tests/Makefile) to ease writing and testing actions. Read the Makefile for the list of useful commands. \ No newline at end of file +While testing you can leverage [Makefile](./tests/Makefile) to ease writing and testing actions. Read the Makefile for the list of useful commands. + + +# Contributing + +Before submitting make sure python linter is happy with your changes first + +``` +pip install flake8 + +#executing flake8 ./ +make -f tests/Makefile lint +``` \ No newline at end of file diff --git a/stackstorm-nexus3/actions/lib/base.py b/stackstorm-nexus3/actions/lib/base.py index 4601031..1e3b583 100644 --- a/stackstorm-nexus3/actions/lib/base.py +++ b/stackstorm-nexus3/actions/lib/base.py @@ -1,6 +1,4 @@ from st2common.runners.base_action import Action -import sys -from exception import Error from exception import MissingProfileError from exception import ValidationFailError from exception import NexusClientNotInstantiatedError @@ -34,7 +32,7 @@ def validate_config(self, c_profile): validation_errors = [] is_valid = True for field in REQUIRED_FIELDS: - if c_profile.get(field, None) == None: + if c_profile.get(field) is None: validation_errors.append( "Required parameter %s is missing" % field) is_valid = False @@ -63,7 +61,8 @@ def init_config(self, profile=None): if profile is None: profile = self.config.get('default_profile', None) - # Use defaults options, if neither config_profile nor default_profile is provided + # Use defaults options, if neither config_profile nor default_profile + # is provided if profile is None: self.logger.info("using defaults connection values") else: @@ -96,7 +95,8 @@ def get_resource_dialer(self, resource): """ if self._client is None: raise NexusClientNotInstantiatedError( - "Instantiate nexus_client by calling init_dialer() method first") + "Instantiate nexus_client by calling \ + init_dialer() method first") return getattr(self._client, resource) def intent_list(self, resource, **kwargs): @@ -146,8 +146,7 @@ def intent_create(self, resource, **kwargs): else: response = dialer.create(payload) except NexusClientCreateRepositoryError as error: - response = "Failed to create %s. Most likely reason, same name resource already exist." % ( - resource) + response = "Failed to create %s. Reason: %s" % (resource, error) is_success = False return (is_success, response) @@ -163,7 +162,8 @@ def intent_run(self, resource, **kwargs): response = dialer.run(kwargs.pop('name'), kwargs.pop('data')) else: is_success = False - response = "Invalid resource: %s(supported only scripts)" % resource + response = "Invalid resource: %s\ + (supported only scripts)" % resource return (is_success, response) diff --git a/stackstorm-nexus3/actions/lib/exception.py b/stackstorm-nexus3/actions/lib/exception.py index 2cae8b5..9185b34 100644 --- a/stackstorm-nexus3/actions/lib/exception.py +++ b/stackstorm-nexus3/actions/lib/exception.py @@ -33,6 +33,11 @@ class ValidationFailError(Error): pass +class UnsupportedActionOrResourceError(Error): + """Raised when resource or action is unsupported""" + pass + + class NexusClientNotInstantiatedError(Error): """Raised when nexus_client is not instantiated""" pass diff --git a/stackstorm-nexus3/actions/run.py b/stackstorm-nexus3/actions/run.py index f4e00fd..7ad8bd1 100644 --- a/stackstorm-nexus3/actions/run.py +++ b/stackstorm-nexus3/actions/run.py @@ -1,7 +1,6 @@ -import sys from lib import base -from st2common.runners.base_action import Action -from lib.exception import * +from lib.exception import MissingParameterError +from lib.exception import UnsupportedActionOrResourceError class ActionManager(base.BaseAction): @@ -23,9 +22,19 @@ def run(self, **kwargs): self.init_dialer() # Serve Request - [intent, resource] = requested_action.split('_') + try: + [intent, resource] = requested_action.split('_') + except ValueError: + raise UnsupportedActionOrResourceError( + "Requested action: '%s' \ + is not supported currently" % requested_action) intent_method_name = "intent_%s" % intent - (is_success, response) = getattr( - self, intent_method_name)(resource, **kwargs) + try: + (is_success, response) = getattr( + self, intent_method_name)(resource, **kwargs) + except AttributeError: + raise UnsupportedActionOrResourceError( + "Requested action: '%s' \ + is not supported currently" % (requested_action)) return (is_success, response) diff --git a/stackstorm-nexus3/tests/Makefile b/stackstorm-nexus3/tests/Makefile index 9afe0d2..782c9c8 100644 --- a/stackstorm-nexus3/tests/Makefile +++ b/stackstorm-nexus3/tests/Makefile @@ -52,6 +52,10 @@ sync: chown -R --reference $$ST2_PACK_DIR/linux/pack.yaml $$ST2_PACK_DIR/nexus3/*; +lint: + flake8 ./ + + test: st2-run-pack-tests -cjtp ./ diff --git a/stackstorm-nexus3/tests/nexus_base_test_case.py b/stackstorm-nexus3/tests/nexus_base_test_case.py index 690b29d..ffb235b 100644 --- a/stackstorm-nexus3/tests/nexus_base_test_case.py +++ b/stackstorm-nexus3/tests/nexus_base_test_case.py @@ -27,7 +27,8 @@ def setUp(self): def get_action_config(self, action_name): self._configs["action_config"]["action"] = action_name - if action_name in ["get_repositories", "delete_repositories", "get_scripts", "delete_scripts"]: + if action_name in ["get_repositories", "delete_repositories", + "get_scripts", "delete_scripts"]: self._configs["action_config"]["name"] = "maven2-repo" elif action_name == "create_repositories": self._configs["action_config"].update(json.loads( diff --git a/stackstorm-nexus3/tests/test_resource_repositories.py b/stackstorm-nexus3/tests/test_resource_repositories.py index 5bd7fb8..e0a2e53 100644 --- a/stackstorm-nexus3/tests/test_resource_repositories.py +++ b/stackstorm-nexus3/tests/test_resource_repositories.py @@ -1,31 +1,29 @@ -from st2tests.base import BaseActionTestCase - from run import ActionManager -from lib.exception import * -from lib.base import BaseAction import mock import json from nexus_base_test_case import NexusBaseTestCase -@mock.patch('lib.base.NexusClient' ) + +@mock.patch('lib.base.NexusClient') class ResourceRepositoriesTest(NexusBaseTestCase): action_cls = ActionManager __test__ = True - + def test_action_list_repositories(self, mock_nexus): """ (A)List Repositories: Should fetch an array of repositories """ action_config = self.get_action_config("list_repositories") pack_config = self._configs["pack_config"] - repo_list_fixture = json.loads(self.get_fixture_content('list_repositories.json')) + repo_list_fixture = json.loads( + self.get_fixture_content('list_repositories.json')) mock_client = mock_nexus.return_value mock_client.repositories.raw_list.return_value = repo_list_fixture action = self.get_action_instance(pack_config) (is_success, response) = action.run(**action_config) - + mock_client.repositories.raw_list.assert_called_once() self.assertEqual(response, repo_list_fixture) @@ -35,20 +33,21 @@ def test_action_get_repositories(self, mock_nexus): action_config = self.get_action_config("get_repositories") pack_config = self._configs["pack_config"] - repository_fixture = json.loads(self.get_fixture_content('get_repositories.json')) + repository_fixture = json.loads( + self.get_fixture_content('get_repositories.json')) def mock_get_raw_by_name(name): return repository_fixture mock_client = mock_nexus.return_value - mock_client.repositories.get_raw_by_name = mock.Mock(side_effect=mock_get_raw_by_name) + mock_client.repositories.get_raw_by_name = mock.Mock( + side_effect=mock_get_raw_by_name) action = self.get_action_instance(pack_config) (is_success, response) = action.run(**action_config) mock_client.repositories.get_raw_by_name.assert_called_once() self.assertEqual((is_success, response), (True, repository_fixture)) - def test_action_create_repositories(self, mock_nexus): """ (A)Create Repositories: Should create a repository @@ -69,7 +68,6 @@ def mock_create(payload): mock_client.repositories.create.assert_called_once() self.assertEqual((is_success, response), (True, None)) - def test_action_delete_repositories(self, mock_nexus): """ (A)Delete Repositories: Should delete a repository """ @@ -88,5 +86,3 @@ def mock_delete(name): mock_client.repositories.delete.assert_called_once() self.assertEqual((is_success, response), (True, None)) - - \ No newline at end of file diff --git a/stackstorm-nexus3/tests/test_resource_scripts.py b/stackstorm-nexus3/tests/test_resource_scripts.py index 852d3b6..c822ff7 100644 --- a/stackstorm-nexus3/tests/test_resource_scripts.py +++ b/stackstorm-nexus3/tests/test_resource_scripts.py @@ -1,17 +1,13 @@ -from st2tests.base import BaseActionTestCase - from run import ActionManager -from lib.exception import * -from lib.base import BaseAction import mock -import json from nexus_base_test_case import NexusBaseTestCase -@mock.patch('lib.base.NexusClient' ) + +@mock.patch('lib.base.NexusClient') class ResourceScriptsTest(NexusBaseTestCase): action_cls = ActionManager __test__ = True - + def test_action_list_scripts(self, mock_nexus): """ (A)List scripts: Should fetch an array of scripts """ @@ -25,7 +21,7 @@ def test_action_list_scripts(self, mock_nexus): action = self.get_action_instance(pack_config) (is_success, response) = action.run(**action_config) - + mock_client.scripts.list.assert_called_once() self.assertEqual(response, script_list_fixture) @@ -48,7 +44,6 @@ def mock_get(name): mock_client.scripts.get.assert_called_once() self.assertEqual((is_success, response), (True, script_fixture)) - def test_action_create_scripts(self, mock_nexus): """ (A)Create scripts: Should create a script @@ -61,7 +56,8 @@ def mock_create_if_missing(payload): return None mock_client = mock_nexus.return_value - mock_client.scripts.create_if_missing = mock.Mock(side_effect=mock_create_if_missing) + mock_client.scripts.create_if_missing = mock.Mock( + side_effect=mock_create_if_missing) action = self.get_action_instance(pack_config) (is_success, response) = action.run(**action_config) @@ -69,7 +65,6 @@ def mock_create_if_missing(payload): mock_client.scripts.create_if_missing.assert_called_once() self.assertEqual((is_success, response), (True, None)) - def test_action_delete_scripts(self, mock_nexus): """ (A)delete scripts: Should delete a script """ @@ -88,5 +83,3 @@ def mock_delete(name): mock_client.scripts.delete.assert_called_once() self.assertEqual((is_success, response), (True, None)) - - \ No newline at end of file diff --git a/stackstorm-nexus3/tests/test_resource_unsupported.py b/stackstorm-nexus3/tests/test_resource_unsupported.py new file mode 100644 index 0000000..6efeafc --- /dev/null +++ b/stackstorm-nexus3/tests/test_resource_unsupported.py @@ -0,0 +1,27 @@ +from run import ActionManager +import mock +from nexus_base_test_case import NexusBaseTestCase +from lib.exception import UnsupportedActionOrResourceError + + +@mock.patch('lib.base.NexusClient') +class ResourceUnsupportedTest(NexusBaseTestCase): + action_cls = ActionManager + __test__ = True + + def test_unsupported_resource(self, mock_nexus): + """ Resource Or Action unsupported: Should raise exception + """ + + action_config = self.get_action_config("unsupported_resource") + pack_config = self._configs["pack_config"] + + # aciton name in right format but still unsupported + action = self.get_action_instance(pack_config) + with self.assertRaises(UnsupportedActionOrResourceError): + action.run(**action_config) + + # action name in invalid format + action_config = self.get_action_config("unsupported") + with self.assertRaises(UnsupportedActionOrResourceError): + action.run(**action_config) diff --git a/stackstorm-nexus3/tests/test_run.py b/stackstorm-nexus3/tests/test_run.py index ccaf544..b909b5e 100644 --- a/stackstorm-nexus3/tests/test_run.py +++ b/stackstorm-nexus3/tests/test_run.py @@ -1,7 +1,9 @@ from st2tests.base import BaseActionTestCase from run import ActionManager -from lib.exception import * +from lib.exception import MissingParameterError +from lib.exception import MissingProfileError +from lib.exception import ValidationFailError class RunTestCase(BaseActionTestCase): From f78a139dc59eb4c4f566936b884f7548be07fb37 Mon Sep 17 00:00:00 2001 From: sonu kumar meena Date: Sat, 23 Feb 2019 21:05:32 +0530 Subject: [PATCH 37/45] removed extra space --- stackstorm-nexus3/actions/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stackstorm-nexus3/actions/run.py b/stackstorm-nexus3/actions/run.py index 7ad8bd1..9bce1ee 100644 --- a/stackstorm-nexus3/actions/run.py +++ b/stackstorm-nexus3/actions/run.py @@ -31,7 +31,7 @@ def run(self, **kwargs): intent_method_name = "intent_%s" % intent try: (is_success, response) = getattr( - self, intent_method_name)(resource, **kwargs) + self, intent_method_name)(resource, **kwargs) except AttributeError: raise UnsupportedActionOrResourceError( "Requested action: '%s' \ From bff80d2f66a9f1a58b5446fe629bb637cff6e3de Mon Sep 17 00:00:00 2001 From: sonu kumar meena Date: Sat, 23 Feb 2019 21:16:11 +0530 Subject: [PATCH 38/45] fixed json files --- stackstorm-nexus3/tests/Makefile | 2 + .../tests/fixtures/get_scripts.json | 73 +---------------- .../tests/fixtures/list_scripts.json | 80 +------------------ 3 files changed, 6 insertions(+), 149 deletions(-) diff --git a/stackstorm-nexus3/tests/Makefile b/stackstorm-nexus3/tests/Makefile index 782c9c8..fd89c35 100644 --- a/stackstorm-nexus3/tests/Makefile +++ b/stackstorm-nexus3/tests/Makefile @@ -55,6 +55,8 @@ sync: lint: flake8 ./ +validate: + st2-check-validate-yaml-file ./*.yaml test: st2-run-pack-tests -cjtp ./ diff --git a/stackstorm-nexus3/tests/fixtures/get_scripts.json b/stackstorm-nexus3/tests/fixtures/get_scripts.json index a5af882..cab6ce5 100644 --- a/stackstorm-nexus3/tests/fixtures/get_scripts.json +++ b/stackstorm-nexus3/tests/fixtures/get_scripts.json @@ -1,76 +1,5 @@ { - "content": " - import groovy.json.JsonSlurper - import org.sonatype.nexus.blobstore.api.BlobStoreManager - import org.sonatype.nexus.repository.config.Configuration - import org.sonatype.nexus.repository.storage.WritePolicy - - class Repository { - Map> properties = new HashMap() - } - - if (args != \"\") { - log.info(\"Creating repository with args [${args}]\") - def rep = convertJsonFileToRepo(args) - def output = createRepository(rep) - - return output - } - - def createRepository(Repository repo) { - def conf = createConfiguration(repo) - - try { - repository.createRepository(conf) - } - catch (Exception e){ - return e - } - - return null - } - - def convertJsonFileToRepo(String jsonData) { - def inputJson = new JsonSlurper().parseText(jsonData) - Repository repo = new Repository() - inputJson.each { - repo.properties.put(it.key, it.value) - } - - return repo - } - - def createConfiguration(Repository repo){ - def name = getName(repo) - def recipeName = getRecipeName(repo) - def online = getOnline(repo) - def attributes = repo.properties.get(\"attributes\") - - Configuration conf = new Configuration( - repositoryName: name, - recipeName: recipeName, - online: online, - attributes: attributes - ) - - return conf - } - - def getName(Repository repo){ - String name = repo.getProperties().get(\"name\") - return name - } - - def getRecipeName(Repository repo){ - String recipeName = repo.getProperties().get(\"recipeName\") - return recipeName - } - - def getOnline(Repository repo){ - String online = repo.getProperties().get(\"online\") - return online - } - ", + "content": "import groovy.json.JsonSlurper...xxx", "type": "groovy", "name": "nexus3-cli-repository-create" } \ No newline at end of file diff --git a/stackstorm-nexus3/tests/fixtures/list_scripts.json b/stackstorm-nexus3/tests/fixtures/list_scripts.json index 0964fa9..b4d7c02 100644 --- a/stackstorm-nexus3/tests/fixtures/list_scripts.json +++ b/stackstorm-nexus3/tests/fixtures/list_scripts.json @@ -1,86 +1,12 @@ [ { - "content": """ - log.info(\"Deleting repository[${args}]\") - repository.repositoryManager.delete(args) - """, + "content": "xxxx", "type": "groovy", "name": "nexus3-cli-repository-delete" }, { - "content": """ - import groovy.json.JsonSlurper - import org.sonatype.nexus.blobstore.api.BlobStoreManager - import org.sonatype.nexus.repository.config.Configuration - import org.sonatype.nexus.repository.storage.WritePolicy - - class Repository { - Map < String, Map < String, Object >> properties = new HashMap < String, Object > () - } - - if (args != \"\") { - log.info(\"Creating repository with args[${args}]\") - def rep= convertJsonFileToRepo(args) - def output= createRepository(rep) - - return output - } - - def createRepository(Repository repo) { - def conf = createConfiguration(repo) - - try { - repository.createRepository(conf) - } - catch(Exception e){ - return e - } - - return null - } - - def convertJsonFileToRepo(String jsonData) { - def inputJson = new JsonSlurper().parseText(jsonData) - Repository repo= new Repository() - inputJson.each { - repo.properties.put(it.key, it.value) - } - - return repo - } - - def createConfiguration(Repository repo){ - def name = getName(repo) - def recipeName= getRecipeName(repo) - def online= getOnline(repo) - def attributes= repo.properties.get(\"attributes\") - - Configuration conf= new Configuration( - repositoryName: name, - recipeName: recipeName, - online: online, - attributes: attributes - ) - - return conf - } - - def getName(Repository repo){ - String name = repo.getProperties().get(\"name\") - return name - } - - def getRecipeName(Repository repo){ - String recipeName = repo.getProperties().get(\"recipeName\") - return recipeName - } - - def getOnline(Repository repo){ - String online = repo.getProperties().get(\"online\") - return online - } - """, + "content": "import groovy.json.JsonSlurper...xxxx", "type": "groovy", "name": "nexus3-cli-repository-create" } -] +] \ No newline at end of file From a593d5e105acdf7d722ff71c24b835b8a2c5646e Mon Sep 17 00:00:00 2001 From: sonu kumar meena Date: Sat, 23 Feb 2019 21:30:41 +0530 Subject: [PATCH 39/45] removed yaml shorthand --- stackstorm-nexus3/config.schema.yaml | 65 ++++++++++++++++++---------- stackstorm-nexus3/tests/Makefile | 4 ++ 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/stackstorm-nexus3/config.schema.yaml b/stackstorm-nexus3/config.schema.yaml index 4f5b400..ed83692 100644 --- a/stackstorm-nexus3/config.schema.yaml +++ b/stackstorm-nexus3/config.schema.yaml @@ -1,26 +1,29 @@ --- -<<: &profile_options - url: - description: "URL of the JIRA instance (e.g. ``https://myproject.atlassian.net``)" - type: "string" - secret: false - required: true - verify: - description: "Verify SSL certificate. Set to False to disable verification. Default True" - type: boolean - default: True - user: - description: "username" - type: "string" - secret: false - required: false - password: - description: "Password" - type: "string" - secret: true - required: false +url: + description: "URL of the nexus3 instance (e.g. ``http://localhost:8081``)" + type: "string" + secret: false + required: true + position: 0 +verify: + description: "verify TLS, only used if the ``url`` option specifies an ``HTTPS`` connection" + type: boolean + position: 1 + default: True +user: + description: "Username" + type: "string" + secret: false + required: false + position: 2 +password: + description: "Password" + type: "string" + secret: true + required: false + position: 3 profiles: - description: "Nexus3 Connection profile." + description: "Nexus3 Connection profile name. This will use above options as" type: object required: false properties: {} @@ -28,4 +31,22 @@ profiles: type: object additionalProperties: false properties: - <<: *profile_options \ No newline at end of file + url: + description: "URL of the JIRA instance (e.g. ``https://myproject.atlassian.net``)" + type: "string" + secret: false + required: true + verify: + description: "verify TLS, only used if the ``url`` option specifies an ``HTTPS`` connection" + type: boolean + default: True + user: + description: "Username" + type: "string" + secret: false + required: false + password: + description: "Password" + type: "string" + secret: true + required: false diff --git a/stackstorm-nexus3/tests/Makefile b/stackstorm-nexus3/tests/Makefile index fd89c35..4d3b655 100644 --- a/stackstorm-nexus3/tests/Makefile +++ b/stackstorm-nexus3/tests/Makefile @@ -43,6 +43,10 @@ reload: echo "=================== Running st2ctl reload" st2ctl reload --register-all +restart: + echo "=================== Running st2ctl restart" + st2ctl restart + sync: LOCAL_NEXUS_DIR=$$PWD; \ ST2_PACK_DIR='/opt/stackstorm/packs'; \ From d19cabbb802f0f73e27918a23f9e9058e1682755 Mon Sep 17 00:00:00 2001 From: sonu kumar meena Date: Tue, 26 Feb 2019 10:49:02 +0530 Subject: [PATCH 40/45] updated README --- stackstorm-nexus3/README.md | 26 +++++++++++--------------- stackstorm-nexus3/pack.yaml | 9 +++++---- stackstorm-nexus3/tests/Makefile | 2 +- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/stackstorm-nexus3/README.md b/stackstorm-nexus3/README.md index 80a3cff..03ac651 100644 --- a/stackstorm-nexus3/README.md +++ b/stackstorm-nexus3/README.md @@ -4,8 +4,7 @@ ## Installation - -Install this pack with: `st2 pack install file:///$PWD` +Install this pack with: `st2 pack install file://$PWD` Or if in remote repository: `st2 pack install https://github.com/MY/PACK` @@ -45,25 +44,25 @@ profiles: # verify: fallback to verify: True ``` - **Note** : When modifying the configuration in `/opt/stackstorm/configs/` please remember to tell StackStorm to load these new values by running `st2ctl reload --register-configs` - ## Actions While naming actions following convention is used: -**< VERB >_< RESOURCE(plural) >** - + < VERB >_< RESOURCE(plural) > + eg. + list_repositories + get_scripts Supported Resources -- Repositories -- Scripts +* Repositories +* Scripts -### Available actions: +### Available actions * **list_repositories** : List nexus3 repositories * **get_repositories** : get nexus3 repositories @@ -91,18 +90,15 @@ Supported Resources --NIL-- - -# Testing - +## Testing While testing you can leverage [Makefile](./tests/Makefile) to ease writing and testing actions. Read the Makefile for the list of useful commands. - -# Contributing +## Contributing Before submitting make sure python linter is happy with your changes first -``` +``` bash pip install flake8 #executing flake8 ./ diff --git a/stackstorm-nexus3/pack.yaml b/stackstorm-nexus3/pack.yaml index 0ff4e68..78dc401 100644 --- a/stackstorm-nexus3/pack.yaml +++ b/stackstorm-nexus3/pack.yaml @@ -3,11 +3,12 @@ ref: nexus3 name: Sontatype nexus3 description: Sontatype nexus3 stackstorm pack keywords: - - example - - test + - nexus + - nexus3 + - sonatype version: 0.1.0 python_versions: - "2" - "3" -author: Sonu K. Meena -email: sonu.meena@example.com +author: Sonu Meena +email: sonukr666@gmail.com diff --git a/stackstorm-nexus3/tests/Makefile b/stackstorm-nexus3/tests/Makefile index 4d3b655..a3f5a33 100644 --- a/stackstorm-nexus3/tests/Makefile +++ b/stackstorm-nexus3/tests/Makefile @@ -37,7 +37,7 @@ delete_script: install: echo "=================== Running st2 pack install" - st2 pack install file:///$$PWD + st2 pack install file://$$PWD reload: echo "=================== Running st2ctl reload" From 0e87ca4468bd49de407eb058ce6e4e6db1309005 Mon Sep 17 00:00:00 2001 From: blag Date: Tue, 26 Feb 2019 16:51:04 -0800 Subject: [PATCH 41/45] Fix incorrect moved directory --- stackstorm-nexus3/.yo-rc.json => .yo-rc.json | 0 README.md | 109 ++++++++++++++++-- .../create_repositories.yaml | 0 .../actions => actions}/create_scripts.yaml | 0 .../delete_repositories.yaml | 0 .../actions => actions}/delete_scripts.yaml | 0 .../actions => actions}/get_repositories.yaml | 0 .../actions => actions}/get_scripts.yaml | 0 .../actions => actions}/lib/__init__.py | 0 .../actions => actions}/lib/base.py | 0 .../actions => actions}/lib/exception.py | 0 .../list_repositories.yaml | 0 .../actions => actions}/list_scripts.yaml | 0 {stackstorm-nexus3/actions => actions}/run.py | 0 .../actions => actions}/run_scripts.yaml | 0 .../get_nexus_repository.yaml | 0 .../config.schema.yaml => config.schema.yaml | 0 stackstorm-nexus3/icon.png => icon.png | Bin ...nexus3.yaml.example => nexus3.yaml.example | 0 stackstorm-nexus3/pack.yaml => pack.yaml | 0 .../retry_core_http_on_timeout.yaml | 0 .../requirements.txt => requirements.txt | 0 stackstorm-nexus3/.gitignore | 92 --------------- stackstorm-nexus3/README.md | 106 ----------------- {stackstorm-nexus3/tests => tests}/Makefile | 0 .../fixtures/get_repositories.json | 0 .../tests => tests}/fixtures/get_scripts.json | 0 .../fixtures/list_repositories.json | 0 .../fixtures/list_scripts.json | 0 .../tests => tests}/nexus_base_test_case.py | 0 .../test_resource_repositories.py | 0 .../tests => tests}/test_resource_scripts.py | 0 .../test_resource_unsupported.py | 0 .../tests => tests}/test_run.py | 0 34 files changed, 98 insertions(+), 209 deletions(-) rename stackstorm-nexus3/.yo-rc.json => .yo-rc.json (100%) rename {stackstorm-nexus3/actions => actions}/create_repositories.yaml (100%) rename {stackstorm-nexus3/actions => actions}/create_scripts.yaml (100%) rename {stackstorm-nexus3/actions => actions}/delete_repositories.yaml (100%) rename {stackstorm-nexus3/actions => actions}/delete_scripts.yaml (100%) rename {stackstorm-nexus3/actions => actions}/get_repositories.yaml (100%) rename {stackstorm-nexus3/actions => actions}/get_scripts.yaml (100%) rename {stackstorm-nexus3/actions => actions}/lib/__init__.py (100%) rename {stackstorm-nexus3/actions => actions}/lib/base.py (100%) rename {stackstorm-nexus3/actions => actions}/lib/exception.py (100%) rename {stackstorm-nexus3/actions => actions}/list_repositories.yaml (100%) rename {stackstorm-nexus3/actions => actions}/list_scripts.yaml (100%) rename {stackstorm-nexus3/actions => actions}/run.py (100%) rename {stackstorm-nexus3/actions => actions}/run_scripts.yaml (100%) rename {stackstorm-nexus3/aliases => aliases}/get_nexus_repository.yaml (100%) rename stackstorm-nexus3/config.schema.yaml => config.schema.yaml (100%) rename stackstorm-nexus3/icon.png => icon.png (100%) rename stackstorm-nexus3/nexus3.yaml.example => nexus3.yaml.example (100%) rename stackstorm-nexus3/pack.yaml => pack.yaml (100%) rename {stackstorm-nexus3/policies => policies}/retry_core_http_on_timeout.yaml (100%) rename stackstorm-nexus3/requirements.txt => requirements.txt (100%) delete mode 100644 stackstorm-nexus3/.gitignore delete mode 100644 stackstorm-nexus3/README.md rename {stackstorm-nexus3/tests => tests}/Makefile (100%) rename {stackstorm-nexus3/tests => tests}/fixtures/get_repositories.json (100%) rename {stackstorm-nexus3/tests => tests}/fixtures/get_scripts.json (100%) rename {stackstorm-nexus3/tests => tests}/fixtures/list_repositories.json (100%) rename {stackstorm-nexus3/tests => tests}/fixtures/list_scripts.json (100%) rename {stackstorm-nexus3/tests => tests}/nexus_base_test_case.py (100%) rename {stackstorm-nexus3/tests => tests}/test_resource_repositories.py (100%) rename {stackstorm-nexus3/tests => tests}/test_resource_scripts.py (100%) rename {stackstorm-nexus3/tests => tests}/test_resource_unsupported.py (100%) rename {stackstorm-nexus3/tests => tests}/test_run.py (100%) diff --git a/stackstorm-nexus3/.yo-rc.json b/.yo-rc.json similarity index 100% rename from stackstorm-nexus3/.yo-rc.json rename to .yo-rc.json diff --git a/README.md b/README.md index f1199d7..03ac651 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,106 @@ -# StackStorm Exchange Incubator +# Stackstorm-Nexus3 -### What is this? +[Sontatype nexus3](https://www.sonatype.com/nexus-repository-oss) stackstorm pack -This repository is a very special place where user-submitted packs get reviewed, perfected, approved, and finally transferred to the Exchange. +## Installation -If you want to submit your pack, it's simple! **Fork this repo, create a subdirectory with your pack, and open a Pull Request.** We'll take it from here. Even if your pack is work-in-progress, you can still submit it to get advice and early feedback from our engineers! Or ping us [on Slack](https://stackstorm.com/community-signup), which is generally the best place to get advice from the StackStorm Community. +Install this pack with: `st2 pack install file://$PWD` -Before you submit a pack, make sure to read the [Create and Contribute a Pack](https://docs.stackstorm.com/reference/packs.html) section of our documentation. +Or if in remote repository: `st2 pack install https://github.com/MY/PACK` -Here's N.E.P.T.R. the StackStorm Exchange Governor, giving you a thumbs-up: +## Configuration -![](http://i.imgur.com/3bqVAh0.gif) +Copy the example configuration in [nexus3.yaml.example](./nexus3.yaml.example) +to `/opt/stackstorm/configs/nexus3.yaml` and edit as required. -## Contributors License Agreement +add nexus3 server connection profile: -By contributing you agree that these contributions are your own (or approved by your employer) and -you grant a full, complete, irrevocable copyright license to all users and developers of the -project, present and future, pursuant to the license of the project. +* ``url`` - URL of the nexus3 server (e.g. ``http://localhost:8081``) +* ``user`` - username +* ``password`` - Password +* ``verify`` - https tls verify, only used if the `url` option specifies an `https` connection + +You can also add multiple profiles: + +When you add multiple profile, above parameters becomes defaults for any key missing in the profile. + +``` yaml +--- +url: "http://localhost:8081" +user: "admin" +password: "admin123" +verify: True +default_profile: "dev" # use this to make for missing config_profile parameter when calling any action +profiles: + "dev": + url: "http://localhost:8081" + user: "dev-user" + password: "mypas" + verify: True + "dev-2": + user: "dev2-user" + password: "mypass2" + # url : fallback to url: "http://localhost:8081" + # verify: fallback to verify: True +``` + +**Note** : When modifying the configuration in `/opt/stackstorm/configs/` please + remember to tell StackStorm to load these new values by running + `st2ctl reload --register-configs` + +## Actions + +While naming actions following convention is used: + + < VERB >_< RESOURCE(plural) > + eg. + list_repositories + get_scripts + +Supported Resources + +* Repositories +* Scripts + +### Available actions + +* **list_repositories** : List nexus3 repositories +* **get_repositories** : get nexus3 repositories +* **create_repositories** : create nexus3 repository +* **delete_repositories** : delete nexus3 repository + +* **list_scripts** : List nexus3 scripts +* **get_scripts** : get nexus3 scripts +* **create_scripts** : create(& upload) if missing, groovy script +* **delete_scripts** : delete nexus3 script + +## Policies + +* **http.retry** : Retry core.http action on timeout. + +## Aliases + +--NIL-- + +## Rules + +--NIL-- + +## Sensors + +--NIL-- + +## Testing + +While testing you can leverage [Makefile](./tests/Makefile) to ease writing and testing actions. Read the Makefile for the list of useful commands. + +## Contributing + +Before submitting make sure python linter is happy with your changes first + +``` bash +pip install flake8 + +#executing flake8 ./ +make -f tests/Makefile lint +``` \ No newline at end of file diff --git a/stackstorm-nexus3/actions/create_repositories.yaml b/actions/create_repositories.yaml similarity index 100% rename from stackstorm-nexus3/actions/create_repositories.yaml rename to actions/create_repositories.yaml diff --git a/stackstorm-nexus3/actions/create_scripts.yaml b/actions/create_scripts.yaml similarity index 100% rename from stackstorm-nexus3/actions/create_scripts.yaml rename to actions/create_scripts.yaml diff --git a/stackstorm-nexus3/actions/delete_repositories.yaml b/actions/delete_repositories.yaml similarity index 100% rename from stackstorm-nexus3/actions/delete_repositories.yaml rename to actions/delete_repositories.yaml diff --git a/stackstorm-nexus3/actions/delete_scripts.yaml b/actions/delete_scripts.yaml similarity index 100% rename from stackstorm-nexus3/actions/delete_scripts.yaml rename to actions/delete_scripts.yaml diff --git a/stackstorm-nexus3/actions/get_repositories.yaml b/actions/get_repositories.yaml similarity index 100% rename from stackstorm-nexus3/actions/get_repositories.yaml rename to actions/get_repositories.yaml diff --git a/stackstorm-nexus3/actions/get_scripts.yaml b/actions/get_scripts.yaml similarity index 100% rename from stackstorm-nexus3/actions/get_scripts.yaml rename to actions/get_scripts.yaml diff --git a/stackstorm-nexus3/actions/lib/__init__.py b/actions/lib/__init__.py similarity index 100% rename from stackstorm-nexus3/actions/lib/__init__.py rename to actions/lib/__init__.py diff --git a/stackstorm-nexus3/actions/lib/base.py b/actions/lib/base.py similarity index 100% rename from stackstorm-nexus3/actions/lib/base.py rename to actions/lib/base.py diff --git a/stackstorm-nexus3/actions/lib/exception.py b/actions/lib/exception.py similarity index 100% rename from stackstorm-nexus3/actions/lib/exception.py rename to actions/lib/exception.py diff --git a/stackstorm-nexus3/actions/list_repositories.yaml b/actions/list_repositories.yaml similarity index 100% rename from stackstorm-nexus3/actions/list_repositories.yaml rename to actions/list_repositories.yaml diff --git a/stackstorm-nexus3/actions/list_scripts.yaml b/actions/list_scripts.yaml similarity index 100% rename from stackstorm-nexus3/actions/list_scripts.yaml rename to actions/list_scripts.yaml diff --git a/stackstorm-nexus3/actions/run.py b/actions/run.py similarity index 100% rename from stackstorm-nexus3/actions/run.py rename to actions/run.py diff --git a/stackstorm-nexus3/actions/run_scripts.yaml b/actions/run_scripts.yaml similarity index 100% rename from stackstorm-nexus3/actions/run_scripts.yaml rename to actions/run_scripts.yaml diff --git a/stackstorm-nexus3/aliases/get_nexus_repository.yaml b/aliases/get_nexus_repository.yaml similarity index 100% rename from stackstorm-nexus3/aliases/get_nexus_repository.yaml rename to aliases/get_nexus_repository.yaml diff --git a/stackstorm-nexus3/config.schema.yaml b/config.schema.yaml similarity index 100% rename from stackstorm-nexus3/config.schema.yaml rename to config.schema.yaml diff --git a/stackstorm-nexus3/icon.png b/icon.png similarity index 100% rename from stackstorm-nexus3/icon.png rename to icon.png diff --git a/stackstorm-nexus3/nexus3.yaml.example b/nexus3.yaml.example similarity index 100% rename from stackstorm-nexus3/nexus3.yaml.example rename to nexus3.yaml.example diff --git a/stackstorm-nexus3/pack.yaml b/pack.yaml similarity index 100% rename from stackstorm-nexus3/pack.yaml rename to pack.yaml diff --git a/stackstorm-nexus3/policies/retry_core_http_on_timeout.yaml b/policies/retry_core_http_on_timeout.yaml similarity index 100% rename from stackstorm-nexus3/policies/retry_core_http_on_timeout.yaml rename to policies/retry_core_http_on_timeout.yaml diff --git a/stackstorm-nexus3/requirements.txt b/requirements.txt similarity index 100% rename from stackstorm-nexus3/requirements.txt rename to requirements.txt diff --git a/stackstorm-nexus3/.gitignore b/stackstorm-nexus3/.gitignore deleted file mode 100644 index 0f363e1..0000000 --- a/stackstorm-nexus3/.gitignore +++ /dev/null @@ -1,92 +0,0 @@ -#visual studio -.vscode - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -./lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# IPython Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# dotenv -.env - -# virtualenv -venv/ -ENV/ - -# Spyder project settings -.spyderproject - -# Rope project settings -.ropeproject \ No newline at end of file diff --git a/stackstorm-nexus3/README.md b/stackstorm-nexus3/README.md deleted file mode 100644 index 03ac651..0000000 --- a/stackstorm-nexus3/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# Stackstorm-Nexus3 - -[Sontatype nexus3](https://www.sonatype.com/nexus-repository-oss) stackstorm pack - -## Installation - -Install this pack with: `st2 pack install file://$PWD` - -Or if in remote repository: `st2 pack install https://github.com/MY/PACK` - -## Configuration - -Copy the example configuration in [nexus3.yaml.example](./nexus3.yaml.example) -to `/opt/stackstorm/configs/nexus3.yaml` and edit as required. - -add nexus3 server connection profile: - -* ``url`` - URL of the nexus3 server (e.g. ``http://localhost:8081``) -* ``user`` - username -* ``password`` - Password -* ``verify`` - https tls verify, only used if the `url` option specifies an `https` connection - -You can also add multiple profiles: - -When you add multiple profile, above parameters becomes defaults for any key missing in the profile. - -``` yaml ---- -url: "http://localhost:8081" -user: "admin" -password: "admin123" -verify: True -default_profile: "dev" # use this to make for missing config_profile parameter when calling any action -profiles: - "dev": - url: "http://localhost:8081" - user: "dev-user" - password: "mypas" - verify: True - "dev-2": - user: "dev2-user" - password: "mypass2" - # url : fallback to url: "http://localhost:8081" - # verify: fallback to verify: True -``` - -**Note** : When modifying the configuration in `/opt/stackstorm/configs/` please - remember to tell StackStorm to load these new values by running - `st2ctl reload --register-configs` - -## Actions - -While naming actions following convention is used: - - < VERB >_< RESOURCE(plural) > - eg. - list_repositories - get_scripts - -Supported Resources - -* Repositories -* Scripts - -### Available actions - -* **list_repositories** : List nexus3 repositories -* **get_repositories** : get nexus3 repositories -* **create_repositories** : create nexus3 repository -* **delete_repositories** : delete nexus3 repository - -* **list_scripts** : List nexus3 scripts -* **get_scripts** : get nexus3 scripts -* **create_scripts** : create(& upload) if missing, groovy script -* **delete_scripts** : delete nexus3 script - -## Policies - -* **http.retry** : Retry core.http action on timeout. - -## Aliases - ---NIL-- - -## Rules - ---NIL-- - -## Sensors - ---NIL-- - -## Testing - -While testing you can leverage [Makefile](./tests/Makefile) to ease writing and testing actions. Read the Makefile for the list of useful commands. - -## Contributing - -Before submitting make sure python linter is happy with your changes first - -``` bash -pip install flake8 - -#executing flake8 ./ -make -f tests/Makefile lint -``` \ No newline at end of file diff --git a/stackstorm-nexus3/tests/Makefile b/tests/Makefile similarity index 100% rename from stackstorm-nexus3/tests/Makefile rename to tests/Makefile diff --git a/stackstorm-nexus3/tests/fixtures/get_repositories.json b/tests/fixtures/get_repositories.json similarity index 100% rename from stackstorm-nexus3/tests/fixtures/get_repositories.json rename to tests/fixtures/get_repositories.json diff --git a/stackstorm-nexus3/tests/fixtures/get_scripts.json b/tests/fixtures/get_scripts.json similarity index 100% rename from stackstorm-nexus3/tests/fixtures/get_scripts.json rename to tests/fixtures/get_scripts.json diff --git a/stackstorm-nexus3/tests/fixtures/list_repositories.json b/tests/fixtures/list_repositories.json similarity index 100% rename from stackstorm-nexus3/tests/fixtures/list_repositories.json rename to tests/fixtures/list_repositories.json diff --git a/stackstorm-nexus3/tests/fixtures/list_scripts.json b/tests/fixtures/list_scripts.json similarity index 100% rename from stackstorm-nexus3/tests/fixtures/list_scripts.json rename to tests/fixtures/list_scripts.json diff --git a/stackstorm-nexus3/tests/nexus_base_test_case.py b/tests/nexus_base_test_case.py similarity index 100% rename from stackstorm-nexus3/tests/nexus_base_test_case.py rename to tests/nexus_base_test_case.py diff --git a/stackstorm-nexus3/tests/test_resource_repositories.py b/tests/test_resource_repositories.py similarity index 100% rename from stackstorm-nexus3/tests/test_resource_repositories.py rename to tests/test_resource_repositories.py diff --git a/stackstorm-nexus3/tests/test_resource_scripts.py b/tests/test_resource_scripts.py similarity index 100% rename from stackstorm-nexus3/tests/test_resource_scripts.py rename to tests/test_resource_scripts.py diff --git a/stackstorm-nexus3/tests/test_resource_unsupported.py b/tests/test_resource_unsupported.py similarity index 100% rename from stackstorm-nexus3/tests/test_resource_unsupported.py rename to tests/test_resource_unsupported.py diff --git a/stackstorm-nexus3/tests/test_run.py b/tests/test_run.py similarity index 100% rename from stackstorm-nexus3/tests/test_run.py rename to tests/test_run.py From 0f00d6eadb66e12ff3fbb63b04b882aad6ef1197 Mon Sep 17 00:00:00 2001 From: blag Date: Tue, 26 Feb 2019 22:43:12 -0800 Subject: [PATCH 42/45] Don't echo that we're going to echo, just echo --- tests/Makefile | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index a3f5a33..cb27fdf 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -4,47 +4,47 @@ ST2_EXEC_CMD = grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}"; run: sync list_repo create_repo get_repo del_repo get_repo list_scripts get_script run_script delete_script get_script test list_repo: - echo "=================== List repository" + @echo "=================== List repository" st2 action execute nexus3.list_repositories config_profile=dev | grep "execution get" | xargs -0 -I{} bash -c "sleep 2; {}"; create_repo: - echo "=================== Create repository" + @echo "=================== Create repository" st2 action execute nexus3.create_repositories config_profile=dev type=hosted name=maven2-dumy format=maven write_policy=ALLOW | $(ST2_EXEC_CMD) get_repo: - echo "=================== Get repository" + @echo "=================== Get repository" st2 action execute nexus3.get_repositories config_profile=dev name=maven2-dumy | $(ST2_EXEC_CMD) del_repo: - echo "=================== Delete repository" + @echo "=================== Delete repository" st2 action execute nexus3.delete_repositories config_profile=dev name=maven2-dumy | $(ST2_EXEC_CMD) list_scripts: - echo "=================== List scripts" + @echo "=================== List scripts" st2 action execute nexus3.list_scripts config_profile=dev | $(ST2_EXEC_CMD) get_script: - echo "=================== Get script" + @echo "=================== Get script" st2 action execute nexus3.get_scripts config_profile=dev name=nexus3-cli-repository-create | $(ST2_EXEC_CMD) run_script: - echo "=================== Run script" + @echo "=================== Run script" st2 action execute nexus3.run_scripts config_profile=dev name=nexus3-cli-repository-create | $(ST2_EXEC_CMD) delete_script: - echo "=================== Delete script" + @echo "=================== Delete script" st2 action execute nexus3.delete_scripts config_profile=dev name=nexus3-cli-repository-create | $(ST2_EXEC_CMD) install: - echo "=================== Running st2 pack install" + @echo "=================== Running st2 pack install" st2 pack install file://$$PWD reload: - echo "=================== Running st2ctl reload" + @echo "=================== Running st2ctl reload" st2ctl reload --register-all restart: - echo "=================== Running st2ctl restart" + @echo "=================== Running st2ctl restart" st2ctl restart sync: @@ -64,4 +64,3 @@ validate: test: st2-run-pack-tests -cjtp ./ - From b9bef176ebd48b98fe3d9128a9239f13117fadc3 Mon Sep 17 00:00:00 2001 From: blag Date: Tue, 26 Feb 2019 22:43:59 -0800 Subject: [PATCH 43/45] Make sure we use the mock object in the action --- tests/test_resource_repositories.py | 4 ++++ tests/test_resource_scripts.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/test_resource_repositories.py b/tests/test_resource_repositories.py index e0a2e53..f5359be 100644 --- a/tests/test_resource_repositories.py +++ b/tests/test_resource_repositories.py @@ -22,6 +22,7 @@ def test_action_list_repositories(self, mock_nexus): mock_client.repositories.raw_list.return_value = repo_list_fixture action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.repositories.raw_list.assert_called_once() @@ -44,6 +45,7 @@ def mock_get_raw_by_name(name): side_effect=mock_get_raw_by_name) action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.repositories.get_raw_by_name.assert_called_once() @@ -63,6 +65,7 @@ def mock_create(payload): mock_client.repositories.create = mock.Mock(side_effect=mock_create) action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.repositories.create.assert_called_once() @@ -82,6 +85,7 @@ def mock_delete(name): mock_client.repositories.delete = mock.Mock(side_effect=mock_delete) action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.repositories.delete.assert_called_once() diff --git a/tests/test_resource_scripts.py b/tests/test_resource_scripts.py index c822ff7..8acbb19 100644 --- a/tests/test_resource_scripts.py +++ b/tests/test_resource_scripts.py @@ -20,6 +20,7 @@ def test_action_list_scripts(self, mock_nexus): mock_client.scripts.list.return_value = script_list_fixture action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.scripts.list.assert_called_once() @@ -40,6 +41,7 @@ def mock_get(name): mock_client.scripts.get = mock.Mock(side_effect=mock_get) action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.scripts.get.assert_called_once() @@ -60,6 +62,7 @@ def mock_create_if_missing(payload): side_effect=mock_create_if_missing) action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.scripts.create_if_missing.assert_called_once() @@ -79,6 +82,7 @@ def mock_delete(name): mock_client.scripts.delete = mock.Mock(side_effect=mock_delete) action = self.get_action_instance(pack_config) + action._client = mock_client (is_success, response) = action.run(**action_config) mock_client.scripts.delete.assert_called_once() From 358c5f404293d0a048e5f8deb66b64159a036e64 Mon Sep 17 00:00:00 2001 From: blag Date: Tue, 26 Feb 2019 22:48:43 -0800 Subject: [PATCH 44/45] Split up tests and tweak assertions to work --- tests/test_run.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/tests/test_run.py b/tests/test_run.py index b909b5e..f3896d1 100644 --- a/tests/test_run.py +++ b/tests/test_run.py @@ -7,10 +7,15 @@ class RunTestCase(BaseActionTestCase): + """ + Test action and pack configuration + """ action_cls = ActionManager - def test_configuration(self): - """ This tests action and pack configuration + def test_missing_parameter(self): + """ + Test that MissingParameterError is raised when a required parameter is + not specified. """ configs = { "action_config": { @@ -23,6 +28,11 @@ def test_configuration(self): with self.assertRaises(MissingParameterError): action.run(**configs["action_config"]) + def test_missing_profile(self): + """ + Test that MissingProfileError is raised when a non-existent profile is + specified. + """ # Profile should exist, if defined in action configs = { "action_config": { @@ -33,9 +43,17 @@ def test_configuration(self): "pack_config": {} } action = self.get_action_instance(config=configs["pack_config"]) - with self.assertRaises(MissingProfileError): + # Unsure why this works when assertRaises(MissingProfileError) doesn't + with self.assertRaises(Exception) as exc: action.run(**configs["action_config"]) + self.assertIsInstance(exc, MissingProfileError) + + def test_validation_failure(self): + """ + Test that ValidationFailError is raised when required connection + parameters are not configured. + """ # Required connection parameters should exist: url, user, password configs = { "action_config": { @@ -45,5 +63,8 @@ def test_configuration(self): "pack_config": {} } action = self.get_action_instance(config=configs["pack_config"]) - with self.assertRaises(ValidationFailError): + # Unsure why this works when assertRaises(MissingProfileError) doesn't + with self.assertRaises(Exception) as exc: action.run(**configs["action_config"]) + + self.assertIsInstance(exc, ValidationFailError) From 72e25cf27bb2e3a7fdd16225a3c85e452f05a4cd Mon Sep 17 00:00:00 2001 From: blag Date: Wed, 27 Feb 2019 12:23:59 -0800 Subject: [PATCH 45/45] Add comment and finish up description --- config.schema.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config.schema.yaml b/config.schema.yaml index ed83692..c174106 100644 --- a/config.schema.yaml +++ b/config.schema.yaml @@ -23,7 +23,7 @@ password: required: false position: 3 profiles: - description: "Nexus3 Connection profile name. This will use above options as" + description: "Nexus3 Connection profile name. This will use above options as default values." type: object required: false properties: {} @@ -31,6 +31,7 @@ profiles: type: object additionalProperties: false properties: + # TODO: Refactor to use YAML anchors and references url: description: "URL of the JIRA instance (e.g. ``https://myproject.atlassian.net``)" type: "string"