1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Add new modules rundeck_job_run and rundeck_job_executions_info (#3521)

* Add new module rundeck_job_run

* Add new module rundeck_job_executions_info

* Removed supports_check_mode

* Fix supports_check_mode

* Fix version_added

* Fixes for PR#3521

* Fix default value for loglevel in the doc

* Fix job_status_check loop

* Add proposed changes in PR#3521

* Add proposed changes in PR#3521

* Change executions_info output to executions

* Add rundeck integration tests

* Fix rundeck integration test

* Add more tests to rundeck integration tests

* Update job_options doc

* Add more tests to rundeck integration tests

* Add more examples to rundeck_job_run doc

* Add proposed fixes for PR#3521

* Add proposed fixes for PR#3521

* Fix job_options

* Add proposed changes for PR#3521
This commit is contained in:
Phillipe Smith 2021-10-11 01:55:47 -03:00 committed by GitHub
parent 8ece0d3609
commit 9772485d3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 841 additions and 0 deletions

4
.github/BOTMETA.yml vendored
View file

@ -1163,6 +1163,10 @@ files:
maintainers: nerzhul
$modules/web_infrastructure/rundeck_project.py:
maintainers: nerzhul
$modules/web_infrastructure/rundeck_job_run.py:
maintainers: phsmith
$modules/web_infrastructure/rundeck_job_executions_info.py:
maintainers: phsmith
$modules/web_infrastructure/sophos_utm/:
maintainers: $team_e_spirit
keywords: sophos utm

View file

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Phillipe Smith <phsmithcc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
class ModuleDocFragment(object):
# Standard files documentation fragment
DOCUMENTATION = r'''
options:
url:
type: str
description:
- Rundeck instance URL.
required: true
api_version:
type: int
description:
- Rundeck API version to be used.
- API version must be at least 14.
default: 39
api_token:
type: str
description:
- Rundeck User API Token.
required: true
'''

View file

@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Phillipe Smith <phsmithcc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import json
from ansible.module_utils.urls import fetch_url, url_argument_spec
from ansible.module_utils.common.text.converters import to_native
def api_argument_spec():
'''
Creates an argument spec that can be used with any module
that will be requesting content via Rundeck API
'''
api_argument_spec = url_argument_spec()
api_argument_spec.update(dict(
url=dict(required=True, type="str"),
api_version=dict(type="int", default=39),
api_token=dict(required=True, type="str", no_log=True)
))
return api_argument_spec
def api_request(module, endpoint, data=None, method="GET"):
"""Manages Rundeck API requests via HTTP(S)
:arg module: The AnsibleModule (used to get url, api_version, api_token, etc).
:arg endpoint: The API endpoint to be used.
:kwarg data: The data to be sent (in case of POST/PUT).
:kwarg method: "POST", "PUT", etc.
:returns: A tuple of (**response**, **info**). Use ``response.read()`` to read the data.
The **info** contains the 'status' and other meta data. When a HttpError (status >= 400)
occurred then ``info['body']`` contains the error response data::
Example::
data={...}
resp, info = fetch_url(module,
"http://rundeck.example.org",
data=module.jsonify(data),
method="POST")
status_code = info["status"]
body = resp.read()
if status_code >= 400 :
body = info['body']
"""
response, info = fetch_url(
module=module,
url="%s/api/%s/%s" % (
module.params["url"],
module.params["api_version"],
endpoint
),
data=json.dumps(data),
method=method,
headers={
"Content-Type": "application/json",
"Accept": "application/json",
"X-Rundeck-Auth-Token": module.params["api_token"]
}
)
if info["status"] == 403:
module.fail_json(msg="Token authorization failed",
execution_info=json.loads(info["body"]))
if info["status"] == 409:
module.fail_json(msg="Job executions limit reached",
execution_info=json.loads(info["body"]))
elif info["status"] >= 500:
module.fail_json(msg="Rundeck API error",
execution_info=json.loads(info["body"]))
try:
content = response.read()
json_response = json.loads(content)
return json_response, info
except AttributeError as error:
module.fail_json(msg="Rundeck API request error",
exception=to_native(error),
execution_info=info)
except ValueError as error:
module.fail_json(
msg="No valid JSON response",
exception=to_native(error),
execution_info=content
)

View file

@ -0,0 +1 @@
./web_infrastructure/rundeck_job_executions_info.py

View file

@ -0,0 +1 @@
./web_infrastructure/rundeck_job_run.py

View file

@ -0,0 +1,193 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Phillipe Smith <phsmithcc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: rundeck_job_executions_info
short_description: Query executions for a Rundeck job
description:
- This module gets the list of executions for a specified Rundeck job.
author: "Phillipe Smith (@phsmith)"
version_added: 3.8.0
options:
job_id:
type: str
description:
- The job unique ID.
required: true
status:
type: str
description:
- The job status to filter.
choices: [succeeded, failed, aborted, running]
max:
type: int
description:
- Max results to return.
default: 20
offset:
type: int
description:
- The start point to return the results.
default: 0
extends_documentation_fragment:
- community.general.rundeck
- url
'''
EXAMPLES = '''
- name: Get Rundeck job executions info
community.general.rundeck_job_executions_info:
url: "https://rundeck.example.org"
api_version: 39
api_token: "mytoken"
job_id: "xxxxxxxxxxxxxxxxx"
register: rundeck_job_executions_info
- name: Show Rundeck job executions info
ansible.builtin.debug:
var: rundeck_job_executions_info.executions
'''
RETURN = '''
paging:
description: Results pagination info.
returned: success
type: dict
contains:
count:
description: Number of results in the response.
type: int
returned: success
total:
description: Total number of results.
type: int
returned: success
offset:
description: Offset from first of all results.
type: int
returned: success
max:
description: Maximum number of results per page.
type: int
returned: success
sample: {
"count": 20,
"total": 100,
"offset": 0,
"max": 20
}
executions:
description: Job executions list.
returned: always
type: list
elements: dict
sample: [
{
"id": 1,
"href": "https://rundeck.example.org/api/39/execution/1",
"permalink": "https://rundeck.example.org/project/myproject/execution/show/1",
"status": "succeeded",
"project": "myproject",
"executionType": "user",
"user": "admin",
"date-started": {
"unixtime": 1633525515026,
"date": "2021-10-06T13:05:15Z"
},
"date-ended": {
"unixtime": 1633525518386,
"date": "2021-10-06T13:05:18Z"
},
"job": {
"id": "697af0c4-72d3-4c15-86a3-b5bfe3c6cb6a",
"averageDuration": 6381,
"name": "Test",
"group": "",
"project": "myproject",
"description": "",
"options": {
"exit_code": "0"
},
"href": "https://rundeck.example.org/api/39/job/697af0c4-72d3-4c15-86a3-b5bfe3c6cb6a",
"permalink": "https://rundeck.example.org/project/myproject/job/show/697af0c4-72d3-4c15-86a3-b5bfe3c6cb6a"
},
"description": "Plugin[com.batix.rundeck.plugins.AnsiblePlaybookInlineWorkflowStep, nodeStep: false]",
"argstring": "-exit_code 0",
"serverUUID": "5b9a1438-fa3a-457e-b254-8f3d70338068"
}
]
'''
# Modules import
import json
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.six.moves.urllib.parse import quote
from ansible_collections.community.general.plugins.module_utils.rundeck import (
api_argument_spec,
api_request
)
class RundeckJobExecutionsInfo(object):
def __init__(self, module):
self.module = module
self.url = self.module.params["url"]
self.api_version = self.module.params["api_version"]
self.job_id = self.module.params["job_id"]
self.offset = self.module.params["offset"]
self.max = self.module.params["max"]
self.status = self.module.params["status"] or ""
def job_executions(self):
response, info = api_request(
module=self.module,
endpoint="job/%s/executions?offset=%s&max=%s&status=%s"
% (quote(self.job_id), self.offset, self.max, self.status),
method="GET"
)
if info["status"] != 200:
self.module.fail_json(
msg=info["msg"],
executions=response
)
self.module.exit_json(msg="Executions info result", **response)
def main():
argument_spec = api_argument_spec()
argument_spec.update(dict(
job_id=dict(required=True, type="str"),
offset=dict(type="int", default=0),
max=dict(type="int", default=20),
status=dict(
type="str",
choices=["succeeded", "failed", "aborted", "running"]
)
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True
)
if module.params["api_version"] < 14:
module.fail_json(msg="API version should be at least 14")
rundeck = RundeckJobExecutionsInfo(module)
rundeck.job_executions()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,317 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2021, Phillipe Smith <phsmithcc@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: rundeck_job_run
short_description: Run a Rundeck job
description:
- This module runs a Rundeck job specified by ID.
author: "Phillipe Smith (@phsmith)"
version_added: 3.8.0
options:
job_id:
type: str
description:
- The job unique ID.
required: true
job_options:
type: dict
description:
- The job options for the steps.
- Numeric values must be quoted.
filter_nodes:
type: str
description:
- Filter the nodes where the jobs must run.
- See U(https://docs.rundeck.com/docs/manual/11-node-filters.html#node-filter-syntax).
run_at_time:
type: str
description:
- Schedule the job execution to run at specific date and time.
- ISO-8601 date and time format like C(2021-10-05T15:45:00-03:00).
loglevel:
type: str
description:
- Log level configuration.
choices: [debug, verbose, info, warn, error]
default: info
wait_execution:
type: bool
description:
- Wait until the job finished the execution.
default: true
wait_execution_delay:
type: int
description:
- Delay, in seconds, between job execution status check requests.
default: 5
wait_execution_timeout:
type: int
description:
- Job execution wait timeout in seconds.
- If the timeout is reached, the job will be aborted.
- Keep in mind that there is a sleep based on I(wait_execution_delay) after each job status check.
default: 120
abort_on_timeout:
type: bool
description:
- Send a job abort request if exceeded the I(wait_execution_timeout) specified.
default: false
extends_documentation_fragment:
- community.general.rundeck
- url
'''
EXAMPLES = '''
- name: Run a Rundeck job
community.general.rundeck_job_run:
url: "https://rundeck.example.org"
api_version: 39
api_token: "mytoken"
job_id: "xxxxxxxxxxxxxxxxx"
register: rundeck_job_run
- name: Show execution info
ansible.builtin.debug:
var: rundeck_job_run.execution_info
- name: Run a Rundeck job with options
community.general.rundeck_job_run:
url: "https://rundeck.example.org"
api_version: 39
api_token: "mytoken"
job_id: "xxxxxxxxxxxxxxxxx"
job_options:
option_1: "value_1"
option_2: "value_3"
option_3: "value_3"
register: rundeck_job_run
- name: Run a Rundeck job with timeout, delay between status check and abort on timeout
community.general.rundeck_job_run:
url: "https://rundeck.example.org"
api_version: 39
api_token: "mytoken"
job_id: "xxxxxxxxxxxxxxxxx"
wait_execution_timeout: 30
wait_execution_delay: 10
abort_on_timeout: true
register: rundeck_job_run
- name: Schedule a Rundeck job
community.general.rundeck_job_run:
url: "https://rundeck.example.org"
api_version: 39
api_token: "mytoken"
job_id: "xxxxxxxxxxxxxxxxx"
run_at_time: "2021-10-05T15:45:00-03:00"
register: rundeck_job_schedule
- name: Fire-and-forget a Rundeck job
community.general.rundeck_job_run:
url: "https://rundeck.example.org"
api_version: 39
api_token: "mytoken"
job_id: "xxxxxxxxxxxxxxxxx"
wait_execution: false
register: rundeck_job_run
'''
RETURN = '''
execution_info:
description: Rundeck job execution metadata.
returned: always
type: dict
sample: {
"msg": "Job execution succeeded!",
"execution_info": {
"id": 1,
"href": "https://rundeck.example.org/api/39/execution/1",
"permalink": "https://rundeck.example.org/project/myproject/execution/show/1",
"status": "succeeded",
"project": "myproject",
"executionType": "user",
"user": "admin",
"date-started": {
"unixtime": 1633449020784,
"date": "2021-10-05T15:50:20Z"
},
"date-ended": {
"unixtime": 1633449026358,
"date": "2021-10-05T15:50:26Z"
},
"job": {
"id": "697af0c4-72d3-4c15-86a3-b5bfe3c6cb6a",
"averageDuration": 4917,
"name": "Test",
"group": "",
"project": "myproject",
"description": "",
"options": {
"exit_code": "0"
},
"href": "https://rundeck.example.org/api/39/job/697af0c4-72d3-4c15-86a3-b5bfe3c6cb6a",
"permalink": "https://rundeck.example.org/project/myproject/job/show/697af0c4-72d3-4c15-86a3-b5bfe3c6cb6a"
},
"description": "sleep 5 && echo 'Test!' && exit ${option.exit_code}",
"argstring": "-exit_code 0",
"serverUUID": "5b9a1438-fa3a-457e-b254-8f3d70338068",
"successfulNodes": [
"localhost"
],
"output": "Test!"
}
}
'''
# Modules import
import json
from datetime import datetime, timedelta
from time import sleep
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.six.moves.urllib.parse import quote
from ansible_collections.community.general.plugins.module_utils.rundeck import (
api_argument_spec,
api_request
)
class RundeckJobRun(object):
def __init__(self, module):
self.module = module
self.url = self.module.params["url"]
self.api_version = self.module.params["api_version"]
self.job_id = self.module.params["job_id"]
self.job_options = self.module.params["job_options"] or {}
self.filter_nodes = self.module.params["filter_nodes"] or ""
self.run_at_time = self.module.params["run_at_time"] or ""
self.loglevel = self.module.params["loglevel"].upper()
self.wait_execution = self.module.params['wait_execution']
self.wait_execution_delay = self.module.params['wait_execution_delay']
self.wait_execution_timeout = self.module.params['wait_execution_timeout']
self.abort_on_timeout = self.module.params['abort_on_timeout']
for k, v in self.job_options.items():
if not isinstance(v, str):
self.module.exit_json(
msg="Job option '%s' value must be a string" % k,
execution_info={}
)
def job_status_check(self, execution_id):
response = dict()
timeout = False
due = datetime.now() + timedelta(seconds=self.wait_execution_timeout)
while not timeout:
endpoint = "execution/%d" % execution_id
response = api_request(module=self.module, endpoint=endpoint)[0]
output = api_request(module=self.module,
endpoint="execution/%d/output" % execution_id)
log_output = "\n".join([x["log"] for x in output[0]["entries"]])
response.update({"output": log_output})
if response["status"] == "aborted":
break
elif response["status"] == "scheduled":
self.module.exit_json(msg="Job scheduled to run at %s" % self.run_at_time,
execution_info=response,
changed=True)
elif response["status"] == "failed":
self.module.fail_json(msg="Job execution failed",
execution_info=response)
elif response["status"] == "succeeded":
self.module.exit_json(msg="Job execution succeeded!",
execution_info=response)
if datetime.now() >= due:
timeout = True
break
# Wait for 5s before continue
sleep(self.wait_execution_delay)
response.update({"timed_out": timeout})
return response
def job_run(self):
response, info = api_request(
module=self.module,
endpoint="job/%s/run" % quote(self.job_id),
method="POST",
data={
"loglevel": self.loglevel,
"options": self.job_options,
"runAtTime": self.run_at_time,
"filter": self.filter_nodes
}
)
if info["status"] != 200:
self.module.fail_json(msg=info["msg"])
if not self.wait_execution:
self.module.exit_json(msg="Job run send successfully!",
execution_info=response)
job_status = self.job_status_check(response["id"])
if job_status["timed_out"]:
if self.abort_on_timeout:
api_request(
module=self.module,
endpoint="execution/%s/abort" % response['id'],
method="GET"
)
abort_status = self.job_status_check(response["id"])
self.module.fail_json(msg="Job execution aborted due the timeout specified",
execution_info=abort_status)
self.module.fail_json(msg="Job execution timed out",
execution_info=job_status)
def main():
argument_spec = api_argument_spec()
argument_spec.update(dict(
job_id=dict(required=True, type="str"),
job_options=dict(type="dict"),
filter_nodes=dict(type="str"),
run_at_time=dict(type="str"),
wait_execution=dict(type="bool", default=True),
wait_execution_delay=dict(type="int", default=5),
wait_execution_timeout=dict(type="int", default=120),
abort_on_timeout=dict(type="bool", default=False),
loglevel=dict(
type="str",
choices=["debug", "verbose", "info", "warn", "error"],
default="info"
)
))
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=False
)
if module.params["api_version"] < 14:
module.fail_json(msg="API version should be at least 14")
rundeck = RundeckJobRun(module)
rundeck.job_run()
if __name__ == "__main__":
main()

View file

@ -0,0 +1,8 @@
destructive
shippable/posix/group1
skip/aix
skip/osx
skip/macos
skip/windows
skip/freebsd
unsupported

View file

@ -0,0 +1,3 @@
rundeck_url: http://localhost:4440
rundeck_api_version: 39
rundeck_job_id: 3b8a6e54-69fb-42b7-b98f-f82e59238478

View file

@ -0,0 +1,23 @@
- defaultTab: nodes
description: ''
executionEnabled: true
id: 3b8a6e54-69fb-42b7-b98f-f82e59238478
loglevel: INFO
name: test_job
nodeFilterEditable: false
options:
- label: Exit Code
name: exit_code
value: '0'
- label: Sleep
name: sleep
value: '1'
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: sleep $RD_OPTION_SLEEP && echo "Test done!" && exit $RD_OPTION_EXIT_CODE
keepgoing: false
strategy: node-first
uuid: 3b8a6e54-69fb-42b7-b98f-f82e59238478

View file

@ -0,0 +1,2 @@
dependencies:
- setup_rundeck

View file

@ -0,0 +1,123 @@
####################################################################
# WARNING: These are designed specifically for Ansible tests #
# and should not be used as examples of how to write Ansible roles #
####################################################################
- name: Generate a Rundeck API Token
ansible.builtin.command: java -jar {{ rdeck_base }}/rundeck-cli.jar tokens create -u admin -d 24h -r admin
environment:
RD_URL: "{{ rundeck_url }}"
RD_USER: admin
RD_PASSWORD: admin
register: rundeck_api_token
- name: Create a Rundeck project
community.general.rundeck_project:
name: "test_project"
api_version: "{{ rundeck_api_version }}"
url: "{{ rundeck_url }}"
token: "{{ rundeck_api_token.stdout_lines[-1] }}"
state: present
- name: Copy test_job definition to /tmp
copy:
src: test_job.yaml
dest: /tmp/test_job.yaml
- name: Create Rundeck job Test
ansible.builtin.command: java -jar {{ rdeck_base }}/rundeck-cli.jar jobs load -f /tmp/test_job.yaml -F yaml -p test_project
environment:
RD_URL: "{{ rundeck_url }}"
RD_USER: admin
RD_PASSWORD: admin
- name: Wrong Rundeck API Token
community.general.rundeck_job_run:
url: "{{ rundeck_url }}"
api_version: "{{ rundeck_api_version }}"
api_token: wrong_token
job_id: "{{ rundeck_job_id }}"
ignore_errors: true
register: rundeck_job_run_wrong_token
- name: Assert that Rundeck authorization failed
ansible.builtin.assert:
that:
- rundeck_job_run_wrong_token.msg == "Token authorization failed"
- name: Success run Rundeck job test_job
community.general.rundeck_job_run:
url: "{{ rundeck_url }}"
api_version: "{{ rundeck_api_version }}"
api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
job_id: "{{ rundeck_job_id }}"
register: rundeck_job_run_success
- name: Assert that Rundeck job test_job runs successfully
ansible.builtin.assert:
that:
- rundeck_job_run_success.execution_info.status == "succeeded"
- name: Fail run Rundeck job test_job
community.general.rundeck_job_run:
url: "{{ rundeck_url }}"
api_version: "{{ rundeck_api_version }}"
api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
job_id: "{{ rundeck_job_id }}"
job_options:
exit_code: "1"
ignore_errors: true
register: rundeck_job_run_fail
- name: Assert that Rundeck job test_job failed
ansible.builtin.assert:
that:
- rundeck_job_run_fail.execution_info.status == "failed"
- name: Abort run Rundeck job test_job due timeout
community.general.rundeck_job_run:
url: "{{ rundeck_url }}"
api_version: "{{ rundeck_api_version }}"
api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
job_id: "{{ rundeck_job_id }}"
job_options:
sleep: "5"
wait_execution_timeout: 2
abort_on_timeout: true
ignore_errors: true
register: rundeck_job_run_aborted
- name: Assert that Rundeck job test_job is aborted
ansible.builtin.assert:
that:
- rundeck_job_run_aborted.execution_info.status == "aborted"
- name: Fire-and-forget run Rundeck job test_job
community.general.rundeck_job_run:
url: "{{ rundeck_url }}"
api_version: "{{ rundeck_api_version }}"
api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
job_id: "{{ rundeck_job_id }}"
job_options:
sleep: "5"
wait_execution: False
register: rundeck_job_run_forget
- name: Assert that Rundeck job test_job is running
ansible.builtin.assert:
that:
- rundeck_job_run_forget.execution_info.status == "running"
- name: Get Rundeck job test_job executions info
community.general.rundeck_job_executions_info:
url: "{{ rundeck_url }}"
api_version: "{{ rundeck_api_version }}"
api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
job_id: "{{ rundeck_job_id }}"
register: rundeck_job_executions_info
- name: Assert that Rundeck job executions info has 4 registers
ansible.builtin.assert:
that:
- rundeck_job_executions_info.paging.total | int == 4

View file

@ -0,0 +1,2 @@
rundeck_war_url: https://packagecloud.io/pagerduty/rundeck/packages/java/org.rundeck/rundeck-3.4.4-20210920.war/artifacts/rundeck-3.4.4-20210920.war/download
rundeck_cli_url: https://github.com/rundeck/rundeck-cli/releases/download/v1.3.10/rundeck-cli-1.3.10-all.jar

View file

@ -0,0 +1,37 @@
---
####################################################################
# WARNING: These are designed specifically for Ansible tests #
# and should not be used as examples of how to write Ansible roles #
####################################################################
- name: Skip unsupported platforms
meta: end_play
when: ansible_distribution not in ['CentOS', 'Fedora', 'Debian', 'Ubuntu']
- name: Include OS-specific variables
include_vars: '{{ ansible_os_family }}.yml'
when: ansible_os_family in ['Debian', 'RedHat']
- name: Set Rundeck base dir
set_fact:
rdeck_base: /home/rundeck
- name: Install OpenJDK
package:
name: "{{ openjdk_pkg }}"
state: present
- name: Install Rundeck
shell: |
mkdir -p $RDECK_BASE;
curl -k -o $RDECK_BASE/rundeck.war -L '{{ rundeck_war_url }}';
curl -k -o $RDECK_BASE/rundeck-cli.jar -L '{{ rundeck_cli_url }}'
cd $RDECK_BASE;
java -Xmx4g -jar rundeck.war &
environment:
RDECK_BASE: "{{ rdeck_base }}"
- name: Wait for Rundeck port 4440
wait_for:
host: localhost
port: 4440

View file

@ -0,0 +1 @@
openjdk_pkg: openjdk-8-jre-headless

View file

@ -0,0 +1 @@
openjdk_pkg: java-1.8.0-openjdk