foreman_google 0.0.1 → 0.0.2

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -4
  3. data/app/lib/foreman_google/google_compute_adapter.rb +178 -0
  4. data/app/lib/google_cloud_compute/compute_attributes.rb +98 -0
  5. data/app/lib/google_cloud_compute/compute_collection.rb +23 -0
  6. data/app/lib/google_extensions/attached_disk.rb +22 -0
  7. data/app/models/concerns/foreman_google/host_managed_extensions.rb +11 -0
  8. data/app/models/foreman_google/gce.rb +98 -38
  9. data/app/models/foreman_google/google_compute.rb +68 -58
  10. data/app/views/compute_resources/form/_gce.html.erb +10 -0
  11. data/app/views/compute_resources/show/_gce.html.erb +0 -0
  12. data/app/views/compute_resources_vms/form/gce/_base.html.erb +18 -0
  13. data/app/views/compute_resources_vms/form/gce/_volume.html.erb +5 -0
  14. data/app/views/compute_resources_vms/index/_gce.html.erb +26 -0
  15. data/app/views/compute_resources_vms/show/_gce.html.erb +21 -0
  16. data/app/views/images/form/_gce.html.erb +3 -0
  17. data/db/migrate/20220331113745_foreman_gce_to_foreman_google_gce.rb +24 -0
  18. data/lib/foreman_google/engine.rb +9 -1
  19. data/lib/foreman_google/version.rb +1 -1
  20. data/locale/action_names.rb +6 -0
  21. data/locale/en/foreman_google.edit.po +116 -0
  22. data/locale/en/foreman_google.po +74 -2
  23. data/locale/en/foreman_google.po.time_stamp +0 -0
  24. data/locale/foreman_google.pot +112 -8
  25. data/locale/gemspec.rb +1 -1
  26. data/package.json +7 -7
  27. data/test/fixtures/disks_delete.json +14 -0
  28. data/test/fixtures/disks_get.json +13 -0
  29. data/test/fixtures/disks_insert.json +12 -0
  30. data/test/fixtures/instance.json +1 -1
  31. data/test/fixtures/instance_insert.json +15 -0
  32. data/test/fixtures/instance_list.json +86 -0
  33. data/test/fixtures/instance_set_disk_auto_delete.json +14 -0
  34. data/test/fixtures/operation_error.json +26 -0
  35. data/test/fixtures/operation_get.json +13 -0
  36. data/test/models/foreman_google/gce_test.rb +43 -5
  37. data/test/models/foreman_google/google_compute_test.rb +90 -32
  38. data/test/unit/foreman_google/google_compute_adapter_test.rb +103 -4
  39. data/test/unit/google_extensions/attached_disk_test.rb +17 -0
  40. data/webpack/global_index.js +2 -13
  41. data/webpack/legacy.js +16 -0
  42. metadata +63 -15
  43. data/lib/foreman_google/google_compute_adapter.rb +0 -91
data/locale/gemspec.rb CHANGED
@@ -1,2 +1,2 @@
1
1
  # Matches foreman_google.gemspec
2
- _('TODO: Description of ForemanGoogle.')
2
+ _('Google Compute Engine plugin for the Foreman.')
data/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "url": "http://projects.theforeman.org/projects/foreman_google/issues"
22
22
  },
23
23
  "peerDependencies": {
24
- "@theforeman/vendor": ">= 6.0.0"
24
+ "@theforeman/vendor": ">= 8.16.0"
25
25
  },
26
26
  "dependencies": {
27
27
  "react-intl": "^2.8.0"
@@ -29,12 +29,12 @@
29
29
  "devDependencies": {
30
30
  "@babel/core": "^7.7.0",
31
31
  "@sheerun/mutationobserver-shim": "^0.3.3",
32
- "@theforeman/builder": "^6.0.0",
33
- "@theforeman/eslint-plugin-foreman": "6.0.0",
34
- "@theforeman/find-foreman": "^4.8.0",
35
- "@theforeman/stories": "^7.0.0",
36
- "@theforeman/test": "^8.0.0",
37
- "@theforeman/vendor-dev": "^6.0.0",
32
+ "@theforeman/builder": "^10.0",
33
+ "@theforeman/eslint-plugin-foreman": "^10.0",
34
+ "@theforeman/find-foreman": "^10.0",
35
+ "@theforeman/stories": "^10.0",
36
+ "@theforeman/test": "^10.0",
37
+ "@theforeman/vendor-dev": "^10.0",
38
38
  "babel-eslint": "^10.0.3",
39
39
  "eslint": "^6.7.2",
40
40
  "prettier": "^1.19.1",
@@ -0,0 +1,14 @@
1
+ {
2
+ "kind": "compute#operation",
3
+ "id": "7996175101872145267",
4
+ "name": "operation-1648639388515-5db6dc51d7cb9-84b381ef-f190800c",
5
+ "zone": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b",
6
+ "operationType": "delete",
7
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/disks/foreman-disk1",
8
+ "targetId": "8772167819860748300",
9
+ "status": "RUNNING",
10
+ "progress": 0,
11
+ "insertTime": "2022-03-30T04:23:08.704-07:00",
12
+ "startTime": "2022-03-30T04:23:08.711-07:00",
13
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/operations/operation-1648639388515-5db6dc51d7cb9-84b381ef-f190800c"
14
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "kind": "compute#disk",
3
+ "id": "8772167819860748300",
4
+ "creationTimestamp": "2022-03-30T01:37:55.394-07:00",
5
+ "name": "foreman-disk1",
6
+ "sizeGb": "500",
7
+ "zone": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b",
8
+ "status": "READY",
9
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/disks/foreman-disk1",
10
+ "type": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/diskTypes/pd-standard",
11
+ "labelFingerprint": "42WmSpB8rSM=",
12
+ "physicalBlockSizeBytes": "4096"
13
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "kind": "compute#operation",
3
+ "id": "1043042221276375052",
4
+ "name": "operation-1648629475145-5db6b763b7595-82e7ebef-451ed31a",
5
+ "zone": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b",
6
+ "operationType": "insert",
7
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/us-east1-b/disks/foreman-disk1",
8
+ "targetId": "8772167819860748300",
9
+ "status": "RUNNING",
10
+ "progress": 0,
11
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/operations/operation-1648629475145-5db6b763b7595-82e7ebef-451ed31a"
12
+ }
@@ -7,7 +7,7 @@
7
7
  "tags": {
8
8
  "fingerprint": "42WmSpB8rSM="
9
9
  },
10
- "machineType": "https://www.googleapis.com/compute/v1/projectscoastal-haven-123456zones/us-east1-b/machineTypes/e2-micro",
10
+ "machineType": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/machineTypes/e2-micro",
11
11
  "status": "RUNNING",
12
12
  "zone": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b",
13
13
  "canIpForward": false,
@@ -0,0 +1,15 @@
1
+ {
2
+ "kind": "compute#operation",
3
+ "id": "6200725776819157246",
4
+ "name": "operation-1648641552671-5db6e461be422-a2599aa0-27cd29fc",
5
+ "zone": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-west3-c",
6
+ "operationType": "insert",
7
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-west3-c/instances/foreman-test-google1648641548",
8
+ "targetId": "6079655721101293822",
9
+ "status": "RUNNING",
10
+ "user": "modular-ethos-98809@appspot.gserviceaccount.com",
11
+ "progress": 0,
12
+ "insertTime": "2022-03-30T04:59:13.515-07:00",
13
+ "startTime": "2022-03-30T04:59:13.516-07:00",
14
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-west3-c/operations/operation-1648641552671-5db6e461be422-a2599aa0-27cd29fc"
15
+ }
@@ -0,0 +1,86 @@
1
+ {
2
+ "kind": "compute#instanceList",
3
+ "id": "projects/coastal-haven-123456/zones/us-east1-b/instances",
4
+ "items": [
5
+ {
6
+ "kind": "compute#instance",
7
+ "id": "123",
8
+ "creationTimestamp": "2022-03-30T04:59:13.453-07:00",
9
+ "name": "foreman-test-google1648641548",
10
+ "tags": {
11
+ "fingerprint": "42WmSpB8rSM="
12
+ },
13
+ "machineType": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/machineTypes/e2-micro",
14
+ "status": "TERMINATED",
15
+ "zone": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b",
16
+ "networkInterfaces": [
17
+ {
18
+ "kind": "compute#networkInterface",
19
+ "network": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/global/networks/default",
20
+ "subnetwork": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/regions/europe-west3/subnetworks/default",
21
+ "networkIP": "10.156.0.15",
22
+ "name": "nic0",
23
+ "fingerprint": "TJa5cxJEqkU=",
24
+ "stackType": "IPV4_ONLY"
25
+ }
26
+ ],
27
+ "disks": [
28
+ {
29
+ "kind": "compute#attachedDisk",
30
+ "type": "PERSISTENT",
31
+ "mode": "READ_WRITE",
32
+ "source": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/disks/foreman-test-google1648641548-disk1",
33
+ "deviceName": "persistent-disk-0",
34
+ "index": 0,
35
+ "boot": true,
36
+ "autoDelete": true,
37
+ "licenses": [
38
+ "https://www.googleapis.com/compute/v1/projects/centos-cloud/global/licenses/centos-stream"
39
+ ],
40
+ "interface": "SCSI",
41
+ "guestOsFeatures": [
42
+ {
43
+ "type": "UEFI_COMPATIBLE"
44
+ },
45
+ {
46
+ "type": "VIRTIO_SCSI_MULTIQUEUE"
47
+ },
48
+ {
49
+ "type": "SEV_CAPABLE"
50
+ },
51
+ {
52
+ "type": "GVNIC"
53
+ }
54
+ ],
55
+ "diskSizeGb": "23"
56
+ }
57
+ ],
58
+ "metadata": {
59
+ "kind": "compute#metadata",
60
+ "fingerprint": "YazRB9ehpGM="
61
+ },
62
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/foreman-test-google1648641548",
63
+ "scheduling": {
64
+ "onHostMaintenance": "MIGRATE",
65
+ "automaticRestart": true,
66
+ "preemptible": false
67
+ },
68
+ "cpuPlatform": "Unknown CPU Platform",
69
+ "labelFingerprint": "42WmSpB8rSM=",
70
+ "startRestricted": false,
71
+ "deletionProtection": false,
72
+ "shieldedInstanceConfig": {
73
+ "enableSecureBoot": false,
74
+ "enableVtpm": true,
75
+ "enableIntegrityMonitoring": true
76
+ },
77
+ "shieldedInstanceIntegrityPolicy": {
78
+ "updateAutoLearnPolicy": true
79
+ },
80
+ "fingerprint": "kDkIG75oL1k=",
81
+ "lastStartTimestamp": "2022-04-07T06:09:42.109-07:00",
82
+ "lastStopTimestamp": "2022-04-07T06:52:58.005-07:00"
83
+ }
84
+ ],
85
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances"
86
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "kind": "compute#operation",
3
+ "id": "4987965516534051502",
4
+ "name": "operation-1648708672817-5db7de6c808c0-7970bcc7-68670f06",
5
+ "zone": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b",
6
+ "operationType": "setDiskAutoDelete",
7
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/instances/foreman-test-google1648641548",
8
+ "targetId": "6079655721101293822",
9
+ "status": "RUNNING",
10
+ "progress": 0,
11
+ "insertTime": "2022-03-30T23:37:53.201-07:00",
12
+ "startTime": "2022-03-30T23:37:53.212-07:00",
13
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/coastal-haven-123456/zones/us-east1-b/operations/operation-1648708672817-5db7de6c808c0-7970bcc7-68670f06"
14
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "kind": "compute#operation",
3
+ "id": "150820958032316172",
4
+ "name": "operation-1654585826373-5e0d6486e6dac-12d06773-e45211ed",
5
+ "zone": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-central2-a",
6
+ "operationType": "insert",
7
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-central2-a/instances/louie-stahly-example-com",
8
+ "targetId": "7654338946829338380",
9
+ "status": "DONE",
10
+ "user": "coconut-service-account@modular-ethos-98809.iam.gserviceaccount.com",
11
+ "progress": 100,
12
+ "insertTime": "2022-06-07T00:10:27.995-07:00",
13
+ "startTime": "2022-06-07T00:10:27.996-07:00",
14
+ "endTime": "2022-06-07T00:10:34.467-07:00",
15
+ "error": {
16
+ "errors": [
17
+ {
18
+ "code": "QUOTA_EXCEEDED",
19
+ "message": "Quota 'CPUS' exceeded. Limit: 8.0 in region europe-central2."
20
+ }
21
+ ]
22
+ },
23
+ "httpErrorStatusCode": 403,
24
+ "httpErrorMessage": "FORBIDDEN",
25
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-central2-a/operations/operation-1654585826373-5e0d6486e6dac-12d06773-e45211ed"
26
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "kind": "compute#operation",
3
+ "id": "6200725776819157246",
4
+ "name": "operation-1653565614407-5dfe8bf0f40b4-855dec88-23e914e4",
5
+ "zone": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-west3-c",
6
+ "operationType": "insert",
7
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/modular-ethos-98809/zones/europe-west3-c/instances/mega-chad-1",
8
+ "targetId": "3160050662526604865",
9
+ "status": "DONE",
10
+ "insertTime": "2022-05-26T04:46:55.770-07:00",
11
+ "startTime": "2022-05-26T04:46:55.770-07:00",
12
+ "endTime": "2022-05-26T04:47:02.023-07:00"
13
+ }
@@ -5,6 +5,14 @@ module ForemanGoogle
5
5
  subject { ForemanGoogle::GCE.new(zone: 'zone', password: gauth_json) }
6
6
  let(:service) { mock('GoogleAdapter') }
7
7
 
8
+ let(:instance_args) do
9
+ nics = [OpenStruct.new(access_configs: [OpenStruct.new(nat_i_p: '1.2.3.4')], network: 'test/default', network_i_p: '10.10.10.23')]
10
+
11
+ { name: "instance-#{Time.now.to_i}", network_interfaces: nics,
12
+ creation_timestamp: Time.zone.now, zone: '/test/us-east1-b',
13
+ machine_type: 'machineTypes/e2-micro' }
14
+ end
15
+
8
16
  setup do
9
17
  subject.stubs(client: service)
10
18
  service.stubs(:project_id).returns('project_id')
@@ -12,9 +20,11 @@ module ForemanGoogle
12
20
 
13
21
  describe '#find_vm_by_uuid' do
14
22
  it 'does query gce' do
15
- instance = stub(status: 'RUNNING')
16
- service.expects(:instance).with(subject.zone, 'instance_name').returns(instance)
17
- compute = subject.find_vm_by_uuid('instance_name')
23
+ instance = OpenStruct.new(**instance_args)
24
+
25
+ service.expects(:instance).with(subject.zone, instance.name).returns(instance)
26
+
27
+ compute = subject.find_vm_by_uuid(instance.name)
18
28
  value(compute).must_be_kind_of(ForemanGoogle::GoogleCompute)
19
29
  end
20
30
 
@@ -22,9 +32,37 @@ module ForemanGoogle
22
32
  service
23
33
  .expects(:instance)
24
34
  .with(subject.zone, 'non-existing-name-or-id')
25
- .raises(Foreman::WrappedException.new(Google::Cloud::NotFoundError.new, 'not found'))
35
+ .raises(ActiveRecord::RecordNotFound)
36
+
37
+ value { subject.find_vm_by_uuid('non-existing-name-or-id') }.must_raise(ActiveRecord::RecordNotFound)
38
+ end
39
+ end
40
+
41
+ describe '#vms' do
42
+ let(:instances) do
43
+ Array.new(2) { |_i| OpenStruct.new(**instance_args) }
44
+ end
45
+
46
+ setup do
47
+ service.expects(:instances).returns(instances)
48
+ end
49
+
50
+ it 'iteration over the vms array' do
51
+ subject.vms.each_with_index { |instance, i| assert instance.name, instances[i].name }
52
+ end
53
+
54
+ it 'all method' do
55
+ subject.vms.all.each_with_index { |instance, i| assert instance.name, instances[i].name }
56
+ end
57
+ end
58
+
59
+ describe '#create_vm' do
60
+ setup do
61
+ service.expects(:image).returns(nil)
62
+ end
26
63
 
27
- value { subject.find_vm_by_uuid('non-existing-name-or-id') }.must_raise(Foreman::WrappedException)
64
+ it 'without OS image' do
65
+ value { subject.create_vm({ image_id: 0 }) }.must_raise(::Foreman::Exception)
28
66
  end
29
67
  end
30
68
  end
@@ -6,6 +6,14 @@ module ForemanGoogle
6
6
  let(:zone) { 'zone-1' }
7
7
  let(:identity) { 'instance-id-or-name' }
8
8
 
9
+ let(:instance) do
10
+ nics = [OpenStruct.new(access_configs: [OpenStruct.new(nat_i_p: '1.2.3.4')], network: 'test/default', network_i_p: '10.10.10.23')]
11
+
12
+ OpenStruct.new name: 'instance', network_interfaces: nics,
13
+ creation_timestamp: Time.zone.now, zone: zone,
14
+ machine_type: 'machineTypes/e2-micro'
15
+ end
16
+
9
17
  subject { ForemanGoogle::GoogleCompute.new(client: client, zone: zone, identity: identity) }
10
18
 
11
19
  setup do
@@ -40,19 +48,15 @@ module ForemanGoogle
40
48
  end
41
49
 
42
50
  describe '#ready?' do
43
- let(:instance) { mock('Google::Compute::Instance') }
44
-
45
- setup do
46
- client.expects(:instance).with(zone, identity).returns(instance)
47
- end
48
-
49
51
  it 'is ready with running instance' do
50
- instance.expects(:status).returns('RUNNING')
52
+ instance.status = 'RUNNING'
53
+ client.expects(:instance).with(zone, identity).returns(instance)
51
54
  value(subject).must_be(:ready?)
52
55
  end
53
56
 
54
57
  it 'is not ready for not running instance' do
55
- instance.expects(:status).returns('PROVISIONING')
58
+ instance.status = 'PROVISIONING'
59
+ client.expects(:instance).with(zone, identity).returns(instance)
56
60
  value(subject).wont_be(:ready?)
57
61
  end
58
62
  end
@@ -62,8 +66,8 @@ module ForemanGoogle
62
66
  args = { network: '' }
63
67
  cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
64
68
 
65
- assert_includes cr.name, 'foreman_'
66
- assert_includes cr.hostname, 'foreman_'
69
+ assert_includes cr.name, 'foreman-'
70
+ assert_includes cr.hostname, 'foreman-'
67
71
  end
68
72
 
69
73
  it 'is parameterized' do
@@ -95,8 +99,7 @@ module ForemanGoogle
95
99
  end
96
100
 
97
101
  it 'with nics' do
98
- nics = [{ network: 'global/networks/custom' }]
99
- args = { associate_external_ip: '1', network_interfaces: nics }
102
+ args = { associate_external_ip: '1', network_interfaces: [{ network: 'global/networks/custom' }] }
100
103
  cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
101
104
  expected_nics = [{ network: 'global/networks/custom', access_configs: [{ name: 'External NAT', type: 'ONE_TO_ONE_NAT' }] }]
102
105
 
@@ -104,52 +107,107 @@ module ForemanGoogle
104
107
  end
105
108
  end
106
109
 
107
- describe '#disks' do
110
+ describe '#volumes' do
108
111
  setup do
109
- client.stubs(:images).returns([OpenStruct.new(id: 1, name: 'coastal-image')])
112
+ client.stubs(:images).returns([OpenStruct.new(id: 1, name: 'coastal-image', self_link: 'test-self-link')])
113
+ client.stubs(:image).returns(OpenStruct.new(id: 1, name: 'coastal-image', self_link: 'test-self-link'))
110
114
  end
111
115
 
112
116
  it 'no volumes' do
113
- args = { volumes: [] }
114
- cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
117
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
118
+ volumes = [Google::Cloud::Compute::V1::AttachedDisk.new(disk_size_gb: 20)]
115
119
 
116
- assert_equal cr.disks, []
120
+ assert_equal cr.volumes, volumes
117
121
  end
118
122
 
119
123
  it 'without image_id' do
120
124
  args = { volumes: [{ size_gb: '23' }] }
121
125
  cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
122
- disk = cr.disks.first
126
+ volume = cr.volumes.first
123
127
 
124
- assert_equal disk.name, "#{cr.name}-disk1"
125
- assert_nil disk.source_image
126
- end
127
-
128
- it 'image not found' do
129
- args = { volumes: [{ size_gb: '23' }], image_id: '0' }
130
- value { ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args) }.must_raise(::Foreman::Exception)
128
+ assert_equal volume.device_name, "#{cr.name}-disk1"
129
+ assert_empty volume.source
131
130
  end
132
131
 
133
132
  it 'with source_image' do
134
- args = { volumes: [{ size_gb: '23', source_image: 'centos-stream-8-v20220317' }], image_id: '1' }
133
+ args = { volumes: Array.new(2, { size_gb: '23', source_image: 'centos-stream-8-v20220317' }), image_id: '1' }
135
134
  cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
136
135
 
137
- disk = cr.disks.first
138
- assert_equal disk.source_image, 'coastal-image'
136
+ assert_equal cr.volumes[0].source, 'test-self-link'
137
+ assert_equal cr.volumes[1].source, ''
139
138
  end
140
139
  end
141
140
 
142
141
  describe '#metadata' do
142
+ let(:ssh_attrs) { { username: 'gce_user', public_key: 'public_key' } }
143
+
143
144
  it 'with user_data' do
144
- args = { user_data: 'test' }
145
+ args = ssh_attrs.merge({ user_data: 'test' })
145
146
  cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
146
- assert_equal cr.metadata, { items: [{ key: 'user-data', value: 'test' }] }
147
+
148
+ assert_includes cr.metadata[:items], { key: 'user-data', value: 'test' }
149
+ assert_includes cr.metadata[:items], { key: 'ssh-keys', value: 'gce_user:public_key' }
147
150
  end
148
151
 
149
152
  it 'no user_data' do
150
- cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
151
- assert_nil cr.metadata
153
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: ssh_attrs)
154
+ assert_equal cr.metadata, { items: [{ key: 'ssh-keys', value: 'gce_user:public_key' }] }
152
155
  end
153
156
  end
157
+
158
+ it '#pretty_machine_type - with instance' do
159
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
160
+ assert_equal cr.pretty_machine_type, 'e2-micro'
161
+ end
162
+
163
+ it '#pretty_machine_type - without instance' do
164
+ args = { machine_type: 'high-cpu-16' }
165
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: args)
166
+ assert_equal cr.pretty_machine_type, args[:machine_type]
167
+ end
168
+
169
+ it '#vm_ip_address' do
170
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
171
+ assert_equal cr.vm_ip_address, '1.2.3.4'
172
+ end
173
+
174
+ it '#private_ip_address' do
175
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
176
+ assert_equal cr.private_ip_address, '10.10.10.23'
177
+ end
178
+
179
+ it '#pretty_image_name' do
180
+ client.stubs(:disk).returns(OpenStruct.new(source_image: '/path/to/centos-source-image'))
181
+ instance.disks = [OpenStruct.new(source: 'path/to/foreman-disk1')]
182
+
183
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
184
+ assert_equal cr.pretty_image_name, 'centos-source-image'
185
+ end
186
+
187
+ it '@associate_external_ip' do
188
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
189
+ assert_not cr.associate_external_ip
190
+
191
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: { associate_external_ip: '1' })
192
+ assert cr.associate_external_ip
193
+ end
194
+
195
+ it '@network' do
196
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
197
+ assert cr.network, 'default'
198
+
199
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, args: { network: 'my-network' })
200
+ assert cr.network, 'my-network'
201
+ end
202
+
203
+ it '@zone' do
204
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone)
205
+ assert zone, cr.zone
206
+ end
207
+
208
+ it '@zone_name' do
209
+ cr = ForemanGoogle::GoogleCompute.new(client: client, zone: zone, instance: instance)
210
+ assert zone, cr.zone_name
211
+ end
154
212
  end
155
213
  end
@@ -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