foreman_google 0.0.1 → 1.0.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -4
  3. data/app/controllers/concerns/foreman/controller/parameters/compute_resource_extension.rb +21 -0
  4. data/app/controllers/foreman_google/api/v2/apipie_extensions.rb +16 -0
  5. data/app/controllers/foreman_google/api/v2/compute_resources_extensions.rb +22 -0
  6. data/app/lib/foreman_google/google_compute_adapter.rb +178 -0
  7. data/app/lib/google_cloud_compute/compute_attributes.rb +98 -0
  8. data/app/lib/google_cloud_compute/compute_collection.rb +23 -0
  9. data/app/lib/google_extensions/attached_disk.rb +22 -0
  10. data/app/models/concerns/foreman_google/host_managed_extensions.rb +11 -0
  11. data/app/models/foreman_google/gce.rb +102 -38
  12. data/app/models/foreman_google/google_compute.rb +68 -58
  13. data/app/views/compute_resources/form/_gce.html.erb +10 -0
  14. data/app/views/compute_resources/show/_gce.html.erb +0 -0
  15. data/app/views/compute_resources_vms/form/gce/_base.html.erb +18 -0
  16. data/app/views/compute_resources_vms/form/gce/_volume.html.erb +5 -0
  17. data/app/views/compute_resources_vms/index/_gce.html.erb +26 -0
  18. data/app/views/compute_resources_vms/show/_gce.html.erb +21 -0
  19. data/app/views/images/form/_gce.html.erb +3 -0
  20. data/db/migrate/20220331113745_foreman_gce_to_foreman_google_gce.rb +24 -0
  21. data/lib/foreman_google/engine.rb +10 -2
  22. data/lib/foreman_google/version.rb +1 -1
  23. data/locale/action_names.rb +6 -0
  24. data/locale/en/foreman_google.edit.po +116 -0
  25. data/locale/en/foreman_google.po +74 -2
  26. data/locale/en/foreman_google.po.time_stamp +0 -0
  27. data/locale/foreman_google.pot +112 -8
  28. data/locale/gemspec.rb +1 -1
  29. data/package.json +7 -7
  30. data/test/fixtures/disks_delete.json +14 -0
  31. data/test/fixtures/disks_get.json +13 -0
  32. data/test/fixtures/disks_insert.json +12 -0
  33. data/test/fixtures/instance.json +1 -1
  34. data/test/fixtures/instance_insert.json +15 -0
  35. data/test/fixtures/instance_list.json +86 -0
  36. data/test/fixtures/instance_set_disk_auto_delete.json +14 -0
  37. data/test/fixtures/operation_error.json +26 -0
  38. data/test/fixtures/operation_get.json +13 -0
  39. data/test/models/foreman_google/gce_test.rb +43 -5
  40. data/test/models/foreman_google/google_compute_test.rb +90 -32
  41. data/test/unit/foreman_google/google_compute_adapter_test.rb +103 -4
  42. data/test/unit/google_extensions/attached_disk_test.rb +17 -0
  43. data/webpack/global_index.js +2 -13
  44. data/webpack/legacy.js +16 -0
  45. metadata +66 -16
  46. data/app/controllers/concerns/foreman_google/temporary_prepend_path.rb +0 -16
  47. data/lib/foreman_google/google_compute_adapter.rb +0 -91
@@ -34,6 +34,30 @@ module ForemanGoogle
34
34
  end
35
35
  end
36
36
 
37
+ describe '#instance - not found' do
38
+ setup do
39
+ stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/not-existing-instance')
40
+ .to_raise(Google::Cloud::NotFoundError)
41
+ end
42
+
43
+ it 'should raise an error' do
44
+ value { subject.instance('us-east1-b', 'not-existing-instance') }.must_raise(ActiveRecord::RecordNotFound)
45
+ end
46
+ end
47
+
48
+ describe '#instances' do
49
+ setup do
50
+ stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances')
51
+ .to_return(body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_list.json')))
52
+ end
53
+
54
+ it 'gets instance by id' do
55
+ instances = subject.instances('us-east1-b')
56
+ value(instances[0]).must_be_kind_of(Google::Cloud::Compute::V1::Instance)
57
+ value(instances[0].id).must_equal(123)
58
+ end
59
+ end
60
+
37
61
  describe '#zones' do
38
62
  setup do
39
63
  stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones')
@@ -107,20 +131,95 @@ module ForemanGoogle
107
131
  end
108
132
 
109
133
  describe 'manage vm' do
134
+ it '#insert' do
135
+ stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances')
136
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_insert.json')))
137
+
138
+ stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/operations/6200725776819157246')
139
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'operation_get.json')))
140
+
141
+ args = {
142
+ name: 'foreman-test',
143
+ machine_type: 'zones/us-east1-b/machineTypes/e2-micro',
144
+ disks: [{ source: 'zones/us-east1-b/disks/foreman-test-disk1', boot: true }],
145
+ network_interfaces: [{ network: 'global/networks/default' }],
146
+ }
147
+
148
+ result = subject.insert_instance('us-east1-b', args)
149
+
150
+ assert 'insert', result.operation.operation_type
151
+ assert_includes result.operation.target_link, 'foreman-test-google'
152
+ end
153
+
154
+ it '#insert with error' do
155
+ stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances')
156
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_insert.json')))
157
+
158
+ stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/operations/6200725776819157246')
159
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'operation_error.json')))
160
+
161
+ args = {
162
+ name: 'foreman-test',
163
+ machine_type: 'zones/us-east1-b/machineTypes/e2-micro',
164
+ disks: [{ source: 'zones/us-east1-b/disks/foreman-test-disk1', boot: true }],
165
+ network_interfaces: [{ network: 'global/networks/default' }],
166
+ }
167
+
168
+ value { subject.insert_instance('us-east1-b', args) }.must_raise(::Google::Cloud::Error)
169
+ end
170
+
110
171
  it '#start' do
111
172
  stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name/start')
112
- .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_start.json')), headers: {})
173
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_start.json')))
113
174
  result = subject.start('us-east1-b', 'instance_name')
114
175
  assert 'start', result.operation.operation_type
115
176
  end
116
177
 
117
178
  it '#stop' do
118
- stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name/stop').
119
-
120
- to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_stop.json')), headers: {})
179
+ stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name/stop')
180
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_stop.json')))
121
181
  result = subject.stop('us-east1-b', 'instance_name')
122
182
  assert 'stop', result.operation.operation_type
123
183
  end
184
+
185
+ it '#set_disk_auto_delete' do
186
+ stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name')
187
+ .to_return(body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance.json')))
188
+
189
+ stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/instance_name/setDiskAutoDelete?autoDelete=true&deviceName=instance-1')
190
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'instance_set_disk_auto_delete.json')))
191
+ result = subject.set_disk_auto_delete('us-east1-b', 'instance_name')
192
+
193
+ assert 'device-1', result[0].source
194
+ assert result[0].auto_delete
195
+ end
196
+ end
197
+
198
+ describe 'disks' do
199
+ it '#insert' do
200
+ stub_request(:post, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/disks')
201
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'disks_insert.json')))
202
+
203
+ result = subject.insert_disk('us-east1-b', { name: 'foreman-disk1', size_gb: 23 })
204
+ assert_includes result.operation.target_link, 'foreman-disk1'
205
+ assert 'insert', result.operation.operation_type
206
+ end
207
+
208
+ it '#get' do
209
+ stub_request(:get, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/disks/foreman-disk1')
210
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'disks_get.json')))
211
+ result = subject.disk('us-east1-b', 'foreman-disk1')
212
+ assert 'foreman-disk1', result.name
213
+ end
214
+
215
+ it '#delete' do
216
+ stub_request(:delete, 'https://compute.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/disks/foreman-disk1')
217
+ .to_return(status: 200, body: File.read(File.join(__dir__, '..', '..', 'fixtures', 'disks_delete.json')))
218
+ result = subject.delete_disk('us-east1-b', 'foreman-disk1')
219
+
220
+ assert_includes result.operation.target_link, 'foreman-disk1'
221
+ assert 'delete', result.operation.operation_type
222
+ end
124
223
  end
125
224
  end
126
225
  end
@@ -0,0 +1,17 @@
1
+ require 'test_google_helper'
2
+
3
+ module GoogleExtensions
4
+ class AttachedDiskTest < GoogleTestCase
5
+ describe 'insert_attrs' do
6
+ it 'with source image' do
7
+ disk = Google::Cloud::Compute::V1::AttachedDisk.new(source: 'source-image')
8
+ assert_equal 'source-image', disk.insert_attrs[:source_image]
9
+ end
10
+
11
+ it 'without source image' do
12
+ disk = Google::Cloud::Compute::V1::AttachedDisk.new
13
+ assert_empty disk.insert_attrs[:source_image]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,17 +1,6 @@
1
- import { registerReducer } from 'foremanReact/common/MountingService';
2
- // import { addGlobalFill } from 'foremanReact/components/common/Fill/GlobalFill';
3
1
  import { registerRoutes } from 'foremanReact/routes/RoutingService';
4
2
  import Routes from './src/Router/routes';
5
- import reducers from './src/reducers';
3
+ import { registerLegacy } from './legacy';
6
4
 
7
- // register reducers
8
- Object.entries(reducers).forEach(([key, reducer]) =>
9
- registerReducer(key, reducer)
10
- );
11
-
12
- // register client routes
13
5
  registerRoutes('ForemanGoogle', Routes);
14
-
15
- // register fills for extending foreman core
16
- // http://foreman.surge.sh/?path=/docs/introduction-slot-and-fill--page
17
- // addGlobalFill('<slotId>', '<fillId>', <div key='plugin-template-example' />, 300);
6
+ registerLegacy();
data/webpack/legacy.js ADDED
@@ -0,0 +1,16 @@
1
+ const jsonLoader = input => {
2
+ const file = input.files[0];
3
+ const reader = new FileReader();
4
+ reader.onload = () => {
5
+ const text = reader.result;
6
+ const outputTextField = document.getElementById('gce_json');
7
+ outputTextField.value = text;
8
+ };
9
+ reader.readAsText(file);
10
+ };
11
+
12
+ export const registerLegacy = () => {
13
+ window.tfm = Object.assign(window.tfm || {}, {
14
+ gce: { jsonLoader },
15
+ });
16
+ };
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_google
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Foreman Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-01 00:00:00.000000000 Z
11
+ date: 2022-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: google-apis-compute_v1
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.14'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.14'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: google-cloud-compute
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -48,38 +62,65 @@ files:
48
62
  - LICENSE
49
63
  - README.md
50
64
  - Rakefile
51
- - app/controllers/concerns/foreman_google/temporary_prepend_path.rb
65
+ - app/controllers/concerns/foreman/controller/parameters/compute_resource_extension.rb
66
+ - app/controllers/foreman_google/api/v2/apipie_extensions.rb
67
+ - app/controllers/foreman_google/api/v2/compute_resources_extensions.rb
68
+ - app/lib/foreman_google/google_compute_adapter.rb
69
+ - app/lib/google_cloud_compute/compute_attributes.rb
70
+ - app/lib/google_cloud_compute/compute_collection.rb
71
+ - app/lib/google_extensions/attached_disk.rb
72
+ - app/models/concerns/foreman_google/host_managed_extensions.rb
52
73
  - app/models/foreman_google/gce.rb
53
74
  - app/models/foreman_google/google_compute.rb
75
+ - app/views/compute_resources/form/_gce.html.erb
76
+ - app/views/compute_resources/show/_gce.html.erb
77
+ - app/views/compute_resources_vms/form/gce/_base.html.erb
78
+ - app/views/compute_resources_vms/form/gce/_volume.html.erb
79
+ - app/views/compute_resources_vms/index/_gce.html.erb
80
+ - app/views/compute_resources_vms/show/_gce.html.erb
81
+ - app/views/images/form/_gce.html.erb
54
82
  - config/routes.rb
83
+ - db/migrate/20220331113745_foreman_gce_to_foreman_google_gce.rb
55
84
  - lib/foreman_google.rb
56
85
  - lib/foreman_google/engine.rb
57
- - lib/foreman_google/google_compute_adapter.rb
58
86
  - lib/foreman_google/version.rb
59
87
  - lib/tasks/foreman_google_tasks.rake
60
88
  - locale/Makefile
89
+ - locale/action_names.rb
90
+ - locale/en/foreman_google.edit.po
61
91
  - locale/en/foreman_google.po
92
+ - locale/en/foreman_google.po.time_stamp
62
93
  - locale/foreman_google.pot
63
94
  - locale/gemspec.rb
64
95
  - package.json
65
96
  - test/factories/gce.rb
97
+ - test/fixtures/disks_delete.json
98
+ - test/fixtures/disks_get.json
99
+ - test/fixtures/disks_insert.json
66
100
  - test/fixtures/images_centos_cloud.json
67
101
  - test/fixtures/images_coastal.json
68
102
  - test/fixtures/images_deprecated.json
69
103
  - test/fixtures/images_nothing_found.json
70
104
  - test/fixtures/instance.json
105
+ - test/fixtures/instance_insert.json
106
+ - test/fixtures/instance_list.json
107
+ - test/fixtures/instance_set_disk_auto_delete.json
71
108
  - test/fixtures/instance_start.json
72
109
  - test/fixtures/instance_stop.json
73
110
  - test/fixtures/machine_types.json
74
111
  - test/fixtures/networks.json
112
+ - test/fixtures/operation_error.json
113
+ - test/fixtures/operation_get.json
75
114
  - test/fixtures/zones.json
76
115
  - test/models/foreman_google/gce_test.rb
77
116
  - test/models/foreman_google/google_compute_test.rb
78
117
  - test/test_google_helper.rb
79
118
  - test/unit/foreman_google/google_compute_adapter_test.rb
119
+ - test/unit/google_extensions/attached_disk_test.rb
80
120
  - webpack/global_index.js
81
121
  - webpack/global_test_setup.js
82
122
  - webpack/index.js
123
+ - webpack/legacy.js
83
124
  - webpack/src/Extends/index.js
84
125
  - webpack/src/Router/routes.js
85
126
  - webpack/src/reducers.js
@@ -105,23 +146,32 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
146
  - !ruby/object:Gem::Version
106
147
  version: '0'
107
148
  requirements: []
108
- rubygems_version: 3.3.7
149
+ rubygems_version: 3.1.6
109
150
  signing_key:
110
151
  specification_version: 4
111
152
  summary: Google Compute Engine plugin for the Foreman
112
153
  test_files:
113
- - test/models/foreman_google/google_compute_test.rb
114
- - test/models/foreman_google/gce_test.rb
115
- - test/unit/foreman_google/google_compute_adapter_test.rb
116
- - test/factories/gce.rb
117
- - test/fixtures/networks.json
118
- - test/fixtures/instance.json
119
- - test/fixtures/zones.json
120
- - test/fixtures/instance_stop.json
121
- - test/fixtures/machine_types.json
154
+ - test/fixtures/disks_delete.json
155
+ - test/fixtures/disks_get.json
156
+ - test/fixtures/disks_insert.json
157
+ - test/fixtures/images_centos_cloud.json
122
158
  - test/fixtures/images_coastal.json
123
- - test/fixtures/instance_start.json
124
159
  - test/fixtures/images_deprecated.json
125
- - test/fixtures/images_centos_cloud.json
126
160
  - test/fixtures/images_nothing_found.json
161
+ - test/fixtures/instance.json
162
+ - test/fixtures/instance_insert.json
163
+ - test/fixtures/instance_list.json
164
+ - test/fixtures/instance_set_disk_auto_delete.json
165
+ - test/fixtures/instance_start.json
166
+ - test/fixtures/instance_stop.json
167
+ - test/fixtures/machine_types.json
168
+ - test/fixtures/networks.json
169
+ - test/fixtures/operation_error.json
170
+ - test/fixtures/operation_get.json
171
+ - test/fixtures/zones.json
172
+ - test/factories/gce.rb
173
+ - test/unit/foreman_google/google_compute_adapter_test.rb
174
+ - test/unit/google_extensions/attached_disk_test.rb
175
+ - test/models/foreman_google/gce_test.rb
176
+ - test/models/foreman_google/google_compute_test.rb
127
177
  - test/test_google_helper.rb
@@ -1,16 +0,0 @@
1
- module ForemanGoogle
2
- # This module prepends core paths so view for gce takes precedence over core ones
3
- # This module NEEDS to get deleted once the core support for gce is dropped.
4
- # or this plugin is merged to core
5
- module TemporaryPrependPath
6
- extend ActiveSupport::Concern
7
-
8
- included do
9
- before_action :prepare_views
10
- end
11
-
12
- def prepare_views
13
- prepend_view_path ForemanGoogle::Engine.root.join('app', 'views')
14
- end
15
- end
16
- end
@@ -1,91 +0,0 @@
1
- require 'google-cloud-compute'
2
-
3
- module ForemanGoogle
4
- class GoogleComputeAdapter
5
- def initialize(auth_json_string:)
6
- @auth_json = JSON.parse(auth_json_string)
7
- end
8
-
9
- def project_id
10
- @auth_json['project_id']
11
- end
12
-
13
- # ------ RESOURCES ------
14
-
15
- # Returns an Google::Instance identified by instance_identity within given zone.
16
- # @param zone [String] eighter full url or just zone name
17
- # @param instance_identity [String] eighter an instance name or its id
18
- def instance(zone, instance_identity)
19
- get('instances', instance: instance_identity, zone: zone)
20
- end
21
-
22
- def zones
23
- list('zones')
24
- end
25
-
26
- def networks
27
- list('networks')
28
- end
29
-
30
- def machine_types(zone)
31
- list('machine_types', zone: zone)
32
- end
33
-
34
- def start(zone, instance_identity)
35
- manage_instance(:start, zone, instance_identity)
36
- end
37
-
38
- def stop(zone, instance_identity)
39
- manage_instance(:stop, zone, instance_identity)
40
- end
41
-
42
- # Setting filter to '(deprecated.state != "DEPRECATED") AND (deprecated.state != "OBSOLETE")'
43
- # doesn't work and returns empty array, no idea what is happening there
44
- def images(filter: nil)
45
- projects = [project_id] + all_projects
46
- all_images = projects.map { |project| list_images(project, filter: filter) }
47
- all_images.flatten.reject(&:deprecated)
48
- end
49
-
50
- private
51
-
52
- def list(resource_name, **opts)
53
- response = resource_client(resource_name).list(project: project_id, **opts).response
54
- response.items
55
- rescue ::Google::Cloud::Error => e
56
- raise Foreman::WrappedException.new(e, 'Cannot list Google resource %s', resource_name)
57
- end
58
-
59
- def list_images(project, **opts)
60
- resource_name = 'images'
61
- response = resource_client(resource_name).list(project: project, **opts).response
62
- response.items
63
- rescue ::Google::Cloud::Error => e
64
- raise Foreman::WrappedException.new(e, 'Cannot list Google resource %s', resource_name)
65
- end
66
-
67
- def get(resource_name, **opts)
68
- resource_client(resource_name).get(project: project_id, **opts)
69
- rescue ::Google::Cloud::Error => e
70
- raise Foreman::WrappedException.new(e, 'Could not fetch Google resource %s', resource_name)
71
- end
72
-
73
- def manage_instance(action, zone, instance_identity)
74
- resource_client('instances').send(action, project: project_id, zone: zone, instance: instance_identity)
75
- rescue ::Google::Cloud::Error => e
76
- raise Foreman::WrappedException.new(e, 'Could not %s Google resource %s', action.to_s, resource_name)
77
- end
78
-
79
- def resource_client(resource_name)
80
- ::Google::Cloud::Compute.public_send(resource_name) do |config|
81
- config.credentials = @auth_json
82
- end
83
- end
84
-
85
- def all_projects
86
- %w[centos-cloud cos-cloud coreos-cloud debian-cloud opensuse-cloud
87
- rhel-cloud rhel-sap-cloud suse-cloud suse-sap-cloud
88
- ubuntu-os-cloud windows-cloud windows-sql-cloud].freeze
89
- end
90
- end
91
- end