Skip to content

Commit c7dc409

Browse files
authored
Merge pull request #1 from viveksyngh/add_cert_config
Add cert config
2 parents 8e076aa + 6059581 commit c7dc409

5 files changed

Lines changed: 232 additions & 190 deletions

File tree

actions/lib/base.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from jira import JIRA
22

33
# from st2common.runners.base_action import Action
4-
__all__ = [
5-
'BaseJiraAction'
6-
]
4+
__all__ = ["BaseJiraAction"]
75

86

97
class Action(object):
@@ -19,37 +17,48 @@ def __init__(self, config):
1917
def _get_client(self):
2018
config = self.config
2119

22-
options = {'server': config['url'], 'verify': config['verify']}
20+
options = {"server": config["url"], "verify": config["verify"]}
2321

24-
auth_method = config['auth_method']
22+
# Getting client cert configuration
23+
cert_file_path = config["client_cert_file"]
24+
key_file_path = config["client_key_file"]
25+
if cert_file_path and key_file_path:
26+
options["client_cert"] = (cert_file_path, key_file_path)
2527

26-
if auth_method == 'oauth':
27-
rsa_cert_file = config['rsa_cert_file']
28+
auth_method = config["auth_method"]
29+
30+
if auth_method == "oauth":
31+
rsa_cert_file = config["rsa_cert_file"]
2832
rsa_key_content = self._get_file_content(file_path=rsa_cert_file)
2933

3034
oauth_creds = {
31-
'access_token': config['oauth_token'],
32-
'access_token_secret': config['oauth_secret'],
33-
'consumer_key': config['consumer_key'],
34-
'key_cert': rsa_key_content
35+
"access_token": config["oauth_token"],
36+
"access_token_secret": config["oauth_secret"],
37+
"consumer_key": config["consumer_key"],
38+
"key_cert": rsa_key_content,
3539
}
3640

3741
client = JIRA(options=options, oauth=oauth_creds)
3842

39-
elif auth_method == 'basic':
40-
basic_creds = (config['username'], config['password'])
41-
client = JIRA(options=options, basic_auth=basic_creds,
42-
validate=config.get('validate', False))
43+
elif auth_method == "basic":
44+
basic_creds = (config["username"], config["password"])
45+
client = JIRA(
46+
options=options,
47+
basic_auth=basic_creds,
48+
validate=config.get("validate", False),
49+
)
4350

4451
else:
45-
msg = ('You must set auth_method to either "oauth"',
46-
'or "basic" your jira.yaml config file.')
52+
msg = (
53+
'You must set auth_method to either "oauth"',
54+
'or "basic" your jira.yaml config file.',
55+
)
4756
raise Exception(msg)
4857

4958
return client
5059

5160
def _get_file_content(self, file_path):
52-
with open(file_path, 'r') as fp:
61+
with open(file_path, "r") as fp:
5362
content = fp.read()
5463

5564
return content

config.schema.yaml

Lines changed: 74 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,75 @@
11
---
2-
url:
3-
description: "URL of the JIRA instance (e.g. ``https://myproject.atlassian.net``)"
4-
type: "string"
5-
secret: false
6-
required: true
7-
verify:
8-
description: "Verify SSL certificate. Set to False to disable verification. Default True"
9-
type: boolean
10-
default: True
11-
auth_method:
12-
description: "Authentication method to use - oauth or basic"
13-
type: "string"
14-
secret: false
15-
required: true
16-
default: "oauth"
17-
enum:
18-
- oauth
19-
- basic
20-
username:
21-
description: "Username if using the basic auth_method"
22-
type: "string"
23-
secret: false
24-
required: false
25-
password:
26-
description: "Password if using the basic auth_method"
27-
type: "string"
28-
secret: true
29-
required: false
30-
rsa_cert_file:
31-
description: "Path to a private key file, e.g. /home/vagrant/jira.pem"
32-
type: "string"
33-
secret: false
34-
required: false
35-
oauth_token:
36-
description: "OAuth token"
37-
type: "string"
38-
secret: true
39-
required: false
40-
oauth_secret:
41-
description: "OAuth secret"
42-
type: "string"
43-
secret: true
44-
required: false
45-
consumer_key:
46-
description: "Consumer key"
47-
type: "string"
48-
secret: true
49-
required: false
50-
poll_interval:
51-
description: "Polling interval - default 30s"
52-
type: "integer"
53-
secret: false
54-
required: false
55-
default: 30
56-
project:
57-
description: "Project to be used as default for actions that don't require or allow a project"
58-
type: "string"
59-
secret: false
60-
required: true
61-
validate:
62-
description: "If true it will validate your credentials first."
63-
type: boolean
64-
default: false
65-
required: false
2+
url:
3+
description: "URL of the JIRA instance (e.g. ``https://myproject.atlassian.net``)"
4+
type: "string"
5+
secret: false
6+
required: true
7+
verify:
8+
description: "Verify SSL certificate. Set to False to disable verification. Default True"
9+
type: boolean
10+
default: True
11+
auth_method:
12+
description: "Authentication method to use - oauth or basic"
13+
type: "string"
14+
secret: false
15+
required: true
16+
default: "oauth"
17+
enum:
18+
- oauth
19+
- basic
20+
username:
21+
description: "Username if using the basic auth_method"
22+
type: "string"
23+
secret: false
24+
required: false
25+
password:
26+
description: "Password if using the basic auth_method"
27+
type: "string"
28+
secret: true
29+
required: false
30+
rsa_cert_file:
31+
description: "Path to a private key file, e.g. /home/vagrant/jira.pem"
32+
type: "string"
33+
secret: false
34+
required: false
35+
oauth_token:
36+
description: "OAuth token"
37+
type: "string"
38+
secret: true
39+
required: false
40+
oauth_secret:
41+
description: "OAuth secret"
42+
type: "string"
43+
secret: true
44+
required: false
45+
consumer_key:
46+
description: "Consumer key"
47+
type: "string"
48+
secret: true
49+
required: false
50+
poll_interval:
51+
description: "Polling interval - default 30s"
52+
type: "integer"
53+
secret: false
54+
required: false
55+
default: 30
56+
project:
57+
description: "Project to be used as default for actions that don't require or allow a project"
58+
type: "string"
59+
secret: false
60+
required: true
61+
validate:
62+
description: "If true it will validate your credentials first."
63+
type: boolean
64+
default: false
65+
required: false
66+
client_cert_file:
67+
description: "Path to a client cert file, e.g. /home/jiracerts/username.cer"
68+
type: "string"
69+
secret: false
70+
required: false
71+
client_key_file:
72+
description: "Path to a client key file, e.g. /home/jiracerts/username.key"
73+
type: "string"
74+
secret: false
75+
required: false

sensors/jira_sensor.py

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,73 +7,83 @@
77

88

99
class JIRASensor(PollingSensor):
10-
'''
10+
"""
1111
Sensor will monitor for any new projects created in JIRA and
1212
emit trigger instance when one is created.
13-
'''
13+
"""
14+
1415
def __init__(self, sensor_service, config=None, poll_interval=5):
15-
super(JIRASensor, self).__init__(sensor_service=sensor_service,
16-
config=config,
17-
poll_interval=poll_interval)
16+
super(JIRASensor, self).__init__(
17+
sensor_service=sensor_service, config=config, poll_interval=poll_interval
18+
)
1819

1920
self._jira_url = None
2021
# The Consumer Key created while setting up the "Incoming Authentication" in
2122
# JIRA for the Application Link.
22-
self._consumer_key = u''
23+
self._consumer_key = u""
2324
self._rsa_key = None
2425
self._jira_client = None
25-
self._access_token = u''
26-
self._access_secret = u''
26+
self._access_token = u""
27+
self._access_secret = u""
2728
self._projects_available = None
2829
self._poll_interval = 30
2930
self._project = None
3031
self._issues_in_project = None
3132
self._jql_query = None
32-
self._trigger_name = 'issues_tracker'
33-
self._trigger_pack = 'jira'
34-
self._trigger_ref = '.'.join([self._trigger_pack, self._trigger_name])
33+
self._trigger_name = "issues_tracker"
34+
self._trigger_pack = "jira"
35+
self._trigger_ref = ".".join([self._trigger_pack, self._trigger_name])
3536

3637
def _read_cert(self, file_path):
3738
with open(file_path) as f:
3839
return f.read()
3940

4041
def setup(self):
41-
self._jira_url = self._config['url']
42-
auth_method = self._config['auth_method']
43-
44-
if auth_method == 'oauth':
45-
rsa_cert_file = self._config['rsa_cert_file']
42+
self._jira_url = self._config["url"]
43+
auth_method = self._config["auth_method"]
44+
45+
options = {"server": self._config["url"], "verify": self._config["verify"]}
46+
# Getting client cert configuration
47+
cert_file_path = self._config["client_cert_file"]
48+
key_file_path = self._config["client_key_file"]
49+
if cert_file_path and key_file_path:
50+
options["client_cert"] = (cert_file_path, key_file_path)
51+
52+
if auth_method == "oauth":
53+
rsa_cert_file = self._config["rsa_cert_file"]
4654
if not os.path.exists(rsa_cert_file):
47-
raise Exception('Cert file for JIRA OAuth not found at %s.' % rsa_cert_file)
55+
raise Exception(
56+
"Cert file for JIRA OAuth not found at %s." % rsa_cert_file
57+
)
4858
self._rsa_key = self._read_cert(rsa_cert_file)
49-
self._poll_interval = self._config.get('poll_interval', self._poll_interval)
59+
self._poll_interval = self._config.get("poll_interval", self._poll_interval)
5060
oauth_creds = {
51-
'access_token': self._config['oauth_token'],
52-
'access_token_secret': self._config['oauth_secret'],
53-
'consumer_key': self._config['consumer_key'],
54-
'key_cert': self._rsa_key
61+
"access_token": self._config["oauth_token"],
62+
"access_token_secret": self._config["oauth_secret"],
63+
"consumer_key": self._config["consumer_key"],
64+
"key_cert": self._rsa_key,
5565
}
5666

57-
self._jira_client = JIRA(options={'server': self._jira_url},
58-
oauth=oauth_creds)
59-
elif auth_method == 'basic':
60-
basic_creds = (self._config['username'], self._config['password'])
61-
self._jira_client = JIRA(options={'server': self._jira_url},
62-
basic_auth=basic_creds)
67+
self._jira_client = JIRA(options=options, oauth=oauth_creds)
68+
elif auth_method == "basic":
69+
basic_creds = (self._config["username"], self._config["password"])
70+
self._jira_client = JIRA(options=options, basic_auth=basic_creds)
6371

6472
else:
65-
msg = ('You must set auth_method to either "oauth"',
66-
'or "basic" your jira.yaml config file.')
73+
msg = (
74+
'You must set auth_method to either "oauth"',
75+
'or "basic" your jira.yaml config file.',
76+
)
6777
raise Exception(msg)
6878

6979
if self._projects_available is None:
7080
self._projects_available = set()
7181
for proj in self._jira_client.projects():
7282
self._projects_available.add(proj.key)
73-
self._project = self._config.get('project', None)
83+
self._project = self._config.get("project", None)
7484
if not self._project or self._project not in self._projects_available:
75-
raise Exception('Invalid project (%s) to track.' % self._project)
76-
self._jql_query = 'project=%s' % self._project
85+
raise Exception("Invalid project (%s) to track." % self._project)
86+
self._jql_query = "project=%s" % self._project
7787
all_issues = self._jira_client.search_issues(self._jql_query, maxResults=None)
7888
self._issues_in_project = {issue.key: issue for issue in all_issues}
7989

@@ -93,7 +103,9 @@ def remove_trigger(self, trigger):
93103
pass
94104

95105
def _detect_new_issues(self):
96-
new_issues = self._jira_client.search_issues(self._jql_query, maxResults=50, startAt=0)
106+
new_issues = self._jira_client.search_issues(
107+
self._jql_query, maxResults=50, startAt=0
108+
)
97109

98110
for issue in new_issues:
99111
if issue.key not in self._issues_in_project:
@@ -103,12 +115,12 @@ def _detect_new_issues(self):
103115
def _dispatch_issues_trigger(self, issue):
104116
trigger = self._trigger_ref
105117
payload = {}
106-
payload['issue_name'] = issue.key
107-
payload['issue_url'] = issue.self
108-
payload['issue_browse_url'] = self._jira_url + '/browse/' + issue.key
109-
payload['project'] = self._project
110-
payload['created'] = issue.raw['fields']['created']
111-
payload['assignee'] = issue.raw['fields']['assignee']
112-
payload['fix_versions'] = issue.raw['fields']['fixVersions']
113-
payload['issue_type'] = issue.raw['fields']['issuetype']['name']
118+
payload["issue_name"] = issue.key
119+
payload["issue_url"] = issue.self
120+
payload["issue_browse_url"] = self._jira_url + "/browse/" + issue.key
121+
payload["project"] = self._project
122+
payload["created"] = issue.raw["fields"]["created"]
123+
payload["assignee"] = issue.raw["fields"]["assignee"]
124+
payload["fix_versions"] = issue.raw["fields"]["fixVersions"]
125+
payload["issue_type"] = issue.raw["fields"]["issuetype"]["name"]
114126
self._sensor_service.dispatch(trigger, payload)

0 commit comments

Comments
 (0)