foreman_google 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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