Skip to content

Commit 6bd6340

Browse files
committed
Initial commit
0 parents  commit 6bd6340

File tree

6 files changed

+312
-0
lines changed

6 files changed

+312
-0
lines changed

.github/workflows/update-semver.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Update Semver
2+
on:
3+
push:
4+
branches-ignore:
5+
- '**'
6+
tags:
7+
- 'v*.*.*'
8+
jobs:
9+
update-semver:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: haya14busa/action-update-semver@v1

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
venv

README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# it-ae-actions-servicenow
2+
3+
This composite action is used to modify a Service Now request
4+
5+
## Example usages
6+
7+
- Add a comment
8+
```yaml
9+
steps:
10+
- name: Update Service Now Request
11+
uses: tamu-edu/[email protected]
12+
with:
13+
sn-base-url: ${{ vars.SN_BASE_URL }}
14+
sn-username: ${{ secrets.SN_USERNAME }}
15+
sn-password: ${{ secrets.SN_PASSWORD }}
16+
action-version: v1.0
17+
sn-request-id: 99e15216db4fb114c02e6909139619d2
18+
sn-action: add_comment
19+
sn-input1: My comment
20+
github-token: ${{ secrets.GITHUB_TOKEN }}
21+
```
22+
23+
- Add a work note
24+
```yaml
25+
steps:
26+
- name: Update Service Now Request
27+
uses: tamu-edu/[email protected]
28+
with:
29+
sn-base-url: ${{ vars.SN_BASE_URL }}
30+
sn-username: ${{ secrets.SN_USERNAME }}
31+
sn-password: ${{ secrets.SN_PASSWORD }}
32+
action-version: v1.0
33+
sn-request-id: 99e15216db4fb114c02e6909139619d2
34+
sn-action: add_work_notes
35+
sn-input1: My work note
36+
github-token: ${{ secrets.GITHUB_TOKEN }}
37+
```
38+
39+
- Close a Request
40+
```yaml
41+
steps:
42+
- name: Update Service Now Request
43+
uses: tamu-edu/[email protected]
44+
with:
45+
sn-base-url: ${{ vars.SN_BASE_URL }}
46+
sn-username: ${{ secrets.SN_USERNAME }}
47+
sn-password: ${{ secrets.SN_PASSWORD }}
48+
action-version: v1.0
49+
sn-request-id: 99e15216db4fb114c02e6909139619d2
50+
sn-action: close_request
51+
sn-input1: ""
52+
github-token: ${{ secrets.GITHUB_TOKEN }}
53+
```
54+
55+
- Update a Request variable called 'resource_url':
56+
```yaml
57+
steps:
58+
- name: Update Service Now Request
59+
uses: tamu-edu/[email protected]
60+
with:
61+
sn-base-url: ${{ vars.SN_BASE_URL }}
62+
sn-username: ${{ secrets.SN_USERNAME }}
63+
sn-password: ${{ secrets.SN_PASSWORD }}
64+
action-version: v1.0
65+
sn-request-id: 99e15216db4fb114c02e6909139619d2
66+
sn-action: update_request_variable
67+
sn-input1: resource_url
68+
sn-input2: Testing composite action 2
69+
github-token: ${{ secrets.GITHUB_TOKEN }}
70+
```

action.yaml

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
name: TDx Request Management
2+
description: Modifies TDx Requests
3+
inputs:
4+
action-version:
5+
type: string
6+
title: Action Version
7+
description: The version of the action to use
8+
required: true
9+
github-token:
10+
type: string
11+
title: GitHub Token
12+
description: The GitHub token to use for authentication
13+
required: true
14+
tdx-base-url:
15+
type: string
16+
title: TDx Base URL
17+
description: The base URL of the TDx instance
18+
required: true
19+
tdx-account_id:
20+
type: string
21+
title: TDx Account ID
22+
description: The username to use for authentication
23+
required: true
24+
tdx-secret:
25+
type: string
26+
title: TDx Secret
27+
description: The password to use for authentication
28+
required: true
29+
tdx-request-id:
30+
type: string
31+
title: TDx Request ID
32+
description: The ID of the TDx request to modify
33+
required: true
34+
tdx-action:
35+
type: string
36+
title: TDx Action
37+
description: The action to perform on the TDx request
38+
required: true
39+
enum:
40+
- add_comment_and_notify
41+
- close_request
42+
- update_request_variable_and_close_request
43+
44+
# Usage:
45+
# The inputs to use for the TDx action. The inputs are
46+
# different for each action. Use the following as a guide -
47+
# * add_comment_and_notify - `my comment`
48+
# * close_request - ``
49+
# * update_request_variable_and_close_request - `my_variable` and `my value`
50+
51+
tdx-input1:
52+
type: string
53+
title: TDx Input 1
54+
description: The first input to the TDx action
55+
required: true
56+
tdx-input2:
57+
type: string
58+
title: TDx Input 2
59+
description: The second input to the TDx action (optional)
60+
required: false
61+
62+
outputs:
63+
output:
64+
description: Output from the TDx action script
65+
value: ${{ steps.run-tdx-action.outputs.output }}
66+
67+
runs:
68+
using: composite
69+
steps:
70+
- name: Checkout actions repo
71+
uses: actions/checkout@v4
72+
with:
73+
repository: tamu-edu/it-ae-actions-tdx
74+
path: action
75+
ref: ${{ inputs.action-version }}
76+
token: ${{ inputs.github-token }}
77+
78+
- name: Install python
79+
uses: actions/setup-python@v4
80+
with:
81+
python-version: '3.12'
82+
- name: Install python dependencies
83+
shell: bash
84+
run: pip install -r ./action/python/requirements.txt
85+
86+
- name: run-tdx-action
87+
shell: bash
88+
env:
89+
TDX_BASE_URL: ${{ inputs.tdx-base-url }}
90+
TDX_ACCOUNT_ID: ${{ inputs.tdx-account_id }}
91+
TDX_SECRET: ${{ inputs.tdx-secret }}
92+
run: |
93+
ARGS="--request_id ${{ inputs.tdx-request-id }}"
94+
if [[ "${{ inputs.tdx-action }}" == "add_comment_and_notify" ]]; then
95+
ARGS="${ARGS} add_comment_and_notify --comment \"${{ inputs.tdx-input1 }}\""
96+
elif [[ "${{ inputs.tdx-action }}" == "update_request_variable_and_close_request" ]]; then
97+
ARGS="${ARGS} update_request_variable_and_close_request --variable_name ${{ inputs.tdx-input1 }} --variable_value \"${{ inputs.tdx-input2 }}\""
98+
elif [[ "${{ inputs.tdx-action }}" == "close_request" ]]; then
99+
ARGS="${ARGS} close_request --close"
100+
else
101+
echo "Invalid action: '${{ inputs.tdx-action }}'"
102+
exit 1
103+
fi
104+
105+
echo "ARGS: ${ARGS}"
106+
107+
eval python ./action/python/tdx_updater.py ${ARGS} 2>&1 | tee /tmp/output.txt
108+
echo "output<<EOF" >> $GITHUB_OUTPUT
109+
cat /tmp/output.txt >> $GITHUB_OUTPUT
110+
echo "EOF" >> $GITHUB_OUTPUT
111+

python/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
requests

python/tdx_updater.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import argparse
2+
import os
3+
from pprint import pprint
4+
import requests
5+
6+
import logging
7+
import http.client
8+
9+
logging.basicConfig(level=logging.DEBUG)
10+
11+
httpclient_logger = logging.getLogger("http.client")
12+
13+
def httpclient_logging_patch(level=logging.DEBUG):
14+
"""Enable HTTPConnection debug logging to the logging framework"""
15+
16+
def httpclient_log(*args):
17+
httpclient_logger.log(level, " ".join(args))
18+
19+
# mask the print() built-in in the http.client module to use
20+
# logging instead
21+
http.client.print = httpclient_log
22+
# enable debugging
23+
http.client.HTTPConnection.debuglevel = 1
24+
25+
httpclient_logging_patch()
26+
27+
28+
class TDxUpdater:
29+
def __init__(self, base_url: str, account_id: str, secret: str, flow_id: str) -> None:
30+
self._base_url = base_url
31+
self._account_id = account_id
32+
self._secret = secret
33+
self._flow_id = flow_id
34+
35+
def _get_auth_header(self) -> dict:
36+
return {
37+
"X-TdxiPaaS-AccountId": self._account_id,
38+
"X-TdxiPaaS-Secret": self._secret,
39+
}
40+
41+
def _get_flow_url(self) -> str:
42+
return f"{self._base_url}/start/{self._flow_id}"
43+
44+
def add_request_comment(self, request_id: str, comment: str) -> None:
45+
pass
46+
47+
def close_request(
48+
self, request_id: str, variable_name: str = None, variable_value: str = None
49+
) -> None:
50+
data = {"ticket_number": int(request_id)}
51+
if variable_name and variable_value:
52+
data[variable_name] = variable_value
53+
r = requests.post(headers=self._get_auth_header(), json=data, url=self._get_flow_url())
54+
55+
if r.status_code != 200:
56+
raise ValueError(f"Failed to close request: {r.status_code}: {r.reason} ({r.text})")
57+
else:
58+
print(f"Request {request_id} closed successfully")
59+
60+
61+
def main():
62+
63+
assert "TDX_BASE_URL" in os.environ, "TDX_BASE_URL not set (format: https://us1.teamdynamix.com/tdapp/app/flow/api/v1)"
64+
assert "TDX_ACCOUNT_ID" in os.environ, "TDX_ACCOUNT_ID not set (format: c4a4f617-0510-4dcb-af07-5ae296c858d0)"
65+
assert "TDX_SECRET" in os.environ, "TDX_SECRET not set"
66+
67+
parser = argparse.ArgumentParser()
68+
69+
parser.add_argument("--request_id", help="ServiceNow request ID", required=True)
70+
parser.add_argument("--flow_id", help="Flow ID", required=True)
71+
subparsers = parser.add_subparsers(help="Action to perform")
72+
group_comment_and_notify = subparsers.add_parser(
73+
"add_comment_and_notify", help="Add comment to request and notify user"
74+
)
75+
group_comment_and_notify.add_argument(
76+
"--comment", help="Comment to add to request", required=False
77+
)
78+
group_update_variable_and_close = subparsers.add_parser(
79+
"update_request_variable_and_close_request",
80+
help="Update request variable and close request",
81+
)
82+
group_update_variable_and_close.add_argument(
83+
"--variable_name", help="Variable name to update", required=True
84+
)
85+
group_update_variable_and_close.add_argument(
86+
"--variable_value", help="Variable value to update", required=True
87+
)
88+
89+
group_close_request = subparsers.add_parser("close_request", help="Close request")
90+
group_close_request.add_argument(
91+
"--close", help="Close request", action="store_true"
92+
)
93+
94+
args = parser.parse_args()
95+
96+
tdx_updater = TDxUpdater(
97+
base_url=os.environ["TDX_BASE_URL"],
98+
account_id=os.environ["TDX_ACCOUNT_ID"],
99+
secret=os.environ["TDX_SECRET"],
100+
flow_id=args.flow_id
101+
)
102+
103+
if "add_comment_and_notify" in args:
104+
tdx_updater.add_request_comment(args.request_id, args.comment)
105+
elif "variable_name" in args and "variable_value" in args:
106+
tdx_updater.close_request(
107+
args.request_id, args.variable_name, args.variable_value
108+
)
109+
elif "close" in args:
110+
tdx_updater.close_request(args.request_id)
111+
else:
112+
raise ValueError("No action specified")
113+
114+
115+
if __name__ == "__main__":
116+
main()

0 commit comments

Comments
 (0)