foreman_ansible_director 0.4.0 → 0.5.0

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_ansible_director/api/v2/ansible_content_controller.rb +86 -2
  3. data/app/controllers/foreman_ansible_director/api/v2/ansible_variable_overrides_controller.rb +122 -0
  4. data/app/controllers/foreman_ansible_director/api/v2/ansible_variables_controller.rb +49 -0
  5. data/app/controllers/foreman_ansible_director/api/v2/assignments_controller.rb +132 -0
  6. data/app/controllers/foreman_ansible_director/api/v2/execution_environments_controller.rb +82 -0
  7. data/app/controllers/foreman_ansible_director/api/v2/lifecycle_environment_paths_controller.rb +90 -0
  8. data/app/controllers/foreman_ansible_director/api/v2/lifecycle_environments_controller.rb +177 -0
  9. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/extract_variables.rb +6 -5
  10. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/import.rb +6 -0
  11. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/import_providers/galaxy/import_collection.rb +16 -1
  12. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/import_providers/galaxy/rescue.rb +62 -0
  13. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/import_providers/git/import_collection.rb +16 -1
  14. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/import_providers/git/rescue.rb +63 -0
  15. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/index/index_git_collection.rb +29 -11
  16. data/app/lib/foreman_ansible_director/actions/ansible_content_unit/index/index_static.rb +19 -14
  17. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/distribution/create.rb +40 -16
  18. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/distribution/destroy.rb +23 -8
  19. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/remote/collection/create.rb +9 -3
  20. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/remote/collection/destroy.rb +23 -9
  21. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/remote/git/create.rb +8 -3
  22. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/remote/git/destroy.rb +33 -5
  23. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/remote/role/create.rb +1 -0
  24. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/repository/create.rb +12 -4
  25. data/app/lib/foreman_ansible_director/actions/pulp3/ansible/repository/destroy.rb +22 -8
  26. data/app/lib/foreman_ansible_director/actions/remote_execution/Provider/ansible_navigator_provider.rb +2 -2
  27. data/app/lib/foreman_ansible_director/actions/remote_execution/Provider/ansible_script_provider.rb +3 -3
  28. data/app/lib/foreman_ansible_director/actions/rescue/ansible_content_unit/common/cleanup_check.rb +35 -0
  29. data/app/lib/foreman_ansible_director/generators/content_generator.rb +18 -6
  30. data/app/lib/foreman_ansible_director/generators/inventory_generator.rb +1 -0
  31. data/app/models/foreman_ansible_director/concerns/host_extensions.rb +5 -6
  32. data/app/models/foreman_ansible_director/concerns/hostgroup_extensions.rb +7 -1
  33. data/app/models/foreman_ansible_director/lifecycle_environment.rb +9 -0
  34. data/app/overrides/create_host_ansible_tab.rb +12 -12
  35. data/app/services/foreman_ansible_director/ansible_report_importer.rb +0 -3
  36. data/app/services/foreman_ansible_director/cert/certs.rb +10 -2
  37. data/app/services/foreman_ansible_director/pulp3/base_client.rb +13 -1
  38. data/app/views/foreman_ansible_director/job_templates/run_playbook-ansible_default.erb +3 -3
  39. data/lib/foreman_ansible_director/constants.rb +7 -1
  40. data/lib/foreman_ansible_director/register.rb +1 -0
  41. data/lib/foreman_ansible_director/remote_execution.rb +0 -6
  42. data/package.json +1 -1
  43. data/webpack/components/ansible_content/components/AnsibleContentWizard/components/ProviderSelectionStep.tsx +0 -1
  44. data/webpack/components/ansible_content/components/AnsibleContentWizard/components/components/FinishFooter.tsx +3 -3
  45. data/webpack/components/ansible_content/components/AnsibleContentWizard/components/components/GalaxyContentUnitInput.tsx +12 -91
  46. data/webpack/components/ansible_content/components/AnsibleContentWizard/components/components/GitContentUnitInput.tsx +34 -17
  47. data/webpack/components/ansible_content/components/AnsibleContentWizard/components/components/components/IdentifierInput.tsx +121 -0
  48. data/webpack/components/ansible_content/components/AnsibleVariablesOverview/AnsibleVariablesOverview.tsx +1 -1
  49. data/webpack/components/ansible_content/components/AnsibleVariablesOverview/AnsibleVariablesSelector.tsx +145 -241
  50. data/webpack/components/ansible_content/components/AnsibleVariablesOverview/VariableManagementModal/OverridesTabContent.tsx +33 -1
  51. data/webpack/components/ansible_content/components/AnsibleVariablesOverview/VariableManagementModal/VariableManagementModalContent.tsx +59 -6
  52. data/webpack/components/ansible_content/components/AnsibleVariablesOverview/VariableManagementModal/VariableManagementModalWrapper.tsx +4 -2
  53. data/webpack/components/ansible_environments/components/components/AnsibleLcePathComponent.tsx +3 -1
  54. data/webpack/components/ansible_execution_environments/components/ExecutionEnvCard.tsx +27 -122
  55. data/webpack/components/ansible_execution_environments/components/ExecutionEnvCardHeaderActions.tsx +3 -0
  56. data/webpack/components/ansible_execution_environments/components/ExecutionEnvCreateCard.tsx +61 -135
  57. data/webpack/components/ansible_execution_environments/components/ExecutionEnvEditCard.tsx +208 -0
  58. data/webpack/components/ansible_execution_environments/components/components/TextInputEditable.tsx +3 -0
  59. metadata +16 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4d8ce033fdae658dc74ed39b1e726223fd1f3f709c0912500eee63a959d1cfb
4
- data.tar.gz: ff49758a3a1ab2654d8af19e4841eda385c14d3338e8fc1d925cbd53863265b2
3
+ metadata.gz: ad5a385698810d3de3c2a7807d683ef2deacc5e12d3ec40d340ca2b3ce13b512
4
+ data.tar.gz: 396708fd055a23d192e4355d08fe5a76396869d8ec36785c4951cc9572268e13
5
5
  SHA512:
6
- metadata.gz: c65a3a229e2b3d482e3144dcfd0eb8a4c5de8e70acc1a089f09234686267ac0c597f98b9308e8b1d438be43c7e0b5301ee9e3d2ea86558656e2b52482e38897f
7
- data.tar.gz: 165890d464e01ce17f4e673fe7ab88d4c391a28a34ce37f13274c1459d5fe37613c8ed8e4d3daf84ca14cc37a276a3f9400fb9647c09c0b6df11f625901bb9d3
6
+ metadata.gz: de0b152a577bfc6cd2f45bb43ee16d456fbd15146510fe6429158cf05a2bad4d6ed1f963131e12e27fd74524bafacb85fb2737ab2c3886be277632889d827ead
7
+ data.tar.gz: 28b6076faaae3c7b027cfe31528d5ea650e88cd0bd682a93d7feca85ae7660a976e628c3d5aac0334fde8dc6b420911873249d9716f2d3fab3e20424e1ec606b
@@ -7,8 +7,54 @@ module ForemanAnsibleDirector
7
7
  before_action :find_organization, only: %i[create_units]
8
8
  before_action :find_optional_organization, only: %i[index]
9
9
 
10
- # TODO: APIDOC
10
+ resource_description { resource_id 'AD Ansible Content' }
11
11
 
12
+ # region ApiDoc: POST /api/v2/ansible_director/ansible_content
13
+ api :POST, '/v2/ansible_director/ansible_content', N_('Import Ansible content units')
14
+ param :organization_id, :number, desc: N_('Organization identifier.'), required: true
15
+ param :units, Array, desc: N_('Array of content units to import.'), required: true do
16
+ param :unit_name,
17
+ String,
18
+ desc: N_('Identifier of the content unit.'),
19
+ example: N_('manala.roles'),
20
+ required: true
21
+ param :unit_type,
22
+ %w[role collection],
23
+ desc: N_('Type of the content unit.'),
24
+ example: N_('collection'),
25
+ required: true
26
+ param :unit_source_type,
27
+ %w[galaxy git],
28
+ desc: N_('Source type of the content unit.'),
29
+ example: N_('galaxy'),
30
+ required: true
31
+ param :unit_source,
32
+ String,
33
+ desc: N_('Source URL or path for the content unit (e.g., Galaxy URL or Git repo).'),
34
+ example: N_('https://galaxy.ansible.com'),
35
+ required: true
36
+ param :unit_versions,
37
+ Array,
38
+ desc: N_('An array of versions to import (e.g., ["1.0.0", "2.0.0"]).'),
39
+ example: %w[1.0.0 2.0.0],
40
+ required: true
41
+ end
42
+ # TRANSLATORS: ApiDoc, do not translate!
43
+ example <<~EXAMPLE
44
+ {
45
+ "organization_id": 1,
46
+ "units": [
47
+ {
48
+ "unit_name": "manala.roles",
49
+ "unit_type": "collection",
50
+ "unit_source_type": "galaxy",
51
+ "unit_source": "https://galaxy.ansible.com",
52
+ "unit_versions": ["5.2.0"]
53
+ }
54
+ ]
55
+ }
56
+ EXAMPLE
57
+ # endregion
12
58
  def create_units
13
59
  resolved = ::ForemanAnsibleDirector::AnsibleContent::AnsibleContentHelpers.resolve_import_payload(
14
60
  params[:units]
@@ -20,6 +66,11 @@ module ForemanAnsibleDirector
20
66
  )
21
67
  end
22
68
 
69
+ # region ApiDoc: GET /api/v2/ansible_director/ansible_content
70
+ api :GET, '/v2/ansible_director/ansible_content', N_('List Ansible content units')
71
+ param :organization_id, :number, desc: N_('Organization identifier'), required: false
72
+ param_group :search_and_pagination, ::Api::V2::BaseController
73
+ # endregion
23
74
  def index
24
75
  scope = resource_scope_for_index
25
76
  @ansible_content_units = if @organization
@@ -29,18 +80,51 @@ module ForemanAnsibleDirector
29
80
  end
30
81
  end
31
82
 
83
+ # region ApiDoc: GET /api/v2/ansible_director/ansible_content/:content_unit_id/versions/:content_unit_version_id
84
+ api :GET, '/v2/ansible_director/ansible_content/:content_unit_id/versions/:content_unit_version_id',
85
+ N_('Show details of a specific Ansible content unit version')
86
+ # endregion
32
87
  def version_detail
33
88
  @content_unit_version = ::ForemanAnsibleDirector::ContentUnitVersion.find_by(id: params[:version])
34
89
  end
35
90
 
36
91
  # TODO: This needs to check and invalidate built EEs
92
+ # region ApiDoc: DELETE /api/v2/ansible_director/ansible_content
93
+ api :DELETE, '/v2/ansible_director/ansible_content',
94
+ N_('Destroy previously imported Ansible content units.')
95
+ param :units, Array, desc: N_('Array of content units to destroy.'), required: true do
96
+ param :unit_id, :number, desc: N_('ID of the Ansible content unit to destroy.'), required: true
97
+ # TRANSLATORS: ApiDoc, do not translate!
98
+ param :unit_version_ids, Array,
99
+ desc: <<~DESC,
100
+ Array of version IDs to delete.
101
+ Optional: If not supplied, every version of the given content unit will be deleted.
102
+ DESC
103
+ required: false
104
+ end
105
+ # TRANSLATORS: ApiDoc, do not translate!
106
+ example <<~EXAMPLE
107
+ {
108
+ "units": [
109
+ {
110
+ "unit_id": 42,
111
+ "unit_version_ids": [101, 102]
112
+ },
113
+ {
114
+ "unit_id": 43,
115
+ "unit_version_ids": [105]
116
+ }
117
+ ]
118
+ }
119
+ EXAMPLE
120
+ # endregion
37
121
  def destroy_units
38
122
  resolved = ::ForemanAnsibleDirector::AnsibleContent::AnsibleContentHelpers.resolve_destroy_payload(
39
123
  destroy_params
40
124
  )
41
125
  @bulk_destroy_task =
42
126
  ForemanTasks.sync_task(::ForemanAnsibleDirector::Actions::AnsibleContentUnit::Bulk::Destroy,
43
- resolved_content_units: resolved, organization_id: @organization.id)
127
+ resolved_content_units: resolved)
44
128
  end
45
129
 
46
130
  def model_of_controller
@@ -7,6 +7,30 @@ module ForemanAnsibleDirector
7
7
  before_action :find_variable, only: %i[create]
8
8
  before_action :find_override, only: %i[update destroy]
9
9
 
10
+ resource_description { resource_id 'AD Ansible Variable Overrides' }
11
+
12
+ # region ApiDoc: GET /api/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides
13
+ api :GET, '/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides',
14
+ N_('List overrides for a target')
15
+ # TRANSLATORS: ApiDoc, do not translate!
16
+ description <<~DESC
17
+ List override values associated with a given target (host or hostgroup).
18
+ Overrides are matched at runtime based on the predefined hierarchy: Default -> Hostgroup -> Host.
19
+ DESC
20
+ param :target,
21
+ %w[HOST HOSTGROUP],
22
+ desc: N_('Type of the target entity.'),
23
+ required: true
24
+ param :target_id,
25
+ :number,
26
+ desc: N_('ID of the target entity.'),
27
+ required: true
28
+ param :include_overridable,
29
+ [true, false],
30
+ desc: N_('Whether to include overridable variables in the response.'),
31
+ example: false,
32
+ required: false
33
+ # endregion
10
34
  def index_for_target
11
35
  target = ::ForemanAnsibleDirector::AssignmentService.find_target(
12
36
  target_type: params[:target],
@@ -17,6 +41,46 @@ module ForemanAnsibleDirector
17
41
  include_overridable: include_overridable
18
42
  end
19
43
 
44
+ # region ApiDoc: POST /api/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides
45
+ api :POST, '/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides',
46
+ N_('Create an override for an Ansible variable')
47
+ # TRANSLATORS: ApiDoc, do not translate!
48
+ description <<~DESC
49
+ Create a new override rule for the specified Ansible variable.
50
+ Overrides allow customizing the variable value for specific hosts, hostgroups, or other matchers.
51
+ DESC
52
+ param :ansible_variable_id,
53
+ :number,
54
+ desc: N_('ID of the Ansible variable to override.'),
55
+ required: true
56
+ param :override, Hash, desc: N_('Override definition'), required: true do
57
+ param :value,
58
+ String,
59
+ desc: N_('Override value (must be valid JSON when the variable type is `json`, `array`, or `hash`).'),
60
+ example: '192.168.1.1',
61
+ required: true
62
+ param :matcher,
63
+ %w[fqdn hostgroup],
64
+ desc: N_('Matcher type.'),
65
+ example: 'fqdn',
66
+ required: true
67
+ param :matcher_value,
68
+ String,
69
+ desc: N_('Value for the matcher (e.g., "myhost.example.com").'),
70
+ example: 'myhost.example.com',
71
+ required: true
72
+ end
73
+ # TRANSLATORS: ApiDoc, do not translate!
74
+ example <<~EXAMPLE
75
+ {
76
+ "override": {
77
+ "value": "prod-ntp.internal",
78
+ "matcher": "fqdn",
79
+ "matcher_value": "prod-web-01.example.com"
80
+ }
81
+ }
82
+ EXAMPLE
83
+ # endregion
20
84
  def create
21
85
  override = override_params
22
86
  ::ForemanAnsibleDirector::VariableService.create_override(
@@ -27,6 +91,48 @@ module ForemanAnsibleDirector
27
91
  )
28
92
  end
29
93
 
94
+ # region ApiDoc: PUT /api/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides/:id
95
+ api :PUT, '/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides/:id', N_('Update an override')
96
+ # TRANSLATORS: ApiDoc, do not translate!
97
+ description <<~DESC
98
+ Update an existing override rule.
99
+ DESC
100
+ param :ansible_variable_id,
101
+ :number,
102
+ desc: N_('ID of the Ansible variable.'),
103
+ required: true
104
+ param :id,
105
+ :number,
106
+ desc: N_('ID of the override to update.'),
107
+ required: true
108
+ param :override, Hash, desc: N_('Override update'), required: true do
109
+ param :value,
110
+ String,
111
+ desc: N_('New override value.'),
112
+ example: 'backup-ntp.internal',
113
+ required: false
114
+ param :matcher,
115
+ String,
116
+ desc: N_('New matcher type (e.g., "hostgroup").'),
117
+ example: 'hostgroup',
118
+ required: false
119
+ param :matcher_value,
120
+ String,
121
+ desc: N_('New matcher value (e.g., "my_hostgroup").'),
122
+ example: 'my_hostgroup',
123
+ required: false
124
+ end
125
+ # TRANSLATORS: ApiDoc, do not translate!
126
+ example <<~EXAMPLE
127
+ {
128
+ "override": {
129
+ "value": "staging-ntp.internal",
130
+ "matcher": "hostgroup",
131
+ "matcher_value": "Staging"
132
+ }
133
+ }
134
+ EXAMPLE
135
+ # endregion
30
136
  def update
31
137
  override = override_params
32
138
  ::ForemanAnsibleDirector::VariableService.edit_override(
@@ -37,6 +143,22 @@ module ForemanAnsibleDirector
37
143
  )
38
144
  end
39
145
 
146
+ # region ApiDoc: DELETE /api/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides/:id
147
+ api :DELETE, '/v2/ansible_director/ansible_variables/:ansible_variable_id/overrides/:id',
148
+ N_('Delete an override')
149
+ # TRANSLATORS: ApiDoc, do not translate!
150
+ description <<~DESC
151
+ Delete an override rule.
152
+ DESC
153
+ param :ansible_variable_id,
154
+ :number,
155
+ desc: N_('ID of the Ansible variable.'),
156
+ required: true
157
+ param :id,
158
+ :number,
159
+ desc: N_('ID of the override to delete.'),
160
+ required: true
161
+ # endregion
40
162
  def destroy
41
163
  ::ForemanAnsibleDirector::VariableService.destroy_override(@override)
42
164
  end
@@ -6,9 +6,58 @@ module ForemanAnsibleDirector
6
6
  class AnsibleVariablesController < AnsibleDirectorApiController
7
7
  before_action :find_resource, only: %i[show update]
8
8
 
9
+ resource_description { resource_id 'AD Ansible Variables' }
10
+
11
+ # region ApiDoc: GET /api/v2/ansible_director/ansible_variables/:id
12
+ api :GET, '/v2/ansible_director/ansible_variables/:id', N_('Show details of an Ansible variable')
13
+ # TRANSLATORS: ApiDoc, do not translate!
14
+ description <<~DESC
15
+ Retrieve details of a specific Ansible variable.
16
+ DESC
17
+ # endregion
9
18
  def show
10
19
  end
11
20
 
21
+ # region ApiDoc: PUT /api/v2/ansible_director/ansible_variables/:id
22
+ api :PUT, '/v2/ansible_director/ansible_variables/:id', N_('Update an Ansible variable')
23
+ # TRANSLATORS: ApiDoc, do not translate!
24
+ description <<~DESC
25
+ Update basic attributes (key, type, default value, and overridability) of an Ansible variable.
26
+ DESC
27
+ param :ansible_variable, Hash, desc: N_('Ansible variable updates'), required: true do
28
+ param :key,
29
+ String,
30
+ desc: N_('Name of the variable.'),
31
+ example: 'ansible_user',
32
+ required: true
33
+ param :type,
34
+ %w[string integer boolean float json array hash],
35
+ desc: N_('Type of the variable value.'),
36
+ example: 'string',
37
+ required: true
38
+ param :default_value,
39
+ String,
40
+ desc: N_('Default value (must be valid JSON when type is `json`, `array`, or `hash`).'),
41
+ example: 'root',
42
+ required: true
43
+ param :overridable,
44
+ [true, false],
45
+ desc: N_('Whether this variable can be overridden on hosts or hostgroups.'),
46
+ example: true,
47
+ required: false
48
+ end
49
+ # TRANSLATORS: ApiDoc, do not translate!
50
+ example <<~EXAMPLE
51
+ {
52
+ "ansible_variable": {
53
+ "key": "ansible_user",
54
+ "type": "string",
55
+ "default_value": "root",
56
+ "overridable": true
57
+ }
58
+ }
59
+ EXAMPLE
60
+ # endregion
12
61
  def update
13
62
  variable = variable_params
14
63
  ::ForemanAnsibleDirector::VariableService.edit_variable(
@@ -6,6 +6,28 @@ module ForemanAnsibleDirector
6
6
  class AssignmentsController < AnsibleDirectorApiController
7
7
  before_action :find_resource, only: %i[destroy]
8
8
 
9
+ resource_description { resource_id 'AD Ansible Content Assignments' }
10
+
11
+ # region ApiDoc: GET /api/v2/ansible_director/assignments
12
+ api :GET, '/v2/ansible_director/assignments', N_('List resolved Ansible content assignments for a target')
13
+ # TRANSLATORS: ApiDoc, do not translate!
14
+ description <<~DESC
15
+ Retrieve all Ansible content units *resolved* for a given target (host or hostgroup).
16
+ This includes content inherited through the assignment hierarchy or direct assignments.
17
+ DESC
18
+ param :target,
19
+ %w[HOST HOSTGROUP],
20
+ desc: N_('Type of the target entity.'),
21
+ required: true
22
+ param :target_id,
23
+ :number,
24
+ desc: N_('ID of the target entity.'),
25
+ required: true
26
+ # TRANSLATORS: ApiDoc, do not translate!
27
+ example <<~EXAMPLE
28
+ GET /api/v2/ansible_director/assignments?target=HOST&target_id=123
29
+ EXAMPLE
30
+ # endregion
9
31
  def assignments
10
32
  target = ::ForemanAnsibleDirector::AssignmentService.find_target(
11
33
  target_type: params[:target],
@@ -15,6 +37,54 @@ module ForemanAnsibleDirector
15
37
  @assignments = target.resolved_ansible_content
16
38
  end
17
39
 
40
+ # region ApiDoc: POST /api/v2/ansible_director/assignments
41
+ api :POST, '/v2/ansible_director/assignments', N_('Assign Ansible content to a target')
42
+ # TRANSLATORS: ApiDoc, do not translate!
43
+ description <<~DESC
44
+ Assign Ansible content from a source (e.g., a lifecycle environment) to a target.
45
+ DESC
46
+ param :assignment, Hash, desc: N_('Assignment definition'), required: true do
47
+ param :source, Hash, desc: N_('Source (provider of content)'), required: true do
48
+ param :type,
49
+ %w[ACR],
50
+ desc: N_('Type of source. Currently, only Ansible collection roles (ACR) are supported as sources.'),
51
+ example: 'ACR',
52
+ required: true
53
+ param :id,
54
+ :number,
55
+ desc: N_('ID of the source entity.'),
56
+ example: 5,
57
+ required: true
58
+ end
59
+ param :target, Hash, desc: N_('Target (receiver of content)'), required: true do
60
+ param :type,
61
+ %w[HOST HOSTGROUP],
62
+ desc: N_('Type of target. Both hosts (HOST) and hostgroups (HOSTGROUP) are supported as targets.'),
63
+ example: 'HOST',
64
+ required: true
65
+ param :id,
66
+ :number,
67
+ desc: N_('ID of the target entity.'),
68
+ example: 6,
69
+ required: true
70
+ end
71
+ end
72
+ # TRANSLATORS: ApiDoc, do not translate!
73
+ example <<~EXAMPLE
74
+ {
75
+ "assignment": {
76
+ "source": {
77
+ "type": "ACR",
78
+ "id": 109
79
+ },
80
+ "target": {
81
+ "type": "HOST",
82
+ "id": 1
83
+ }
84
+ }
85
+ }
86
+ EXAMPLE
87
+ # endregion
18
88
  def assign
19
89
  assignment = assignment_params
20
90
 
@@ -34,6 +104,57 @@ module ForemanAnsibleDirector
34
104
  )
35
105
  end
36
106
 
107
+ # region ApiDoc: POST /api/v2/ansible_director/assignments/bulk
108
+ api :POST, '/v2/ansible_director/assignments/bulk', N_('Bulk assign Ansible content')
109
+ # TRANSLATORS: ApiDoc, do not translate!
110
+ description <<~DESC
111
+ Bulk-assign Ansible content from a source (e.g., a lifecycle environment) to targets.
112
+ Equivalent to calling `/assign` multiple times.
113
+ DESC
114
+ param :assignments, Array, desc: N_('Array of assignment objects'), required: true do
115
+ param :source, Hash, desc: N_('Source (provider of content)'), required: true do
116
+ param :type,
117
+ %w[ACR],
118
+ desc: N_('Type of source. Currently, only Ansible collection roles (ACR) are supported as sources.'),
119
+ example: 'ACR',
120
+ required: true
121
+ param :id,
122
+ :number,
123
+ desc: N_('ID of the source entity.'),
124
+ example: 5,
125
+ required: true
126
+ end
127
+ param :target, Hash, desc: N_('Target (receiver of content)'), required: true do
128
+ param :type,
129
+ %w[HOST HOSTGROUP],
130
+ desc: N_('Type of target. Both hosts (HOST) and hostgroups (HOSTGROUP) are supported as targets.'),
131
+ example: 'HOST',
132
+ required: true
133
+ param :id,
134
+ :number,
135
+ desc: N_('ID of the target entity.'),
136
+ example: 6,
137
+ required: true
138
+ end
139
+ end
140
+ # TRANSLATORS: ApiDoc, do not translate!
141
+ example <<~EXAMPLE
142
+ {
143
+ "assignments": [
144
+ {
145
+ "source": {
146
+ "type": "ACR",
147
+ "id": 109
148
+ },
149
+ "target": {
150
+ "type": "HOST",
151
+ "id": 1
152
+ }
153
+ }
154
+ ]
155
+ }
156
+ EXAMPLE
157
+ # endregion
37
158
  def assign_bulk
38
159
  assignments = bulk_assignment_params
39
160
  ::ForemanAnsibleDirector::AssignmentService.create_bulk_assignments(
@@ -41,6 +162,17 @@ module ForemanAnsibleDirector
41
162
  )
42
163
  end
43
164
 
165
+ # region ApiDoc: DELETE /api/v2/ansible_director/assignments/:id
166
+ api :DELETE, '/v2/ansible_director/assignments/:id', N_('Delete an Ansible content assignment')
167
+ # TRANSLATORS: ApiDoc, do not translate!
168
+ description <<~DESC
169
+ Note: This deletes the assignment record but not the underlying Ansible content.
170
+ DESC
171
+ param :id,
172
+ :number,
173
+ desc: N_('ID of the assignment to delete.'),
174
+ required: true
175
+ # endregion
44
176
  def destroy
45
177
  ::ForemanAnsibleDirector::AssignmentService.destroy_assignment(@assignment)
46
178
  end
@@ -9,10 +9,54 @@ module ForemanAnsibleDirector
9
9
  before_action :find_resource, only: %i[update destroy]
10
10
  before_action :find_organization, only: %i[create]
11
11
 
12
+ resource_description { resource_id 'AD Ansible Execution Environments' }
13
+
14
+ # region ApiDoc: GET /api/v2/ansible_director/execution_environments
15
+ api :GET, '/v2/ansible_director/execution_environments', N_('List all execution environments')
16
+ param :organization_id, :number, desc: N_('Organization identifier.'), required: false
17
+ param_group :search_and_pagination, ::Api::V2::BaseController
18
+ # endregion
12
19
  def index
13
20
  @execution_environments = resource_scope_for_index
14
21
  end
15
22
 
23
+ # region ApiDoc: POST /api/v2/ansible_director/execution_environments
24
+ api :POST, '/v2/ansible_director/execution_environments', N_('Create an Execution Environment')
25
+ param :organization_id, :number, desc: N_('Organization identifier'), required: true
26
+ param :execution_environment, Hash, desc: N_('Execution Environment definition'), required: true do
27
+ param :name,
28
+ String,
29
+ desc: N_('Execution Environment name.'),
30
+ example: 'MyExecutionEnvironment',
31
+ required: true
32
+ param :base_image_url,
33
+ String,
34
+ desc: N_('Execution Environment base image URL. The image must be pullable by an unauthenticated user.'),
35
+ example: 'registry.fedoraproject.org/fedora:43',
36
+ required: true
37
+ # TRANSLATORS: ApiDoc, do not translate!
38
+ param :ansible_version,
39
+ String,
40
+ desc: <<~DESC,
41
+ Version of "ansible-core" to be used in this execution environment.
42
+ The version must match one of the available releases.
43
+ See: https://pypi.org/project/ansible-core/#history
44
+ DESC
45
+ example: ::ForemanAnsibleDirector::Constants::DEFAULT_ANSIBLE_VERSION,
46
+ required: true
47
+ end
48
+ # TRANSLATORS: ApiDoc, do not translate!
49
+ example <<~EXAMPLE
50
+ {
51
+ "organization_id": 1,
52
+ "execution_environment": {
53
+ "name": "EE-2.20.0",
54
+ "base_image_url": "quay.io/fedora/fedora:42",
55
+ "ansible_version": "2.20.0"
56
+ }
57
+ }
58
+ EXAMPLE
59
+ # endregion
16
60
  def create
17
61
  permitted_params = execution_environment_params
18
62
  # content = permitted_params.delete(:content)
@@ -25,6 +69,41 @@ module ForemanAnsibleDirector
25
69
  )
26
70
  end
27
71
 
72
+ # region ApiDoc: PATCH /api/v2/ansible_director/execution_environments/:id
73
+ api :PATCH, '/v2/ansible_director/execution_environments/:id', N_('Update an Execution Environment')
74
+ param :execution_environment, Hash, desc: N_('Execution Environment definition'), required: true do
75
+ param :name,
76
+ String,
77
+ desc: N_('Execution Environment name.'),
78
+ example: 'MyExecutionEnvironment',
79
+ required: false
80
+ param :base_image_url,
81
+ String,
82
+ desc: N_('Execution Environment base image URL. The image must be pullable by an unauthenticated user.'),
83
+ example: 'registry.fedoraproject.org/fedora:43',
84
+ required: false
85
+ # TRANSLATORS: ApiDoc, do not translate!
86
+ param :ansible_version,
87
+ String,
88
+ desc: <<~DESC,
89
+ Version of "ansible-core" to be used in this execution environment.
90
+ The version must match one of the available releases.
91
+ See: https://pypi.org/project/ansible-core/#history
92
+ DESC
93
+ example: ::ForemanAnsibleDirector::Constants::DEFAULT_ANSIBLE_VERSION,
94
+ required: false
95
+ end
96
+ # TRANSLATORS: ApiDoc, do not translate!
97
+ example <<~EXAMPLE
98
+ {
99
+ "execution_environment": {
100
+ "name": "EE-2.20.0",
101
+ "base_image_url": "quay.io/fedora/fedora:42",
102
+ "ansible_version": "2.20.0"
103
+ }
104
+ }
105
+ EXAMPLE
106
+ # endregion
28
107
  def update
29
108
  permitted_params = execution_environment_params
30
109
  # content = permitted_params.delete(:content)
@@ -37,6 +116,9 @@ module ForemanAnsibleDirector
37
116
  )
38
117
  end
39
118
 
119
+ # region ApiDoc: DELETE /api/v2/ansible_director/execution_environments/:id
120
+ api :DELETE, '/v2/ansible_director/execution_environments/:id', N_('Delete an Execution Environment')
121
+ # endregion
40
122
  def destroy
41
123
  @execution_environment.destroy
42
124
  ::ForemanAnsibleDirector::ExecutionEnvironmentService.destroy_execution_environment @execution_environment