gitlabform 4.1.2__tar.gz → 4.2.0__tar.gz
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.
- {gitlabform-4.1.2 → gitlabform-4.2.0}/PKG-INFO +12 -19
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/__init__.py +17 -50
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/configuration/core.py +5 -15
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/configuration/groups.py +3 -9
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/configuration/projects.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/configuration/transform.py +18 -39
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/__init__.py +2 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/commits.py +3 -9
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/core.py +12 -37
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/group_ldap_links.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/group_variables.py +3 -9
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/groups.py +4 -12
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/merge_requests.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/pipelines.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/project_deploy_keys.py +5 -15
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/project_merge_requests_approvals.py +1 -18
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/project_protected_environments.py +5 -16
- gitlabform-4.2.0/gitlabform/gitlab/project_security_settings.py +22 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/projects.py +3 -9
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/python_gitlab.py +5 -16
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/variables.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/lists/filter.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/lists/groups.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/lists/projects.py +17 -47
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/output.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/__init__.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/abstract_processor.py +17 -52
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/application/application_settings_processor.py +4 -12
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/defining_keys.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/__init__.py +5 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_badges_processor.py +1 -3
- gitlabform-4.2.0/gitlabform/processors/group/group_hooks_processor.py +63 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_labels_processor.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_ldap_links_processor.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_members_processor.py +15 -46
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_push_rules_processor.py +3 -9
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_saml_links_processor.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/multiple_entities_processor.py +14 -42
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/__init__.py +5 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/badges_processor.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/branches_processor.py +4 -12
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/files_processor.py +12 -38
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/hooks_processor.py +5 -15
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/integrations_processor.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/job_token_scope_processor.py +18 -54
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/members_processor.py +16 -53
- gitlabform-4.2.0/gitlabform/processors/project/merge_requests_approvals.py +56 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/project_labels_processor.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/project_processor.py +5 -15
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/project_push_rules_processor.py +2 -6
- gitlabform-4.2.0/gitlabform/processors/project/project_security_settings.py +12 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/project_settings_processor.py +9 -17
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/resource_groups_processor.py +4 -12
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/schedules_processor.py +14 -42
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/tags_processor.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/variables_processor.py +3 -12
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/shared/protected_environments_processor.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/single_entity_processor.py +2 -6
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/util/difference_logger.py +4 -14
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/util/labels_processor.py +1 -3
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform.egg-info/PKG-INFO +12 -19
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform.egg-info/SOURCES.txt +5 -56
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform.egg-info/requires.txt +7 -7
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform.egg-info/top_level.txt +0 -1
- gitlabform-4.2.0/pyproject.toml +87 -0
- gitlabform-4.2.0/setup.cfg +4 -0
- gitlabform-4.1.2/gitlabform/processors/project/merge_requests_approvals.py +0 -24
- gitlabform-4.1.2/setup.cfg +0 -10
- gitlabform-4.1.2/setup.py +0 -83
- gitlabform-4.1.2/tests/__init__.py +0 -0
- gitlabform-4.1.2/tests/acceptance/__init__.py +0 -370
- gitlabform-4.1.2/tests/acceptance/conftest.py +0 -480
- gitlabform-4.1.2/tests/acceptance/standard/__init__.py +0 -0
- gitlabform-4.1.2/tests/acceptance/standard/test_application_settings.py +0 -95
- gitlabform-4.1.2/tests/acceptance/standard/test_archive_project.py +0 -86
- gitlabform-4.1.2/tests/acceptance/standard/test_badges.py +0 -164
- gitlabform-4.1.2/tests/acceptance/standard/test_branches.py +0 -184
- gitlabform-4.1.2/tests/acceptance/standard/test_deploy_keys.py +0 -220
- gitlabform-4.1.2/tests/acceptance/standard/test_deploy_keys_all_projects.py +0 -41
- gitlabform-4.1.2/tests/acceptance/standard/test_files.py +0 -460
- gitlabform-4.1.2/tests/acceptance/standard/test_files_templates.py +0 -101
- gitlabform-4.1.2/tests/acceptance/standard/test_group_badges.py +0 -125
- gitlabform-4.1.2/tests/acceptance/standard/test_group_labels.py +0 -125
- gitlabform-4.1.2/tests/acceptance/standard/test_group_members_case_insensitive.py +0 -123
- gitlabform-4.1.2/tests/acceptance/standard/test_group_members_groups.py +0 -261
- gitlabform-4.1.2/tests/acceptance/standard/test_group_members_users.py +0 -277
- gitlabform-4.1.2/tests/acceptance/standard/test_group_settings.py +0 -33
- gitlabform-4.1.2/tests/acceptance/standard/test_group_variables.py +0 -185
- gitlabform-4.1.2/tests/acceptance/standard/test_hooks.py +0 -266
- gitlabform-4.1.2/tests/acceptance/standard/test_integrations.py +0 -264
- gitlabform-4.1.2/tests/acceptance/standard/test_job_token_scope.py +0 -420
- gitlabform-4.1.2/tests/acceptance/standard/test_members.py +0 -111
- gitlabform-4.1.2/tests/acceptance/standard/test_members_add_group.py +0 -63
- gitlabform-4.1.2/tests/acceptance/standard/test_members_enforce.py +0 -78
- gitlabform-4.1.2/tests/acceptance/standard/test_project_group_members_case_insensitive.py +0 -64
- gitlabform-4.1.2/tests/acceptance/standard/test_project_labels.py +0 -173
- gitlabform-4.1.2/tests/acceptance/standard/test_project_members_case_insensitve.py +0 -77
- gitlabform-4.1.2/tests/acceptance/standard/test_project_settings.py +0 -127
- gitlabform-4.1.2/tests/acceptance/standard/test_resource_groups.py +0 -118
- gitlabform-4.1.2/tests/acceptance/standard/test_running.py +0 -99
- gitlabform-4.1.2/tests/acceptance/standard/test_schedules.py +0 -413
- gitlabform-4.1.2/tests/acceptance/standard/test_tags.py +0 -190
- gitlabform-4.1.2/tests/acceptance/standard/test_token_from_config.py +0 -40
- gitlabform-4.1.2/tests/acceptance/standard/test_transfer_project.py +0 -446
- gitlabform-4.1.2/tests/acceptance/standard/test_variables.py +0 -195
- gitlabform-4.1.2/tests/unit/__init__.py +0 -0
- gitlabform-4.1.2/tests/unit/configuration/__init__.py +0 -0
- gitlabform-4.1.2/tests/unit/configuration/test_case_sensitivity.py +0 -102
- gitlabform-4.1.2/tests/unit/configuration/test_inheritance_break_projects_and_groups.py +0 -197
- gitlabform-4.1.2/tests/unit/configuration/test_inheritance_break_subgroups.py +0 -133
- gitlabform-4.1.2/tests/unit/configuration/test_inheritance_break_validation.py +0 -131
- gitlabform-4.1.2/tests/unit/configuration/test_projects_and_groups.py +0 -150
- gitlabform-4.1.2/tests/unit/configuration/test_skip_groups_skip_projects.py +0 -120
- gitlabform-4.1.2/tests/unit/configuration/test_subgroups.py +0 -125
- gitlabform-4.1.2/tests/unit/configuration/test_yaml_version.py +0 -25
- gitlabform-4.1.2/tests/unit/processors/__init__.py +0 -0
- gitlabform-4.1.2/tests/unit/processors/test_abstract_processor.py +0 -39
- gitlabform-4.1.2/tests/unit/processors/test_difference_logger.py +0 -87
- gitlabform-4.1.2/tests/unit/processors/test_schedules_processor_extended_cron_pattern.py +0 -41
- gitlabform-4.1.2/tests/unit/test_access_levels.py +0 -19
- gitlabform-4.1.2/tests/unit/test_non_empty_configs_provider.py +0 -29
- gitlabform-4.1.2/tests/unit/test_utils.py +0 -20
- {gitlabform-4.1.2 → gitlabform-4.2.0}/LICENSE +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/README.md +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/configuration/__init__.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/configuration/common.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/constants.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/group_badges.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/gitlab/project_badges.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/lists/__init__.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/application/__init__.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_settings_processor.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/group/group_variables_processor.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/deploy_keys_processor.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/project/merge_requests_approval_rules.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/shared/__init__.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/util/__init__.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/processors/util/decorators.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/run.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform/util.py +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform.egg-info/dependency_links.txt +0 -0
- {gitlabform-4.1.2 → gitlabform-4.2.0}/gitlabform.egg-info/entry_points.txt +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: gitlabform
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Summary: 🏗 Specialized configuration as a code tool for GitLab projects, groups and more using hierarchical configuration written in YAML
|
|
5
|
-
Home-page: https://gitlabform.github.io/gitlabform
|
|
6
5
|
Author: Greg Dubicki and Contributors
|
|
6
|
+
Project-URL: Homepage, https://gitlabform.github.io/gitlabform/
|
|
7
|
+
Project-URL: Repository, https://github.com/gitlabform/gitlabform.git
|
|
8
|
+
Project-URL: Issues, https://github.com/gitlabform/gitlabform/issues
|
|
9
|
+
Project-URL: Changelog, https://gitlabform.github.io/gitlabform/changelog/
|
|
7
10
|
Keywords: cli,yaml,gitlab,configuration-as-code
|
|
8
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
9
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
@@ -29,33 +32,23 @@ Requires-Dist: python-gitlab==5.6.0
|
|
|
29
32
|
Requires-Dist: python-gitlab[graphql]==5.6.0
|
|
30
33
|
Requires-Dist: requests==2.32.3
|
|
31
34
|
Requires-Dist: ruamel.yaml==0.17.21
|
|
32
|
-
Requires-Dist: types-requests==2.32.0.
|
|
33
|
-
Requires-Dist: types-setuptools==75.8.
|
|
35
|
+
Requires-Dist: types-requests==2.32.0.20250301
|
|
36
|
+
Requires-Dist: types-setuptools==75.8.2.20250301
|
|
34
37
|
Requires-Dist: yamlpath==3.8.2
|
|
35
38
|
Provides-Extra: test
|
|
36
|
-
Requires-Dist: coverage==7.6.
|
|
37
|
-
Requires-Dist: cryptography==44.0.
|
|
38
|
-
Requires-Dist: deepdiff==8.
|
|
39
|
-
Requires-Dist: mypy==1.
|
|
39
|
+
Requires-Dist: coverage==7.6.12; extra == "test"
|
|
40
|
+
Requires-Dist: cryptography==44.0.2; extra == "test"
|
|
41
|
+
Requires-Dist: deepdiff==8.2.0; extra == "test"
|
|
42
|
+
Requires-Dist: mypy==1.15.0; extra == "test"
|
|
40
43
|
Requires-Dist: mypy-extensions==1.0.0; extra == "test"
|
|
41
44
|
Requires-Dist: pre-commit==2.21.0; extra == "test"
|
|
42
|
-
Requires-Dist: pytest==8.3.
|
|
45
|
+
Requires-Dist: pytest==8.3.5; extra == "test"
|
|
43
46
|
Requires-Dist: pytest-cov==6.0.0; extra == "test"
|
|
44
47
|
Requires-Dist: pytest-rerunfailures==15.0; extra == "test"
|
|
45
48
|
Requires-Dist: xkcdpass==1.19.9; extra == "test"
|
|
46
49
|
Provides-Extra: docs
|
|
47
50
|
Requires-Dist: mkdocs; extra == "docs"
|
|
48
51
|
Requires-Dist: mkdocs-material; extra == "docs"
|
|
49
|
-
Dynamic: author
|
|
50
|
-
Dynamic: classifier
|
|
51
|
-
Dynamic: description
|
|
52
|
-
Dynamic: description-content-type
|
|
53
|
-
Dynamic: home-page
|
|
54
|
-
Dynamic: keywords
|
|
55
|
-
Dynamic: provides-extra
|
|
56
|
-
Dynamic: requires-dist
|
|
57
|
-
Dynamic: requires-python
|
|
58
|
-
Dynamic: summary
|
|
59
52
|
|
|
60
53
|
[](https://badge.fury.io/gh/gitlabform%2Fgitlabform)
|
|
61
54
|

|
|
@@ -114,15 +114,9 @@ class GitLabForm:
|
|
|
114
114
|
|
|
115
115
|
self.gitlab, self.configuration = self._initialize_configuration_and_gitlab()
|
|
116
116
|
|
|
117
|
-
self.application_processors = ApplicationProcessors(
|
|
118
|
-
|
|
119
|
-
)
|
|
120
|
-
self.group_processors = GroupProcessors(
|
|
121
|
-
self.gitlab, self.configuration, self.strict
|
|
122
|
-
)
|
|
123
|
-
self.project_processors = ProjectProcessors(
|
|
124
|
-
self.gitlab, self.configuration, self.strict
|
|
125
|
-
)
|
|
117
|
+
self.application_processors = ApplicationProcessors(self.gitlab, self.configuration, self.strict)
|
|
118
|
+
self.group_processors = GroupProcessors(self.gitlab, self.configuration, self.strict)
|
|
119
|
+
self.project_processors = ProjectProcessors(self.gitlab, self.configuration, self.strict)
|
|
126
120
|
self.groups_provider = GroupsProvider(
|
|
127
121
|
self.gitlab,
|
|
128
122
|
self.configuration,
|
|
@@ -186,15 +180,11 @@ class GitLabForm:
|
|
|
186
180
|
help="Skips checking if the latest version is used",
|
|
187
181
|
)
|
|
188
182
|
|
|
189
|
-
parser.add_argument(
|
|
190
|
-
"-c", "--config", default="config.yml", help="config file path and filename"
|
|
191
|
-
)
|
|
183
|
+
parser.add_argument("-c", "--config", default="config.yml", help="config file path and filename")
|
|
192
184
|
|
|
193
185
|
verbosity_args = parser.add_mutually_exclusive_group()
|
|
194
186
|
|
|
195
|
-
verbosity_args.add_argument(
|
|
196
|
-
"-v", "--verbose", action="store_true", help="verbose output"
|
|
197
|
-
)
|
|
187
|
+
verbosity_args.add_argument("-v", "--verbose", action="store_true", help="verbose output")
|
|
198
188
|
|
|
199
189
|
verbosity_args.add_argument(
|
|
200
190
|
"-d",
|
|
@@ -428,9 +418,7 @@ class GitLabForm:
|
|
|
428
418
|
)
|
|
429
419
|
continue
|
|
430
420
|
|
|
431
|
-
group_configuration = self.configuration.get_effective_config_for_group(
|
|
432
|
-
group
|
|
433
|
-
)
|
|
421
|
+
group_configuration = self.configuration.get_effective_config_for_group(group)
|
|
434
422
|
|
|
435
423
|
effective_configuration.add_placeholder(group)
|
|
436
424
|
|
|
@@ -457,9 +445,7 @@ class GitLabForm:
|
|
|
457
445
|
failed_groups[group_number] = group
|
|
458
446
|
|
|
459
447
|
trace = traceback.format_exc()
|
|
460
|
-
message =
|
|
461
|
-
f"Error occurred while processing group {group}, exception:\n\n{e}"
|
|
462
|
-
)
|
|
448
|
+
message = f"Error occurred while processing group {group}, exception:\n\n{e}"
|
|
463
449
|
|
|
464
450
|
if self.terminate_after_error:
|
|
465
451
|
effective_configuration.write_to_file()
|
|
@@ -470,9 +456,7 @@ class GitLabForm:
|
|
|
470
456
|
warning(message)
|
|
471
457
|
debug(trace)
|
|
472
458
|
finally:
|
|
473
|
-
debug(
|
|
474
|
-
f"@ ({group_number}/{len(groups)}) FINISHED Processing group: {group}"
|
|
475
|
-
)
|
|
459
|
+
debug(f"@ ({group_number}/{len(groups)}) FINISHED Processing group: {group}")
|
|
476
460
|
|
|
477
461
|
project_number = 0
|
|
478
462
|
successful_projects = 0
|
|
@@ -492,9 +476,7 @@ class GitLabForm:
|
|
|
492
476
|
)
|
|
493
477
|
continue
|
|
494
478
|
|
|
495
|
-
project_configuration = self.configuration.get_effective_config_for_project(
|
|
496
|
-
project_and_group
|
|
497
|
-
)
|
|
479
|
+
project_configuration = self.configuration.get_effective_config_for_project(project_and_group)
|
|
498
480
|
|
|
499
481
|
effective_configuration.add_placeholder(project_and_group)
|
|
500
482
|
|
|
@@ -519,9 +501,7 @@ class GitLabForm:
|
|
|
519
501
|
|
|
520
502
|
except Exception as e:
|
|
521
503
|
if "Non GET methods are not allowed for moved projects" in str(e):
|
|
522
|
-
info(
|
|
523
|
-
"Project has been transferred, no need to process original location"
|
|
524
|
-
)
|
|
504
|
+
info("Project has been transferred, no need to process original location")
|
|
525
505
|
continue
|
|
526
506
|
|
|
527
507
|
failed_projects[project_number] = project_and_group
|
|
@@ -539,8 +519,7 @@ class GitLabForm:
|
|
|
539
519
|
debug(trace)
|
|
540
520
|
finally:
|
|
541
521
|
debug(
|
|
542
|
-
f"* ({project_number}/{len(projects)})"
|
|
543
|
-
f" FINISHED Processing project: {project_and_group}",
|
|
522
|
+
f"* ({project_number}/{len(projects)})" f" FINISHED Processing project: {project_and_group}",
|
|
544
523
|
)
|
|
545
524
|
|
|
546
525
|
effective_configuration.write_to_file()
|
|
@@ -618,9 +597,7 @@ class GitLabForm:
|
|
|
618
597
|
info("Running in dry-run mode...")
|
|
619
598
|
|
|
620
599
|
if target == "ALL":
|
|
621
|
-
info(
|
|
622
|
-
">>> Getting ALL groups and projects that I have permission to modify..."
|
|
623
|
-
)
|
|
600
|
+
info(">>> Getting ALL groups and projects that I have permission to modify...")
|
|
624
601
|
elif target == "ALL_DEFINED":
|
|
625
602
|
info(">>> Getting ALL groups and projects DEFINED in the configuration...")
|
|
626
603
|
else:
|
|
@@ -633,9 +610,7 @@ class GitLabForm:
|
|
|
633
610
|
if target == "ALL":
|
|
634
611
|
error_message = "GitLab has no projects and groups!"
|
|
635
612
|
elif target == "ALL_DEFINED":
|
|
636
|
-
error_message =
|
|
637
|
-
"Configuration does not have any groups or projects defined!"
|
|
638
|
-
)
|
|
613
|
+
error_message = "Configuration does not have any groups or projects defined!"
|
|
639
614
|
else:
|
|
640
615
|
error_message = f"Project or group {target} cannot be found in GitLab!"
|
|
641
616
|
fatal(
|
|
@@ -668,9 +643,7 @@ class GitLabForm:
|
|
|
668
643
|
if len(entities.omitted[reason]) > 0:
|
|
669
644
|
if not first:
|
|
670
645
|
entities_omitted += ","
|
|
671
|
-
entities_omitted += (
|
|
672
|
-
f" {reason.value}: {len(entities.omitted[reason])}"
|
|
673
|
-
)
|
|
646
|
+
entities_omitted += f" {reason.value}: {len(entities.omitted[reason])}"
|
|
674
647
|
entities_verbose += f"\nomitted {entities.name} - {reason.value}: {entities.get_omitted(reason)}"
|
|
675
648
|
first = False
|
|
676
649
|
entities_omitted += ")"
|
|
@@ -733,21 +706,15 @@ class GitLabForm:
|
|
|
733
706
|
# fmt: on
|
|
734
707
|
|
|
735
708
|
@classmethod
|
|
736
|
-
def _info_group_count(
|
|
737
|
-
cls, prefix, i: int, n: int, *rest: Token, **kwargs: Any
|
|
738
|
-
) -> None:
|
|
709
|
+
def _info_group_count(cls, prefix, i: int, n: int, *rest: Token, **kwargs: Any) -> None:
|
|
739
710
|
cls._info_count(purple, prefix, i, n, *rest, **kwargs)
|
|
740
711
|
|
|
741
712
|
@classmethod
|
|
742
|
-
def _info_project_count(
|
|
743
|
-
cls, prefix, i: int, n: int, *rest: Token, **kwargs: Any
|
|
744
|
-
) -> None:
|
|
713
|
+
def _info_project_count(cls, prefix, i: int, n: int, *rest: Token, **kwargs: Any) -> None:
|
|
745
714
|
cls._info_count(green, prefix, i, n, *rest, **kwargs)
|
|
746
715
|
|
|
747
716
|
@classmethod
|
|
748
|
-
def _info_count(
|
|
749
|
-
cls, color, prefix, i: int, n: int, *rest: Token, **kwargs: Any
|
|
750
|
-
) -> None:
|
|
717
|
+
def _info_count(cls, color, prefix, i: int, n: int, *rest: Token, **kwargs: Any) -> None:
|
|
751
718
|
num_digits = len(str(n))
|
|
752
719
|
counter_format = f"(%{num_digits}d/%d)"
|
|
753
720
|
counter_str = counter_format % (i, n)
|
|
@@ -101,9 +101,7 @@ class ConfigurationCore(ABC):
|
|
|
101
101
|
if config_string:
|
|
102
102
|
config = textwrap.dedent(source)
|
|
103
103
|
verbose("Reading config from the provided string.")
|
|
104
|
-
(yaml_data, doc_loaded) = Parsers.get_yaml_data(
|
|
105
|
-
yaml, log, config, literal=True
|
|
106
|
-
)
|
|
104
|
+
(yaml_data, doc_loaded) = Parsers.get_yaml_data(yaml, log, config, literal=True)
|
|
107
105
|
else:
|
|
108
106
|
config_path = source
|
|
109
107
|
verbose(f"Reading config from file: {config_path}")
|
|
@@ -157,23 +155,17 @@ class ConfigurationCore(ABC):
|
|
|
157
155
|
return to_return
|
|
158
156
|
|
|
159
157
|
@staticmethod
|
|
160
|
-
def _validate_break_inheritance_flag(
|
|
161
|
-
config: dict, section_name: str, parent_key: str = ""
|
|
162
|
-
) -> None:
|
|
158
|
+
def _validate_break_inheritance_flag(config: dict, section_name: str, parent_key: str = "") -> None:
|
|
163
159
|
for key, value in config.items():
|
|
164
160
|
if "inherit" == key:
|
|
165
|
-
parent_key_description =
|
|
166
|
-
' under key "' + parent_key + '"' if parent_key else ""
|
|
167
|
-
)
|
|
161
|
+
parent_key_description = ' under key "' + parent_key + '"' if parent_key else ""
|
|
168
162
|
fatal(
|
|
169
163
|
f'The inheritance-break flag set in "{section_name}"{parent_key_description} is invalid\n'
|
|
170
164
|
f"because it has no higher level setting to inherit from.\n",
|
|
171
165
|
exit_code=EXIT_INVALID_INPUT,
|
|
172
166
|
)
|
|
173
167
|
elif type(value) in [CommentedMap, dict]:
|
|
174
|
-
ConfigurationCore._validate_break_inheritance_flag(
|
|
175
|
-
value, section_name, key
|
|
176
|
-
)
|
|
168
|
+
ConfigurationCore._validate_break_inheritance_flag(value, section_name, key)
|
|
177
169
|
|
|
178
170
|
@staticmethod
|
|
179
171
|
def _merge_configs(more_general_config, more_specific_config) -> dict:
|
|
@@ -191,9 +183,7 @@ class ConfigurationCore(ABC):
|
|
|
191
183
|
for key, value in specific_config.items():
|
|
192
184
|
if "inherit" == key:
|
|
193
185
|
if not value:
|
|
194
|
-
replace_config_sections(
|
|
195
|
-
merged_dict, parent_key, specific_config
|
|
196
|
-
)
|
|
186
|
+
replace_config_sections(merged_dict, parent_key, specific_config)
|
|
197
187
|
break
|
|
198
188
|
elif value:
|
|
199
189
|
fatal(
|
|
@@ -88,9 +88,7 @@ class ConfigurationGroups(ConfigurationCommon, ABC):
|
|
|
88
88
|
for element in elements:
|
|
89
89
|
if not last_element:
|
|
90
90
|
effective_config = self._get_group_config(element)
|
|
91
|
-
debug(
|
|
92
|
-
"First level config for '%s': %s", element, to_str(effective_config)
|
|
93
|
-
)
|
|
91
|
+
debug("First level config for '%s': %s", element, to_str(effective_config))
|
|
94
92
|
last_element = element
|
|
95
93
|
else:
|
|
96
94
|
next_level_subgroup = last_element + "/" + element
|
|
@@ -104,9 +102,7 @@ class ConfigurationGroups(ConfigurationCommon, ABC):
|
|
|
104
102
|
if effective_config:
|
|
105
103
|
self._validate_break_inheritance_flag(effective_config, subgroup)
|
|
106
104
|
elif not effective_config and next_level_subgroup_config:
|
|
107
|
-
self._validate_break_inheritance_flag(
|
|
108
|
-
next_level_subgroup_config, next_level_subgroup
|
|
109
|
-
)
|
|
105
|
+
self._validate_break_inheritance_flag(next_level_subgroup_config, next_level_subgroup)
|
|
110
106
|
|
|
111
107
|
effective_config = self._merge_configs(
|
|
112
108
|
effective_config,
|
|
@@ -128,6 +124,4 @@ class ConfigurationGroups(ConfigurationCommon, ABC):
|
|
|
128
124
|
:return: configuration for this group/subgroup or empty dict if not defined,
|
|
129
125
|
ignoring the case
|
|
130
126
|
"""
|
|
131
|
-
return self._get_case_insensitively(
|
|
132
|
-
self.get("projects_and_groups"), f"{group}/*"
|
|
133
|
-
)
|
|
127
|
+
return self._get_case_insensitively(self.get("projects_and_groups"), f"{group}/*")
|
|
@@ -31,9 +31,7 @@ class ConfigurationProjects(ConfigurationGroups, ABC):
|
|
|
31
31
|
:return: if project is defined in the key with projects to skip,
|
|
32
32
|
ignoring the case
|
|
33
33
|
"""
|
|
34
|
-
return self._is_skipped_case_insensitively(
|
|
35
|
-
self.get("skip_projects", []), project
|
|
36
|
-
)
|
|
34
|
+
return self._is_skipped_case_insensitively(self.get("skip_projects", []), project)
|
|
37
35
|
|
|
38
36
|
@functools.lru_cache()
|
|
39
37
|
def get_effective_config_for_project(self, group_and_project) -> dict:
|
|
@@ -72,6 +70,4 @@ class ConfigurationProjects(ConfigurationGroups, ABC):
|
|
|
72
70
|
:return: configuration for this project or empty dict if not defined,
|
|
73
71
|
ignoring the case
|
|
74
72
|
"""
|
|
75
|
-
return self._get_case_insensitively(
|
|
76
|
-
self.get("projects_and_groups"), group_and_project
|
|
77
|
-
)
|
|
73
|
+
return self._get_case_insensitively(self.get("projects_and_groups"), group_and_project)
|
|
@@ -26,9 +26,7 @@ from gitlabform.gitlab import GitLab
|
|
|
26
26
|
|
|
27
27
|
class ConfigurationTransformers:
|
|
28
28
|
def __init__(self, gitlab: GitLab):
|
|
29
|
-
self.merge_request_approvals_transformer = MergeRequestApprovalsTransformer(
|
|
30
|
-
gitlab
|
|
31
|
-
)
|
|
29
|
+
self.merge_request_approvals_transformer = MergeRequestApprovalsTransformer(gitlab)
|
|
32
30
|
self.user_transformer = UserTransformer(gitlab)
|
|
33
31
|
self.group_transformer = GroupTransformer(gitlab)
|
|
34
32
|
self.implicit_name_transformer = ImplicitNameTransformer(gitlab)
|
|
@@ -94,9 +92,7 @@ class UserTransformer(ConfigurationTransformer):
|
|
|
94
92
|
# under the given path
|
|
95
93
|
pass
|
|
96
94
|
|
|
97
|
-
verbose(
|
|
98
|
-
"Getting user ids for users defined in merge_requests_approval_rules config"
|
|
99
|
-
)
|
|
95
|
+
verbose("Getting user ids for users defined in merge_requests_approval_rules config")
|
|
100
96
|
try:
|
|
101
97
|
for node_coordinate in processor.get_nodes(
|
|
102
98
|
"**.merge_requests_approval_rules.*.users",
|
|
@@ -184,9 +180,7 @@ class ImplicitNameTransformer(ConfigurationTransformer):
|
|
|
184
180
|
if type(node_coordinate.node) not in [CommentedMap, dict]:
|
|
185
181
|
continue
|
|
186
182
|
|
|
187
|
-
node_coordinate.parent[node_coordinate.parentref][
|
|
188
|
-
"name"
|
|
189
|
-
] = node_coordinate.parentref
|
|
183
|
+
node_coordinate.parent[node_coordinate.parentref]["name"] = node_coordinate.parentref
|
|
190
184
|
except YAMLPathException:
|
|
191
185
|
# this just means that we haven't found any keys in YAML
|
|
192
186
|
# under the given path
|
|
@@ -228,9 +222,7 @@ class AccessLevelsTransformer(ConfigurationTransformer):
|
|
|
228
222
|
for node_coordinate in processor.get_nodes(path, mustexist=True):
|
|
229
223
|
try:
|
|
230
224
|
access_level_string = str(node_coordinate.node)
|
|
231
|
-
node_coordinate.parent[node_coordinate.parentref] = (
|
|
232
|
-
AccessLevel.get_value(access_level_string)
|
|
233
|
-
)
|
|
225
|
+
node_coordinate.parent[node_coordinate.parentref] = AccessLevel.get_value(access_level_string)
|
|
234
226
|
except KeyError:
|
|
235
227
|
fatal(
|
|
236
228
|
f"Configuration string '{access_level_string}' is not one of the valid access levels:"
|
|
@@ -258,8 +250,8 @@ class AccessLevelsTransformer(ConfigurationTransformer):
|
|
|
258
250
|
if node_coordinate.parentref == "access_level":
|
|
259
251
|
try:
|
|
260
252
|
access_level_string = str(node_coordinate.node)
|
|
261
|
-
node_coordinate.parent[node_coordinate.parentref] = (
|
|
262
|
-
|
|
253
|
+
node_coordinate.parent[node_coordinate.parentref] = AccessLevel.get_value(
|
|
254
|
+
access_level_string
|
|
263
255
|
)
|
|
264
256
|
except KeyError:
|
|
265
257
|
fatal(
|
|
@@ -308,24 +300,16 @@ class MergeRequestApprovalsTransformer(ConfigurationTransformer):
|
|
|
308
300
|
if "approvals_before_merge" in old_syntax["approvals"]:
|
|
309
301
|
# this setting is now moved inside the approval rules, so remove it from here
|
|
310
302
|
# but store it for adding there
|
|
311
|
-
approvals_required = old_syntax["approvals"][
|
|
312
|
-
"approvals_before_merge"
|
|
313
|
-
]
|
|
303
|
+
approvals_required = old_syntax["approvals"]["approvals_before_merge"]
|
|
314
304
|
approvals_required_guessed = False
|
|
315
305
|
old_syntax["approvals"].pop("approvals_before_merge")
|
|
316
306
|
|
|
317
307
|
if old_syntax["approvals"]:
|
|
318
308
|
# add the settings, if there are left any after removing 'approvals_before_merge'
|
|
319
|
-
where_to_add_new_syntax["merge_requests_approvals"] =
|
|
320
|
-
old_syntax["approvals"]
|
|
321
|
-
)
|
|
309
|
+
where_to_add_new_syntax["merge_requests_approvals"] = old_syntax["approvals"]
|
|
322
310
|
|
|
323
311
|
# approval rules
|
|
324
|
-
if
|
|
325
|
-
"approvers" in old_syntax
|
|
326
|
-
or "approver_groups" in old_syntax
|
|
327
|
-
or not approvals_required_guessed
|
|
328
|
-
):
|
|
312
|
+
if "approvers" in old_syntax or "approver_groups" in old_syntax or not approvals_required_guessed:
|
|
329
313
|
old_syntax_found = True
|
|
330
314
|
|
|
331
315
|
where_to_add_new_syntax["merge_requests_approval_rules"] = {
|
|
@@ -336,22 +320,17 @@ class MergeRequestApprovalsTransformer(ConfigurationTransformer):
|
|
|
336
320
|
}
|
|
337
321
|
|
|
338
322
|
if "approvers" in old_syntax:
|
|
339
|
-
where_to_add_new_syntax["merge_requests_approval_rules"][
|
|
340
|
-
"
|
|
341
|
-
]
|
|
323
|
+
where_to_add_new_syntax["merge_requests_approval_rules"]["legacy"]["users"] = old_syntax[
|
|
324
|
+
"approvers"
|
|
325
|
+
]
|
|
342
326
|
if "approver_groups" in old_syntax:
|
|
343
|
-
where_to_add_new_syntax["merge_requests_approval_rules"][
|
|
344
|
-
"
|
|
345
|
-
]
|
|
346
|
-
|
|
347
|
-
if
|
|
348
|
-
"remove_other_approval_rules" in old_syntax
|
|
349
|
-
and old_syntax["remove_other_approval_rules"]
|
|
350
|
-
):
|
|
327
|
+
where_to_add_new_syntax["merge_requests_approval_rules"]["legacy"]["groups"] = old_syntax[
|
|
328
|
+
"approver_groups"
|
|
329
|
+
]
|
|
330
|
+
|
|
331
|
+
if "remove_other_approval_rules" in old_syntax and old_syntax["remove_other_approval_rules"]:
|
|
351
332
|
old_syntax_found = True
|
|
352
|
-
where_to_add_new_syntax["merge_requests_approval_rules"][
|
|
353
|
-
"enforce"
|
|
354
|
-
] = True
|
|
333
|
+
where_to_add_new_syntax["merge_requests_approval_rules"]["enforce"] = True
|
|
355
334
|
|
|
356
335
|
if old_syntax_found:
|
|
357
336
|
where_to_add_new_syntax.pop("merge_requests")
|
|
@@ -20,6 +20,7 @@ from gitlabform.gitlab.project_merge_requests_approvals import (
|
|
|
20
20
|
)
|
|
21
21
|
from gitlabform.gitlab.python_gitlab import PythonGitlab
|
|
22
22
|
from gitlabform.gitlab.variables import GitLabVariables
|
|
23
|
+
from gitlabform.gitlab.project_security_settings import GitlabProjectSecuritySettings
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
@enum.unique
|
|
@@ -59,6 +60,7 @@ class GitLab(
|
|
|
59
60
|
GitLabProjectProtectedEnvironments,
|
|
60
61
|
GitLabProjectMergeRequestsApprovals,
|
|
61
62
|
GitLabVariables,
|
|
63
|
+
GitlabProjectSecuritySettings,
|
|
62
64
|
):
|
|
63
65
|
pass
|
|
64
66
|
|
|
@@ -3,13 +3,9 @@ from gitlabform.gitlab.core import GitLabCore
|
|
|
3
3
|
|
|
4
4
|
class GitLabCommits(GitLabCore):
|
|
5
5
|
def get_commit(self, project_and_group_name, sha):
|
|
6
|
-
return self._make_requests_to_api(
|
|
7
|
-
"projects/%s/repository/commits/%s", (project_and_group_name, sha)
|
|
8
|
-
)
|
|
6
|
+
return self._make_requests_to_api("projects/%s/repository/commits/%s", (project_and_group_name, sha))
|
|
9
7
|
|
|
10
|
-
def get_ahead_and_behind(
|
|
11
|
-
self, project_and_group_name, protected_branch, feature_branch
|
|
12
|
-
):
|
|
8
|
+
def get_ahead_and_behind(self, project_and_group_name, protected_branch, feature_branch):
|
|
13
9
|
ahead = 0
|
|
14
10
|
behind = 0
|
|
15
11
|
|
|
@@ -30,9 +26,7 @@ class GitLabCommits(GitLabCore):
|
|
|
30
26
|
return ahead, behind
|
|
31
27
|
|
|
32
28
|
def get_last_commit(self, project_and_group_name, branch_name):
|
|
33
|
-
branch = self._make_requests_to_api(
|
|
34
|
-
"projects/%s/repository/branches/%s", (project_and_group_name, branch_name)
|
|
35
|
-
)
|
|
29
|
+
branch = self._make_requests_to_api("projects/%s/repository/branches/%s", (project_and_group_name, branch_name))
|
|
36
30
|
last_commit_hash = branch["commit"]["id"]
|
|
37
31
|
return self.get_commit(project_and_group_name, last_commit_hash)
|
|
38
32
|
|
|
@@ -54,9 +54,7 @@ class GitLabCore:
|
|
|
54
54
|
|
|
55
55
|
try:
|
|
56
56
|
version = self._make_requests_to_api("version")
|
|
57
|
-
verbose(
|
|
58
|
-
f"Connected to GitLab version: {version['version']} ({version['revision']})"
|
|
59
|
-
)
|
|
57
|
+
verbose(f"Connected to GitLab version: {version['version']} ({version['revision']})")
|
|
60
58
|
self.version = version["version"]
|
|
61
59
|
|
|
62
60
|
current_user = self._make_requests_to_api("user")
|
|
@@ -64,9 +62,7 @@ class GitLabCore:
|
|
|
64
62
|
self.admin = True
|
|
65
63
|
else:
|
|
66
64
|
self.admin = False
|
|
67
|
-
verbose(
|
|
68
|
-
f"Connected as: {current_user['username']}, admin: {'yes' if self.admin else 'no'}"
|
|
69
|
-
)
|
|
65
|
+
verbose(f"Connected as: {current_user['username']}, admin: {'yes' if self.admin else 'no'}")
|
|
70
66
|
if not self.admin:
|
|
71
67
|
warning("Connected as non-admin. You may encounter permission issues.")
|
|
72
68
|
|
|
@@ -87,9 +83,7 @@ class GitLabCore:
|
|
|
87
83
|
# also it's not possible to get more than 1 user as a result
|
|
88
84
|
|
|
89
85
|
if len(users) == 0:
|
|
90
|
-
raise NotFoundException(
|
|
91
|
-
"No users found when searching for username '%s'" % username
|
|
92
|
-
)
|
|
86
|
+
raise NotFoundException("No users found when searching for username '%s'" % username)
|
|
93
87
|
|
|
94
88
|
return int(users[0]["id"])
|
|
95
89
|
|
|
@@ -100,9 +94,7 @@ class GitLabCore:
|
|
|
100
94
|
|
|
101
95
|
@functools.lru_cache()
|
|
102
96
|
def _get_protected_branch_id(self, project_and_group_name, branch) -> int:
|
|
103
|
-
branch = self._make_requests_to_api(
|
|
104
|
-
"projects/%s/protected_branches/%s", (project_and_group_name, branch)
|
|
105
|
-
)
|
|
97
|
+
branch = self._make_requests_to_api("projects/%s/protected_branches/%s", (project_and_group_name, branch))
|
|
106
98
|
return int(branch["id"])
|
|
107
99
|
|
|
108
100
|
@functools.lru_cache()
|
|
@@ -139,9 +131,7 @@ class GitLabCore:
|
|
|
139
131
|
objects.
|
|
140
132
|
"""
|
|
141
133
|
if method != "GET":
|
|
142
|
-
response = self._make_request_to_api(
|
|
143
|
-
path_as_format_string, args, method, data, expected_codes, json
|
|
144
|
-
)
|
|
134
|
+
response = self._make_request_to_api(path_as_format_string, args, method, data, expected_codes, json)
|
|
145
135
|
return response.json()
|
|
146
136
|
else:
|
|
147
137
|
if "?" in path_as_format_string:
|
|
@@ -149,9 +139,7 @@ class GitLabCore:
|
|
|
149
139
|
else:
|
|
150
140
|
path_as_format_string += "?per_page=100"
|
|
151
141
|
|
|
152
|
-
first_response = self._make_request_to_api(
|
|
153
|
-
path_as_format_string, args, method, data, expected_codes, json
|
|
154
|
-
)
|
|
142
|
+
first_response = self._make_request_to_api(path_as_format_string, args, method, data, expected_codes, json)
|
|
155
143
|
results = first_response.json()
|
|
156
144
|
|
|
157
145
|
# In newer versions of GitLab the 'x-total-pages' may not be available
|
|
@@ -160,10 +148,7 @@ class GitLabCore:
|
|
|
160
148
|
|
|
161
149
|
response = first_response
|
|
162
150
|
while True:
|
|
163
|
-
if
|
|
164
|
-
"x-next-page" in response.headers
|
|
165
|
-
and response.headers["x-next-page"]
|
|
166
|
-
):
|
|
151
|
+
if "x-next-page" in response.headers and response.headers["x-next-page"]:
|
|
167
152
|
next_page = response.headers["x-next-page"]
|
|
168
153
|
response = self._make_request_to_api(
|
|
169
154
|
path_as_format_string + "&page=" + str(next_page),
|
|
@@ -179,9 +164,7 @@ class GitLabCore:
|
|
|
179
164
|
|
|
180
165
|
return results
|
|
181
166
|
|
|
182
|
-
def _make_request_to_api(
|
|
183
|
-
self, path_as_format_string, args, method, dict_data, expected_codes, json_data
|
|
184
|
-
):
|
|
167
|
+
def _make_request_to_api(self, path_as_format_string, args, method, dict_data, expected_codes, json_data):
|
|
185
168
|
"""
|
|
186
169
|
Makes a single request to the GitLab API. Takes care of the authentication, basic error processing,
|
|
187
170
|
retries, timeout etc.
|
|
@@ -193,20 +176,14 @@ class GitLabCore:
|
|
|
193
176
|
expected_codes = self._listify(expected_codes)
|
|
194
177
|
|
|
195
178
|
if dict_data and json_data:
|
|
196
|
-
raise Exception(
|
|
197
|
-
"You need to pass the data either as dict (dict_data) or JSON (json_data), not both!"
|
|
198
|
-
)
|
|
179
|
+
raise Exception("You need to pass the data either as dict (dict_data) or JSON (json_data), not both!")
|
|
199
180
|
|
|
200
181
|
url = f"{self.url}/api/v4/{self._format_with_url_encoding(path_as_format_string, args)}"
|
|
201
182
|
if dict_data:
|
|
202
|
-
response = self.session.request(
|
|
203
|
-
method, url, data=dict_data, timeout=self.timeout
|
|
204
|
-
)
|
|
183
|
+
response = self.session.request(method, url, data=dict_data, timeout=self.timeout)
|
|
205
184
|
debug(f"===> data = {to_str(dict_data)}")
|
|
206
185
|
elif json_data:
|
|
207
|
-
response = self.session.request(
|
|
208
|
-
method, url, json=json_data, timeout=self.timeout
|
|
209
|
-
)
|
|
186
|
+
response = self.session.request(method, url, json=json_data, timeout=self.timeout)
|
|
210
187
|
debug(f"===> json = {to_str(json_data)}")
|
|
211
188
|
else:
|
|
212
189
|
response = self.session.request(method, url, timeout=self.timeout)
|
|
@@ -218,9 +195,7 @@ class GitLabCore:
|
|
|
218
195
|
response.json = lambda: {}
|
|
219
196
|
else:
|
|
220
197
|
if response.status_code == 404:
|
|
221
|
-
raise NotFoundException(
|
|
222
|
-
f"Resource with url='{url}' not found (HTTP 404)!"
|
|
223
|
-
)
|
|
198
|
+
raise NotFoundException(f"Resource with url='{url}' not found (HTTP 404)!")
|
|
224
199
|
else:
|
|
225
200
|
if dict_data:
|
|
226
201
|
data_output = f"data='{to_str(dict_data)}' "
|
|
@@ -5,9 +5,7 @@ from gitlabform.gitlab.groups import GitLabGroups
|
|
|
5
5
|
class GitLabGroupLDAPLinks(GitLabGroups):
|
|
6
6
|
def get_ldap_group_links(self, group):
|
|
7
7
|
group_id = self.get_group_id_case_insensitive(group)
|
|
8
|
-
return self._make_requests_to_api(
|
|
9
|
-
"groups/%s/ldap_group_links", group_id, expected_codes=[200, 404]
|
|
10
|
-
)
|
|
8
|
+
return self._make_requests_to_api("groups/%s/ldap_group_links", group_id, expected_codes=[200, 404])
|
|
11
9
|
|
|
12
10
|
def add_ldap_group_link(self, group, data):
|
|
13
11
|
group_id = self.get_group_id_case_insensitive(group)
|
|
@@ -23,9 +21,7 @@ class GitLabGroupLDAPLinks(GitLabGroups):
|
|
|
23
21
|
)
|
|
24
22
|
# this is a GitLab API bug - it returns 404 here instead of 400 for bad requests...
|
|
25
23
|
except NotFoundException:
|
|
26
|
-
raise InvalidParametersException(
|
|
27
|
-
f"Invalid parameters for a Group LDAP link for group {group}: {data}"
|
|
28
|
-
)
|
|
24
|
+
raise InvalidParametersException(f"Invalid parameters for a Group LDAP link for group {group}: {data}")
|
|
29
25
|
|
|
30
26
|
def delete_ldap_group_link(self, group, data):
|
|
31
27
|
if "group_access" in data:
|
|
@@ -20,9 +20,7 @@ class GitLabGroupVariables(GitLabCore):
|
|
|
20
20
|
# workaround for the GitLab bug
|
|
21
21
|
variable = {k: to_string(v) for k, v in variable.items()}
|
|
22
22
|
|
|
23
|
-
self._make_requests_to_api(
|
|
24
|
-
"groups/%s/variables", group, "POST", variable, expected_codes=201
|
|
25
|
-
)
|
|
23
|
+
self._make_requests_to_api("groups/%s/variables", group, "POST", variable, expected_codes=201)
|
|
26
24
|
|
|
27
25
|
def delete_group_variable(self, group, variable_object):
|
|
28
26
|
self._make_requests_to_api(
|
|
@@ -47,11 +45,7 @@ class GitLabGroupVariables(GitLabCore):
|
|
|
47
45
|
)
|
|
48
46
|
|
|
49
47
|
def get_group_variable(self, group, variable_key):
|
|
50
|
-
return self._make_requests_to_api(
|
|
51
|
-
"groups/%s/variables/%s", (group, variable_key)
|
|
52
|
-
)["value"]
|
|
48
|
+
return self._make_requests_to_api("groups/%s/variables/%s", (group, variable_key))["value"]
|
|
53
49
|
|
|
54
50
|
def get_group_variable_object(self, group, variable_key):
|
|
55
|
-
return self._make_requests_to_api(
|
|
56
|
-
"groups/%s/variables/%s", (group, variable_key)
|
|
57
|
-
)
|
|
51
|
+
return self._make_requests_to_api("groups/%s/variables/%s", (group, variable_key))
|