qontract-reconcile 0.10.2.dev184__py3-none-any.whl → 0.10.2.dev186__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,126 +0,0 @@
1
- import logging
2
-
3
- import reconcile.gql_definitions.acs.acs_policies as gql_acs_policies
4
- from reconcile.gql_definitions.jira.jira_servers import (
5
- JiraServerV1,
6
- )
7
- from reconcile.gql_definitions.jira.jira_servers import (
8
- query as query_jira_servers,
9
- )
10
- from reconcile.utils import gql
11
- from reconcile.utils.acs.notifiers import (
12
- AcsNotifiersApi,
13
- JiraCredentials,
14
- JiraNotifier,
15
- )
16
- from reconcile.utils.differ import diff_iterables
17
- from reconcile.utils.disabled_integrations import integration_is_enabled
18
- from reconcile.utils.runtime.integration import (
19
- NoParams,
20
- QontractReconcileIntegration,
21
- )
22
- from reconcile.utils.semver_helper import make_semver
23
-
24
-
25
- class AcsNotifiersIntegration(QontractReconcileIntegration[NoParams]):
26
- def __init__(self) -> None:
27
- super().__init__(NoParams())
28
- self.qontract_integration = "acs-notifiers"
29
- self.qontract_integration_version = make_semver(0, 1, 0)
30
-
31
- @property
32
- def name(self) -> str:
33
- return self.qontract_integration
34
-
35
- def _get_escalation_policies(
36
- self, acs_policies: list[gql_acs_policies.AcsPolicyV1]
37
- ) -> list[gql_acs_policies.AppEscalationPolicyV1]:
38
- return list(
39
- {
40
- p.integrations.notifiers.jira.escalation_policy.name: p.integrations.notifiers.jira.escalation_policy
41
- for p in acs_policies
42
- if p.integrations
43
- and p.integrations.notifiers
44
- and p.integrations.notifiers.jira
45
- and integration_is_enabled(
46
- self.qontract_integration,
47
- p.integrations.notifiers.jira.escalation_policy.channels.jira_board[
48
- 0
49
- ],
50
- )
51
- }.values()
52
- )
53
-
54
- def get_desired_state(
55
- self, acs_policies: list[gql_acs_policies.AcsPolicyV1]
56
- ) -> list[JiraNotifier]:
57
- return [
58
- JiraNotifier.from_escalation_policy(ep)
59
- for ep in self._get_escalation_policies(acs_policies)
60
- ]
61
-
62
- def get_jira_credentials(
63
- self, jira_servers: list[JiraServerV1]
64
- ) -> dict[str, JiraCredentials]:
65
- return {
66
- server.server_url: JiraCredentials(
67
- url=server.server_url,
68
- username=server.username,
69
- token=self.secret_reader.read_secret(server.token),
70
- )
71
- for server in jira_servers
72
- }
73
-
74
- def reconcile(
75
- self,
76
- current_state: list[JiraNotifier],
77
- desired_state: list[JiraNotifier],
78
- acs_api: AcsNotifiersApi,
79
- jira_credentials: dict[str, JiraCredentials],
80
- dry_run: bool,
81
- ) -> None:
82
- diff = diff_iterables(
83
- current=current_state, desired=desired_state, key=lambda x: x.name
84
- )
85
- for a in diff.add.values():
86
- logging.info(f"Create Jira notifier: {a.name}")
87
- if not dry_run:
88
- acs_api.create_jira_notifier(
89
- a,
90
- jira_credentials=jira_credentials[a.url],
91
- )
92
- for c in diff.change.values():
93
- logging.info(f"Update Jira notifier: {c.desired.name}")
94
- if not dry_run:
95
- acs_api.update_jira_notifier(
96
- c.desired,
97
- jira_credentials=jira_credentials[c.desired.url],
98
- )
99
- for d in diff.delete.values():
100
- logging.info(f"Delete Jira notifier: {d.name}")
101
- if not dry_run:
102
- acs_api.delete_jira_notifier(d)
103
-
104
- def run(
105
- self,
106
- dry_run: bool,
107
- ) -> None:
108
- gql_api_query = gql.get_api().query
109
- jira_credentials = self.get_jira_credentials(
110
- query_jira_servers(query_func=gql_api_query).jira_servers or []
111
- )
112
- desired_state = self.get_desired_state(
113
- gql_acs_policies.query(query_func=gql_api_query).acs_policies or []
114
- )
115
- instance = AcsNotifiersApi.get_acs_instance(query_func=gql_api_query)
116
- with AcsNotifiersApi(
117
- url=instance.url, token=self.secret_reader.read_secret(instance.credentials)
118
- ) as acs_api:
119
- current_state = acs_api.get_jira_notifiers()
120
- self.reconcile(
121
- current_state=current_state,
122
- desired_state=desired_state,
123
- acs_api=acs_api,
124
- jira_credentials=jira_credentials,
125
- dry_run=dry_run,
126
- )
@@ -1,145 +0,0 @@
1
- import json
2
- from typing import Any
3
-
4
- from pydantic import BaseModel
5
-
6
- from reconcile.gql_definitions.acs.acs_policies import AppEscalationPolicyV1
7
- from reconcile.utils.acs.base import AcsBaseApi
8
-
9
-
10
- class JiraCredentials(BaseModel):
11
- url: str
12
- username: str
13
- token: str
14
-
15
-
16
- class SeverityPriorityMapping(BaseModel):
17
- severity: str
18
- priority: str
19
-
20
- @staticmethod
21
- def from_api(mapping: dict[str, str]) -> "SeverityPriorityMapping":
22
- return SeverityPriorityMapping(
23
- severity=mapping["severity"].replace("_SEVERITY", "").lower(),
24
- priority=mapping["priorityName"],
25
- )
26
-
27
- def to_api(self) -> Any:
28
- return {
29
- "severity": f"{self.severity.upper()}_SEVERITY",
30
- "priorityName": self.priority,
31
- }
32
-
33
-
34
- class JiraNotifier(BaseModel):
35
- name: str
36
- board: str
37
- url: str
38
- issue_type: str | None
39
- severity_priority_mappings: list[SeverityPriorityMapping]
40
- custom_fields: dict[str, Any] | None
41
-
42
- @staticmethod
43
- def from_api(notifier: dict[str, Any]) -> "JiraNotifier":
44
- notifier_jira = notifier["jira"]
45
- return JiraNotifier(
46
- name=notifier["name"],
47
- board=notifier["labelDefault"],
48
- url=notifier_jira["url"],
49
- issue_type=notifier_jira["issueType"],
50
- severity_priority_mappings=sorted(
51
- [
52
- SeverityPriorityMapping.from_api(mapping)
53
- for mapping in notifier_jira["priorityMappings"]
54
- ],
55
- key=lambda m: m.severity,
56
- ),
57
- custom_fields=json.loads(notifier_jira.get("defaultFieldsJson") or "{}"),
58
- )
59
-
60
- def to_api(self, ui_endpoint: str, jira_credentials: JiraCredentials) -> Any:
61
- return {
62
- "name": self.name,
63
- "type": "jira",
64
- "uiEndpoint": ui_endpoint,
65
- "labelDefault": self.board,
66
- "jira": {
67
- "url": jira_credentials.url,
68
- "username": jira_credentials.username,
69
- "password": jira_credentials.token,
70
- "issueType": self.issue_type or "Task",
71
- "priorityMappings": [
72
- mapping.to_api() for mapping in self.severity_priority_mappings
73
- ],
74
- "defaultFieldsJson": json.dumps(self.custom_fields or {}),
75
- },
76
- }
77
-
78
- @staticmethod
79
- def from_escalation_policy(
80
- escalation_policy: AppEscalationPolicyV1,
81
- ) -> "JiraNotifier":
82
- jira_board = escalation_policy.channels.jira_board[0]
83
-
84
- custom_fields: dict[str, Any] = {}
85
- for field in jira_board.issue_fields or []:
86
- if field.name == "Security Level":
87
- custom_fields["security"] = {"name": field.value}
88
-
89
- if escalation_policy.channels.jira_component:
90
- custom_fields["components"] = [
91
- {"name": escalation_policy.channels.jira_component}
92
- ]
93
- if escalation_policy.channels.jira_labels:
94
- custom_fields["labels"] = escalation_policy.channels.jira_labels
95
-
96
- return JiraNotifier(
97
- name=f"jira-{escalation_policy.name}",
98
- board=jira_board.name,
99
- url=jira_board.server.server_url,
100
- issue_type=jira_board.issue_type or "Task",
101
- severity_priority_mappings=sorted(
102
- [
103
- SeverityPriorityMapping(**vars(sp))
104
- for sp in jira_board.severity_priority_mappings.mappings
105
- ],
106
- key=lambda m: m.severity,
107
- ),
108
- custom_fields=custom_fields,
109
- )
110
-
111
-
112
- class AcsNotifiersApi(AcsBaseApi):
113
- """
114
- Implements methods to support reconcile operations against the ACS NotifiersService api
115
- """
116
-
117
- def get_notifiers(self) -> list[Any]:
118
- return self.generic_request_json("/v1/notifiers", "GET")["notifiers"]
119
-
120
- def get_jira_notifiers(self) -> list[JiraNotifier]:
121
- return [
122
- JiraNotifier.from_api(notifier)
123
- for notifier in self.get_notifiers()
124
- if notifier["type"] == "jira"
125
- ]
126
-
127
- def get_notifier_id_by_name(self, name: str) -> str:
128
- return next(n["id"] for n in self.get_notifiers() if n["name"] == name)
129
-
130
- def update_jira_notifier(
131
- self, jira_notifier: JiraNotifier, jira_credentials: JiraCredentials
132
- ) -> None:
133
- notifier_id = self.get_notifier_id_by_name(jira_notifier.name)
134
- body = jira_notifier.to_api(self.url, jira_credentials)
135
- self.generic_request(f"/v1/notifiers/{notifier_id}", "PUT", body)
136
-
137
- def create_jira_notifier(
138
- self, jira_notifier: JiraNotifier, jira_credentials: JiraCredentials
139
- ) -> None:
140
- body = jira_notifier.to_api(self.url, jira_credentials)
141
- self.generic_request("/v1/notifiers", "POST", body)
142
-
143
- def delete_jira_notifier(self, jira_notifier: JiraNotifier) -> None:
144
- notifier_id = self.get_notifier_id_by_name(jira_notifier.name)
145
- self.generic_request(f"/v1/notifiers/{notifier_id}", "DELETE")