saltext.github 1.1.0__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.
- saltext/github/__init__.py +31 -0
- saltext/github/modules/__init__.py +0 -0
- saltext/github/modules/github.py +1873 -0
- saltext/github/modules/github_org.py +667 -0
- saltext/github/modules/github_repo.py +1658 -0
- saltext/github/modules/github_user.py +75 -0
- saltext/github/resources/__init__.py +0 -0
- saltext/github/resources/github/__init__.py +251 -0
- saltext/github/resources/github/modules/__init__.py +0 -0
- saltext/github/resources/github/modules/actions.py +175 -0
- saltext/github/resources/github/modules/config.py +69 -0
- saltext/github/resources/github/modules/deploy_key.py +122 -0
- saltext/github/resources/github/modules/environment.py +241 -0
- saltext/github/resources/github/modules/grains.py +18 -0
- saltext/github/resources/github/modules/issue.py +157 -0
- saltext/github/resources/github/modules/label.py +161 -0
- saltext/github/resources/github/modules/milestone.py +103 -0
- saltext/github/resources/github/modules/pages.py +149 -0
- saltext/github/resources/github/modules/pull.py +90 -0
- saltext/github/resources/github/modules/repo.py +155 -0
- saltext/github/resources/github/modules/ruleset.py +144 -0
- saltext/github/resources/github/modules/saltutil.py +24 -0
- saltext/github/resources/github/modules/state.py +116 -0
- saltext/github/resources/github/modules/test.py +29 -0
- saltext/github/resources/github/states/__init__.py +0 -0
- saltext/github/resources/github/states/actions.py +117 -0
- saltext/github/resources/github/states/deploy_key.py +130 -0
- saltext/github/resources/github/states/environment.py +99 -0
- saltext/github/resources/github/states/label.py +71 -0
- saltext/github/resources/github/states/pages.py +92 -0
- saltext/github/resources/github/states/repo.py +108 -0
- saltext/github/resources/github/states/ruleset.py +81 -0
- saltext/github/states/__init__.py +0 -0
- saltext/github/states/github.py +966 -0
- saltext/github/states/github_org.py +369 -0
- saltext/github/states/github_repo.py +722 -0
- saltext/github/utils/__init__.py +72 -0
- saltext/github/utils/gh/__init__.py +14 -0
- saltext/github/utils/gh/actions.py +195 -0
- saltext/github/utils/gh/cache.py +126 -0
- saltext/github/utils/gh/client.py +534 -0
- saltext/github/utils/gh/deploy_keys.py +121 -0
- saltext/github/utils/gh/environments.py +271 -0
- saltext/github/utils/gh/exceptions.py +28 -0
- saltext/github/utils/gh/grains_files.py +366 -0
- saltext/github/utils/gh/issues.py +193 -0
- saltext/github/utils/gh/labels.py +142 -0
- saltext/github/utils/gh/members.py +157 -0
- saltext/github/utils/gh/milestones.py +122 -0
- saltext/github/utils/gh/pages.py +128 -0
- saltext/github/utils/gh/profile.py +458 -0
- saltext/github/utils/gh/pulls.py +99 -0
- saltext/github/utils/gh/repos.py +465 -0
- saltext/github/utils/gh/resource.py +35 -0
- saltext/github/utils/gh/rulesets.py +191 -0
- saltext/github/utils/gh/statecores/__init__.py +70 -0
- saltext/github/utils/gh/statecores/actions.py +180 -0
- saltext/github/utils/gh/statecores/deploy_keys.py +241 -0
- saltext/github/utils/gh/statecores/environments.py +212 -0
- saltext/github/utils/gh/statecores/labels.py +116 -0
- saltext/github/utils/gh/statecores/pages.py +177 -0
- saltext/github/utils/gh/statecores/repo.py +249 -0
- saltext/github/utils/gh/statecores/rulesets.py +115 -0
- saltext/github/utils/gh/teams.py +375 -0
- saltext/github/utils/gh/users.py +87 -0
- saltext/github/version.py +1 -0
- saltext_github-1.1.0.dist-info/METADATA +151 -0
- saltext_github-1.1.0.dist-info/RECORD +73 -0
- saltext_github-1.1.0.dist-info/WHEEL +5 -0
- saltext_github-1.1.0.dist-info/entry_points.txt +2 -0
- saltext_github-1.1.0.dist-info/licenses/LICENSE +201 -0
- saltext_github-1.1.0.dist-info/licenses/NOTICE +10 -0
- saltext_github-1.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Look up information about GitHub **user** accounts.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 1.1.0
|
|
5
|
+
|
|
6
|
+
:depends: PyGithub python module
|
|
7
|
+
|
|
8
|
+
Configuration
|
|
9
|
+
-------------
|
|
10
|
+
|
|
11
|
+
This module reads its configuration from profiles, which are described
|
|
12
|
+
in the :ref:`configuration guide <github-configuration>`. All functions
|
|
13
|
+
accept a ``profile`` argument, defaulting to the ``github`` profile.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
|
|
18
|
+
from saltext.github.utils.gh import profile as gh_profile
|
|
19
|
+
from saltext.github.utils.gh import users as gh_users
|
|
20
|
+
|
|
21
|
+
log = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
__virtualname__ = "github_user"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _get_conn(profile):
|
|
27
|
+
return gh_profile.get_conn(profile, opts=__opts__, context=__context__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def info(name=None, profile="github"):
|
|
31
|
+
"""
|
|
32
|
+
Return the public profile of a user account. Fails when the account
|
|
33
|
+
is an organization. Use :py:func:`github.account_info
|
|
34
|
+
<saltext.github.modules.github.account_info>` to look up accounts of
|
|
35
|
+
either type (note that it defaults to the profile's owner instead of
|
|
36
|
+
the token's user).
|
|
37
|
+
|
|
38
|
+
CLI Example:
|
|
39
|
+
|
|
40
|
+
.. code-block:: bash
|
|
41
|
+
|
|
42
|
+
salt-call github_user.info github-handle
|
|
43
|
+
salt-call github_user.info # the token's user
|
|
44
|
+
|
|
45
|
+
name
|
|
46
|
+
Login of the user to look up. Defaults to the user the
|
|
47
|
+
profile's token belongs to.
|
|
48
|
+
|
|
49
|
+
profile
|
|
50
|
+
Profile configuration name to use. Defaults to ``github``.
|
|
51
|
+
"""
|
|
52
|
+
return gh_users.get_info(_get_conn(profile), name, expect="User")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def list_keys(name=None, profile="github"):
|
|
56
|
+
"""
|
|
57
|
+
Return the verified public SSH keys of any user as a list of
|
|
58
|
+
mappings with ``id`` and ``key`` fields, e.g. for use with the
|
|
59
|
+
:py:func:`ssh_auth.present <salt.states.ssh_auth.present>` state.
|
|
60
|
+
|
|
61
|
+
CLI Example:
|
|
62
|
+
|
|
63
|
+
.. code-block:: bash
|
|
64
|
+
|
|
65
|
+
salt-call github_user.list_keys github-handle
|
|
66
|
+
salt-call github_user.list_keys # the token's user
|
|
67
|
+
|
|
68
|
+
name
|
|
69
|
+
Login of the user whose keys to list. Defaults to the user the
|
|
70
|
+
profile's token belongs to.
|
|
71
|
+
|
|
72
|
+
profile
|
|
73
|
+
Profile configuration name to use. Defaults to ``github``.
|
|
74
|
+
"""
|
|
75
|
+
return gh_users.list_keys(_get_conn(profile), name)
|
|
File without changes
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Connection module for the ``github`` resource type, which manages
|
|
3
|
+
GitHub repositories as Salt resources (requires Salt 3008.3+).
|
|
4
|
+
|
|
5
|
+
.. versionadded:: 1.1.0
|
|
6
|
+
|
|
7
|
+
Each resource is a single repository, identified by ``owner/repo``
|
|
8
|
+
(e.g. the SRN ``github:my-org/my-repo``). Jobs dispatched to a resource
|
|
9
|
+
run the per-type execution and state modules shipped in this package's
|
|
10
|
+
``modules``/``states`` directories, which operate on the targeted
|
|
11
|
+
repository implicitly.
|
|
12
|
+
|
|
13
|
+
Configuration
|
|
14
|
+
-------------
|
|
15
|
+
|
|
16
|
+
The resource type is declared in the managing minion's pillar, under
|
|
17
|
+
the subtree selected by :conf_minion:`resource_pillar_key` (default
|
|
18
|
+
``resources``)::
|
|
19
|
+
|
|
20
|
+
resources:
|
|
21
|
+
github:
|
|
22
|
+
profile: github
|
|
23
|
+
owners:
|
|
24
|
+
- my-org
|
|
25
|
+
|
|
26
|
+
The declaration keys (:ghconf:`resource:profile`, :ghconf:`resource:owners`,
|
|
27
|
+
:ghconf:`resource:repos`/:ghconf:`resource:exclude` patterns,
|
|
28
|
+
:ghconf:`resource:include_archived` and :ghconf:`resource:grains_files`
|
|
29
|
+
for custom grains sourced from in-repo YAML/JSON files) are described in
|
|
30
|
+
the :ref:`configuration guide <github-resource-configuration>`.
|
|
31
|
+
``owners`` may be a mapping, overriding any of the other declaration
|
|
32
|
+
keys per owner::
|
|
33
|
+
|
|
34
|
+
resources:
|
|
35
|
+
github:
|
|
36
|
+
owners:
|
|
37
|
+
my-github-handle:
|
|
38
|
+
exclude:
|
|
39
|
+
- not-this
|
|
40
|
+
my-org:
|
|
41
|
+
repos:
|
|
42
|
+
- foo*
|
|
43
|
+
other-org:
|
|
44
|
+
profile: other_github_org
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
import fnmatch
|
|
48
|
+
import logging
|
|
49
|
+
|
|
50
|
+
from salt.exceptions import CommandExecutionError
|
|
51
|
+
|
|
52
|
+
from saltext.github.utils.gh import grains_files as gh_grains_files
|
|
53
|
+
from saltext.github.utils.gh import profile as gh_profile
|
|
54
|
+
from saltext.github.utils.gh import repos as gh_repos
|
|
55
|
+
|
|
56
|
+
log = logging.getLogger(__name__)
|
|
57
|
+
|
|
58
|
+
__virtualname__ = "github"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def __virtual__():
|
|
62
|
+
return __virtualname__
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _resource_id():
|
|
66
|
+
"""
|
|
67
|
+
Return the ID (``owner/repo``) of the resource currently being
|
|
68
|
+
operated on.
|
|
69
|
+
"""
|
|
70
|
+
return __resource__["id"]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _split_id(resource_id):
|
|
74
|
+
"""
|
|
75
|
+
Split a resource ID into owner and repository name.
|
|
76
|
+
"""
|
|
77
|
+
owner, _, repo_name = resource_id.partition("/")
|
|
78
|
+
return owner, repo_name
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _matches(patterns, full_name, name):
|
|
82
|
+
"""
|
|
83
|
+
Report whether a repository matches any of the fnmatch patterns.
|
|
84
|
+
Patterns containing a slash match the full name (``owner/repo``),
|
|
85
|
+
others the bare repository name, both case-insensitively.
|
|
86
|
+
"""
|
|
87
|
+
for pattern in patterns:
|
|
88
|
+
target = full_name if "/" in pattern else name
|
|
89
|
+
if fnmatch.fnmatch(target.lower(), pattern.lower()):
|
|
90
|
+
return True
|
|
91
|
+
return False
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _conn(opts, owner=None):
|
|
95
|
+
"""
|
|
96
|
+
Return the connection for an owner per the resource declaration
|
|
97
|
+
(per-owner profile override or the declared default profile).
|
|
98
|
+
"""
|
|
99
|
+
return gh_profile.resource_conn(opts, __context__, owner=owner)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def init(opts):
|
|
103
|
+
"""
|
|
104
|
+
Initialize the ``github`` resource type for this minion.
|
|
105
|
+
|
|
106
|
+
Validates that all declared profiles (the default one and any
|
|
107
|
+
per-owner overrides) carry a token (without contacting the API),
|
|
108
|
+
validates any ``grains_files`` declarations and records the
|
|
109
|
+
type-level state in ``__context__``.
|
|
110
|
+
"""
|
|
111
|
+
profiles = gh_profile.resource_profiles(opts)
|
|
112
|
+
# Fail fast on unconfigured profiles; the connections themselves
|
|
113
|
+
# are established lazily on first use.
|
|
114
|
+
for profile in profiles:
|
|
115
|
+
gh_profile.get_config_value(profile, "token", opts=opts, context=__context__)
|
|
116
|
+
# Fail fast on malformed custom grains declarations.
|
|
117
|
+
decl = gh_profile.resource_decl(opts)
|
|
118
|
+
gh_grains_files.validate(decl.get("grains_files"))
|
|
119
|
+
owners = decl.get("owners")
|
|
120
|
+
if isinstance(owners, dict):
|
|
121
|
+
for settings in owners.values():
|
|
122
|
+
if isinstance(settings, dict):
|
|
123
|
+
gh_grains_files.validate(settings.get("grains_files"))
|
|
124
|
+
__context__["github_resource"] = {
|
|
125
|
+
"initialized": True,
|
|
126
|
+
"profiles": profiles,
|
|
127
|
+
}
|
|
128
|
+
log.debug("github resource init() done, profiles: %s", profiles)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def initialized():
|
|
132
|
+
"""
|
|
133
|
+
Return whether ``init()`` has been called successfully for this
|
|
134
|
+
resource type.
|
|
135
|
+
"""
|
|
136
|
+
return __context__.get("github_resource", {}).get("initialized", False)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def discover(opts):
|
|
140
|
+
"""
|
|
141
|
+
Return the ``owner/repo`` IDs of the repositories this minion
|
|
142
|
+
manages: all repositories of the declared owners, filtered by the
|
|
143
|
+
``repos``/``exclude`` patterns and the ``include_archived`` flag,
|
|
144
|
+
each of which can be overridden per owner.
|
|
145
|
+
"""
|
|
146
|
+
owners = gh_profile.resource_owners(opts) or [_conn(opts).owner]
|
|
147
|
+
|
|
148
|
+
discovered = []
|
|
149
|
+
for owner in owners:
|
|
150
|
+
include = gh_profile.resource_owner_setting(opts, owner, "repos") or ["*"]
|
|
151
|
+
exclude = gh_profile.resource_owner_setting(opts, owner, "exclude") or []
|
|
152
|
+
include_archived = gh_profile.resource_owner_setting(opts, owner, "include_archived", False)
|
|
153
|
+
conn = _conn(opts, owner)
|
|
154
|
+
for repo in gh_repos.list_all(conn, owner=owner):
|
|
155
|
+
if repo.archived and not include_archived:
|
|
156
|
+
continue
|
|
157
|
+
if not _matches(include, repo.full_name, repo.name):
|
|
158
|
+
continue
|
|
159
|
+
if _matches(exclude, repo.full_name, repo.name):
|
|
160
|
+
continue
|
|
161
|
+
discovered.append(repo.full_name)
|
|
162
|
+
log.debug("github resource discover() returning: %s", discovered)
|
|
163
|
+
return sorted(discovered)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def grains():
|
|
167
|
+
"""
|
|
168
|
+
Return the grains of the current resource: the repository's identity
|
|
169
|
+
and basic metadata, merged with any custom grains sourced from
|
|
170
|
+
in-repo files per the declaration's ``grains_files`` key.
|
|
171
|
+
"""
|
|
172
|
+
resource_id = _resource_id()
|
|
173
|
+
owner, repo_name = _split_id(resource_id)
|
|
174
|
+
conn = _conn(__opts__, owner)
|
|
175
|
+
# Warm the per-owner cache: a single listing serves the grains of
|
|
176
|
+
# all of this owner's resources within one context.
|
|
177
|
+
gh_repos.list_all(conn, owner=owner)
|
|
178
|
+
info = gh_repos.get_info(conn, repo_name, owner=owner)
|
|
179
|
+
ret = {
|
|
180
|
+
"id": resource_id,
|
|
181
|
+
"owner": info["owner"],
|
|
182
|
+
"repo": info["name"],
|
|
183
|
+
"full_name": info["full_name"],
|
|
184
|
+
"private": info["private"],
|
|
185
|
+
"visibility": info["visibility"],
|
|
186
|
+
"fork": info["fork"],
|
|
187
|
+
"archived": info["archived"],
|
|
188
|
+
"disabled": info["disabled"],
|
|
189
|
+
"is_template": info["is_template"],
|
|
190
|
+
"default_branch": info["default_branch"],
|
|
191
|
+
"language": info["language"],
|
|
192
|
+
"license": info["license"],
|
|
193
|
+
"topics": info["topics"],
|
|
194
|
+
"custom_properties": info["custom_properties"],
|
|
195
|
+
"html_url": info["html_url"],
|
|
196
|
+
"clone_url": info["clone_url"],
|
|
197
|
+
"ssh_url": info["ssh_url"],
|
|
198
|
+
"description": info["description"],
|
|
199
|
+
"homepage": info["homepage"],
|
|
200
|
+
"created_at": info["created_at"],
|
|
201
|
+
"has_discussions": info["has_discussions"],
|
|
202
|
+
"has_pages": info["has_pages"],
|
|
203
|
+
"has_projects": info["has_projects"],
|
|
204
|
+
}
|
|
205
|
+
spec = gh_profile.resource_owner_setting(__opts__, owner, "grains_files")
|
|
206
|
+
if spec:
|
|
207
|
+
# Revalidate: the pillar can have changed since init(). The
|
|
208
|
+
# identity grains must survive declaration/content problems.
|
|
209
|
+
try:
|
|
210
|
+
normalized = gh_grains_files.validate(spec)
|
|
211
|
+
except CommandExecutionError as err:
|
|
212
|
+
log.error("Invalid grains_files declaration, skipping custom grains: %s", err)
|
|
213
|
+
else:
|
|
214
|
+
custom = gh_grains_files.collect(conn, repo_name, normalized, owner=owner)
|
|
215
|
+
gh_grains_files.merge_grains(ret, custom)
|
|
216
|
+
return ret
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def grains_refresh():
|
|
220
|
+
"""
|
|
221
|
+
Return freshly fetched grains for the current resource, bypassing
|
|
222
|
+
cached repository information and file contents.
|
|
223
|
+
"""
|
|
224
|
+
owner, repo_name = _split_id(_resource_id())
|
|
225
|
+
conn = _conn(__opts__, owner)
|
|
226
|
+
gh_repos.get_info(conn, repo_name, owner=owner, ignore_cache=True)
|
|
227
|
+
gh_repos.clear_file_cache(conn, repo_name, owner=owner)
|
|
228
|
+
return grains()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def ping():
|
|
232
|
+
"""
|
|
233
|
+
Return whether the current resource's repository is reachable via
|
|
234
|
+
the API.
|
|
235
|
+
"""
|
|
236
|
+
owner, repo_name = _split_id(_resource_id())
|
|
237
|
+
try:
|
|
238
|
+
conn = _conn(__opts__, owner)
|
|
239
|
+
gh_repos.get_info(conn, repo_name, owner=owner, ignore_cache=True)
|
|
240
|
+
except CommandExecutionError as err:
|
|
241
|
+
log.debug("github resource ping() failed for %s/%s: %s", owner, repo_name, err)
|
|
242
|
+
return False
|
|
243
|
+
return True
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def shutdown(opts): # pylint: disable=unused-argument
|
|
247
|
+
"""
|
|
248
|
+
Tear down the ``github`` resource type, dropping the type-level
|
|
249
|
+
state from ``__context__``.
|
|
250
|
+
"""
|
|
251
|
+
__context__.pop("github_resource", None)
|
|
File without changes
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage the targeted repository's Actions secrets and workflow
|
|
3
|
+
permissions.
|
|
4
|
+
|
|
5
|
+
.. versionadded:: 1.1.0
|
|
6
|
+
|
|
7
|
+
Part of the :py:mod:`github <saltext.github.resources.github>` resource type: all functions operate on the
|
|
8
|
+
repository the job was dispatched to. The ``profile`` parameter
|
|
9
|
+
defaults to the :ghconf:`profile <resource:profile>` named in the resource declaration.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
from salt.utils.functools import namespaced_function
|
|
15
|
+
|
|
16
|
+
from saltext.github.utils import filter_fields
|
|
17
|
+
from saltext.github.utils.gh import actions as gh_actions
|
|
18
|
+
from saltext.github.utils.gh import resource as gh_resource
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_core_args = namespaced_function(gh_resource.core_args, globals())
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def list_secrets(*, fields=None, profile=None):
|
|
27
|
+
"""
|
|
28
|
+
List the Actions secrets of the targeted repository, as a mapping
|
|
29
|
+
of secret name to metadata. Secret values are write-only, so this
|
|
30
|
+
only returns metadata (``created_at``, ``updated_at``).
|
|
31
|
+
|
|
32
|
+
CLI Example:
|
|
33
|
+
|
|
34
|
+
.. code-block:: bash
|
|
35
|
+
|
|
36
|
+
salt 'my-org/my-repo' actions.list_secrets
|
|
37
|
+
|
|
38
|
+
fields
|
|
39
|
+
Only include these fields in the output. A single field name
|
|
40
|
+
reduces each entry to the field's value.
|
|
41
|
+
|
|
42
|
+
profile
|
|
43
|
+
Profile configuration name to use. Defaults to the resource
|
|
44
|
+
declaration's profile.
|
|
45
|
+
"""
|
|
46
|
+
conn, owner, repo_name = _core_args(profile)
|
|
47
|
+
secrets = gh_actions.list_secrets(conn, repo_name, owner=owner)
|
|
48
|
+
return filter_fields({secret["name"]: secret for secret in secrets}, fields)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_secret(name, *, profile=None):
|
|
52
|
+
"""
|
|
53
|
+
Return the metadata of a single Actions secret of the targeted
|
|
54
|
+
repository. The value itself is write-only and cannot be retrieved.
|
|
55
|
+
|
|
56
|
+
CLI Example:
|
|
57
|
+
|
|
58
|
+
.. code-block:: bash
|
|
59
|
+
|
|
60
|
+
salt 'my-org/my-repo' actions.get_secret MY_SECRET
|
|
61
|
+
|
|
62
|
+
name
|
|
63
|
+
Name of the secret.
|
|
64
|
+
|
|
65
|
+
profile
|
|
66
|
+
Profile configuration name to use. Defaults to the resource
|
|
67
|
+
declaration's profile.
|
|
68
|
+
"""
|
|
69
|
+
conn, owner, repo_name = _core_args(profile)
|
|
70
|
+
return gh_actions.get_secret(conn, repo_name, name, owner=owner)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def set_secret(name, value, *, profile=None):
|
|
74
|
+
"""
|
|
75
|
+
Create or update an Actions secret of the targeted repository. The
|
|
76
|
+
value is encrypted to the repository public key before leaving the
|
|
77
|
+
minion.
|
|
78
|
+
|
|
79
|
+
CLI Example:
|
|
80
|
+
|
|
81
|
+
.. code-block:: bash
|
|
82
|
+
|
|
83
|
+
salt 'my-org/my-repo' actions.set_secret MY_SECRET hunter2
|
|
84
|
+
|
|
85
|
+
name
|
|
86
|
+
Name of the secret.
|
|
87
|
+
|
|
88
|
+
value
|
|
89
|
+
Plaintext secret value.
|
|
90
|
+
|
|
91
|
+
profile
|
|
92
|
+
Profile configuration name to use. Defaults to the resource
|
|
93
|
+
declaration's profile.
|
|
94
|
+
"""
|
|
95
|
+
conn, owner, repo_name = _core_args(profile)
|
|
96
|
+
gh_actions.set_secret(conn, repo_name, name, value, owner=owner)
|
|
97
|
+
return True
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def remove_secret(name, *, profile=None):
|
|
101
|
+
"""
|
|
102
|
+
Remove an Actions secret from the targeted repository.
|
|
103
|
+
|
|
104
|
+
CLI Example:
|
|
105
|
+
|
|
106
|
+
.. code-block:: bash
|
|
107
|
+
|
|
108
|
+
salt 'my-org/my-repo' actions.remove_secret MY_SECRET
|
|
109
|
+
|
|
110
|
+
name
|
|
111
|
+
Name of the secret.
|
|
112
|
+
|
|
113
|
+
profile
|
|
114
|
+
Profile configuration name to use. Defaults to the resource
|
|
115
|
+
declaration's profile.
|
|
116
|
+
"""
|
|
117
|
+
conn, owner, repo_name = _core_args(profile)
|
|
118
|
+
gh_actions.delete_secret(conn, repo_name, name, owner=owner)
|
|
119
|
+
return True
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_workflow_permissions(*, profile=None):
|
|
123
|
+
"""
|
|
124
|
+
Return the default workflow permissions granted to the ``GITHUB_TOKEN``
|
|
125
|
+
in the targeted repository, a mapping with ``default_workflow_permissions``
|
|
126
|
+
(``read``/``write``) and ``can_approve_pull_request_reviews``.
|
|
127
|
+
|
|
128
|
+
CLI Example:
|
|
129
|
+
|
|
130
|
+
.. code-block:: bash
|
|
131
|
+
|
|
132
|
+
salt 'my-org/my-repo' actions.get_workflow_permissions
|
|
133
|
+
|
|
134
|
+
profile
|
|
135
|
+
Profile configuration name to use. Defaults to the resource
|
|
136
|
+
declaration's profile.
|
|
137
|
+
"""
|
|
138
|
+
conn, owner, repo_name = _core_args(profile)
|
|
139
|
+
return gh_actions.get_workflow_permissions(conn, repo_name, owner=owner)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def set_workflow_permissions(
|
|
143
|
+
*, default_workflow_permissions=None, can_approve_pull_request_reviews=None, profile=None
|
|
144
|
+
):
|
|
145
|
+
"""
|
|
146
|
+
Update the default workflow permissions granted to the ``GITHUB_TOKEN``
|
|
147
|
+
in the targeted repository.
|
|
148
|
+
|
|
149
|
+
CLI Example:
|
|
150
|
+
|
|
151
|
+
.. code-block:: bash
|
|
152
|
+
|
|
153
|
+
salt 'my-org/my-repo' actions.set_workflow_permissions \\
|
|
154
|
+
default_workflow_permissions=read can_approve_pull_request_reviews=true
|
|
155
|
+
|
|
156
|
+
default_workflow_permissions
|
|
157
|
+
Default permissions for the ``GITHUB_TOKEN``, either ``read``
|
|
158
|
+
or ``write``.
|
|
159
|
+
|
|
160
|
+
can_approve_pull_request_reviews
|
|
161
|
+
Allow GitHub Actions to approve pull requests.
|
|
162
|
+
|
|
163
|
+
profile
|
|
164
|
+
Profile configuration name to use. Defaults to the resource
|
|
165
|
+
declaration's profile.
|
|
166
|
+
"""
|
|
167
|
+
conn, owner, repo_name = _core_args(profile)
|
|
168
|
+
gh_actions.set_workflow_permissions(
|
|
169
|
+
conn,
|
|
170
|
+
repo_name,
|
|
171
|
+
default_workflow_permissions=default_workflow_permissions,
|
|
172
|
+
can_approve_pull_request_reviews=can_approve_pull_request_reviews,
|
|
173
|
+
owner=owner,
|
|
174
|
+
)
|
|
175
|
+
return True
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Look up configuration values from the managing minion.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 1.1.0
|
|
5
|
+
|
|
6
|
+
Repositories have no minion configuration of their own — GitHub
|
|
7
|
+
profiles and related settings live on the managing minion. The stock
|
|
8
|
+
:py:mod:`state <salt.modules.state>` execution module (re-exported for
|
|
9
|
+
this resource type) relies on ``config.get``/``config.option``, so this
|
|
10
|
+
override provides them: it delegates to the managing minion's loader
|
|
11
|
+
when the ``__minion__`` escape hatch is packed (state-engine context)
|
|
12
|
+
and falls back to the managing minion's opts otherwise (the minion's
|
|
13
|
+
dispatch-context per-type loaders do not pack ``__minion__``).
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
|
|
18
|
+
import salt.utils.data
|
|
19
|
+
|
|
20
|
+
log = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _minion():
|
|
24
|
+
try:
|
|
25
|
+
return __minion__
|
|
26
|
+
except NameError:
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get(key, default="", delimiter=":", omit_opts=False, **kwargs):
|
|
31
|
+
"""
|
|
32
|
+
Look up a config value on the managing minion. See
|
|
33
|
+
:py:func:`config.get <salt.modules.config.get>` for details.
|
|
34
|
+
|
|
35
|
+
CLI Example:
|
|
36
|
+
|
|
37
|
+
.. code-block:: bash
|
|
38
|
+
|
|
39
|
+
salt 'my-org/my-repo' config.get state_verbose
|
|
40
|
+
"""
|
|
41
|
+
minion = _minion()
|
|
42
|
+
if minion is not None:
|
|
43
|
+
return minion["config.get"](
|
|
44
|
+
key, default=default, delimiter=delimiter, omit_opts=omit_opts, **kwargs
|
|
45
|
+
)
|
|
46
|
+
if omit_opts:
|
|
47
|
+
return default
|
|
48
|
+
return salt.utils.data.traverse_dict_and_list(__opts__, key, default, delimiter)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def option(value, default="", omit_opts=False, omit_all=False, **kwargs):
|
|
52
|
+
"""
|
|
53
|
+
Return the value of a specific config option on the managing minion.
|
|
54
|
+
See :py:func:`config.option <salt.modules.config.option>` for details.
|
|
55
|
+
|
|
56
|
+
CLI Example:
|
|
57
|
+
|
|
58
|
+
.. code-block:: bash
|
|
59
|
+
|
|
60
|
+
salt 'my-org/my-repo' config.option state_queue
|
|
61
|
+
"""
|
|
62
|
+
minion = _minion()
|
|
63
|
+
if minion is not None:
|
|
64
|
+
return minion["config.option"](
|
|
65
|
+
value, default=default, omit_opts=omit_opts, omit_all=omit_all, **kwargs
|
|
66
|
+
)
|
|
67
|
+
if not (omit_opts or omit_all) and value in __opts__:
|
|
68
|
+
return __opts__[value]
|
|
69
|
+
return default
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manage the targeted repository's deploy keys.
|
|
3
|
+
|
|
4
|
+
.. versionadded:: 1.1.0
|
|
5
|
+
|
|
6
|
+
Part of the :py:mod:`github <saltext.github.resources.github>` resource type: all functions operate on the
|
|
7
|
+
repository the job was dispatched to. The ``profile`` parameter
|
|
8
|
+
defaults to the :ghconf:`profile <resource:profile>` named in the resource declaration.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
|
|
13
|
+
from salt.utils.functools import namespaced_function
|
|
14
|
+
|
|
15
|
+
from saltext.github.utils import filter_fields
|
|
16
|
+
from saltext.github.utils.gh import deploy_keys as gh_deploy_keys
|
|
17
|
+
from saltext.github.utils.gh import resource as gh_resource
|
|
18
|
+
|
|
19
|
+
log = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
__func_alias__ = {"list_": "list"}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
_core_args = namespaced_function(gh_resource.core_args, globals())
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def list_(*, fields=None, profile=None):
|
|
28
|
+
"""
|
|
29
|
+
List the deploy keys of the targeted repository.
|
|
30
|
+
|
|
31
|
+
CLI Example:
|
|
32
|
+
|
|
33
|
+
.. code-block:: bash
|
|
34
|
+
|
|
35
|
+
salt 'my-org/my-repo' deploy_key.list
|
|
36
|
+
|
|
37
|
+
fields
|
|
38
|
+
Only include these fields in the output. A single field name
|
|
39
|
+
reduces each entry to the field's value.
|
|
40
|
+
|
|
41
|
+
profile
|
|
42
|
+
Profile configuration name to use. Defaults to the resource
|
|
43
|
+
declaration's profile.
|
|
44
|
+
"""
|
|
45
|
+
conn, owner, repo_name = _core_args(profile)
|
|
46
|
+
return filter_fields(gh_deploy_keys.list_all(conn, repo_name, owner=owner), fields)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get(key_id, *, profile=None):
|
|
50
|
+
"""
|
|
51
|
+
Return the data of a single deploy key of the targeted repository.
|
|
52
|
+
|
|
53
|
+
CLI Example:
|
|
54
|
+
|
|
55
|
+
.. code-block:: bash
|
|
56
|
+
|
|
57
|
+
salt 'my-org/my-repo' deploy_key.get 12345
|
|
58
|
+
|
|
59
|
+
key_id
|
|
60
|
+
ID of the deploy key.
|
|
61
|
+
|
|
62
|
+
profile
|
|
63
|
+
Profile configuration name to use. Defaults to the resource
|
|
64
|
+
declaration's profile.
|
|
65
|
+
"""
|
|
66
|
+
conn, owner, repo_name = _core_args(profile)
|
|
67
|
+
return gh_deploy_keys.get(conn, repo_name, key_id, owner=owner)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def add(title, key, *, read_only=False, profile=None):
|
|
71
|
+
"""
|
|
72
|
+
Add a deploy key to the targeted repository.
|
|
73
|
+
Returns the data of the created key.
|
|
74
|
+
|
|
75
|
+
.. note::
|
|
76
|
+
Deploy keys are immutable. To modify one, remove it and add a replacement.
|
|
77
|
+
|
|
78
|
+
CLI Example:
|
|
79
|
+
|
|
80
|
+
.. code-block:: bash
|
|
81
|
+
|
|
82
|
+
salt 'my-org/my-repo' deploy_key.add autorelease 'ssh-ed25519 AAAA...' read_only=false
|
|
83
|
+
|
|
84
|
+
title
|
|
85
|
+
Display title of the deploy key.
|
|
86
|
+
|
|
87
|
+
key
|
|
88
|
+
SSH public key.
|
|
89
|
+
|
|
90
|
+
read_only
|
|
91
|
+
Deny write access to the repository for this key. Defaults to false.
|
|
92
|
+
|
|
93
|
+
profile
|
|
94
|
+
Profile configuration name to use. Defaults to the resource
|
|
95
|
+
declaration's profile.
|
|
96
|
+
"""
|
|
97
|
+
conn, owner, repo_name = _core_args(profile)
|
|
98
|
+
return gh_deploy_keys.create(
|
|
99
|
+
conn, repo_name, title, key, read_only=bool(read_only), owner=owner
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def remove(key_id, *, profile=None):
|
|
104
|
+
"""
|
|
105
|
+
Remove a deploy key from the targeted repository.
|
|
106
|
+
|
|
107
|
+
CLI Example:
|
|
108
|
+
|
|
109
|
+
.. code-block:: bash
|
|
110
|
+
|
|
111
|
+
salt 'my-org/my-repo' deploy_key.remove 12345
|
|
112
|
+
|
|
113
|
+
key_id
|
|
114
|
+
ID of the deploy key.
|
|
115
|
+
|
|
116
|
+
profile
|
|
117
|
+
Profile configuration name to use. Defaults to the resource
|
|
118
|
+
declaration's profile.
|
|
119
|
+
"""
|
|
120
|
+
conn, owner, repo_name = _core_args(profile)
|
|
121
|
+
gh_deploy_keys.delete(conn, repo_name, key_id, owner=owner)
|
|
122
|
+
return True
|