Add Google Cloud Compute services
-
Review changes -
-
Download -
Patches
-
Plain diff
What does this MR do and why?
Add Google Cloud Compute services
Adds 3 services for to interact with Google Cloud Compute. These services are gated behind a SaaS-only feature.
Basically, they will build and use the client class but also provide data conversions and additional validations. Among others, check a feature flag.
We have 3 functions that the client exposes, so naturally, we split that into 3 services:
- list regions
- list zones
- list machine types
All 3 services will have a similar validation and error handling, thus we have a base class that will centralize the common logic.
The main user of these services will be GraphQL endpoints (implemented in different MRs).
NOTE: This MR is inspired from David's !143359 (merged) (which does the same for Artifact Registry).
Closes #439569 (closed)

What does this MR do and why?

- Add 3 services:
-
GoogleCloudPlatform::Compute::ListRegionsService
. -
GoogleCloudPlatform::Compute::ListZonesService
. -
GoogleCloudPlatform::Compute::ListMachineTypesService
.
-
- Add a base (common parent) service class:
GoogleCloudPlatform::Compute::BaseService
. - Add the related specs.
The feature is hidden behind the gcp_runner
FF: #437901 (closed)

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

These are services so, hu... no impact on the existing UI

How to set up and validate locally


Setup

Local testing is a bit involved as we need to have an Artifact Registry set up and some other things for the authentication part. Follow !143099 (merged), points
Now, we need to set up the Artifact registry integration. Follow the instructions from !141127 (merged).
Enable the gcp_artifact_registry
and gcp_runner
feature flags:
$ echo "Feature.enable(:gcp_artifact_registry); Feature.enable(:gcp_runner, type: :wip)" | gdk rails console
All the examples below are to be executed in the rails console and you will need the project_id
on which you set up the integration and a user with read_runner_cloud_provisioning_options
permission (maintainer
+).

Get machine types

GoogleCloudPlatform::Compute::ListRegionsService.new(project: Project.find(<project_id>), current_user: User.first, max_results: 2).execute
=> #<ServiceResponse:0x0000000299017bd8
@http_status=:ok,
@message=nil,
@payload={:items=>[{:name=>"africa-south1", :description=>"africa-south1"}, {:name=>"asia-east1", :description=>"asia-east1"}], :next_page_token=>"Cgphc2lhLWVhc3Qx"},
@reason=nil,
@status=:success>

List zones

GoogleCloudPlatform::Compute::ListZonesService.new(project: Project.find(<project_id>), current_user: User.first).execute
=> #<ServiceResponse:0x0000000299014b18
@http_status=:ok,
@message=nil,
@payload={:items=>[{:name=>"africa-south1-b", :description=>"africa-south1-b"}, {:name=>"africa-south1-c", :description=>"africa-south1-c"}], :next_page_token=>"Cg9hZnJpY2Etc291dGgxLWI="},
@reason=nil,
@status=:success>

List machine types

> GoogleCloudPlatform::Compute::ListMachineTypesService.new(project: Project.find(43), current_user: User.first, zone: "us-west1-a", max_results: 2).execute
=> #<ServiceResponse:0x00000002a0130568
@http_status=:ok,
@message=nil,
@payload=
{:items=>
[{:name=>"c2-standard-16", :description=>"Compute Optimized: 16 vCPUs, 64 GB RAM", :zone=>"us-west1-a"},
{:name=>"c2-standard-30", :description=>"Compute Optimized: 30 vCPUs, 120 GB RAM", :zone=>"us-west1-a"}],
:next_page_token=>"Cg5jMi1zdGFuZGFyZC0zMA=="},
@reason=nil,
@status=:success>
> GoogleCloudPlatform::Compute::ListMachineTypesService.new(project: Project.find(43), current_user: User.first, zone: "us-west1-a", max_results: 2, page_token: "Cg5jMi1zdGFuZGFyZC0zMA==").execute
=> #<ServiceResponse:0x000000029fabf238
@http_status=:ok,
@message=nil,
@payload=
{:items=>
[{:name=>"c2-standard-4", :description=>"Compute Optimized: 4 vCPUs, 16 GB RAM", :zone=>"us-west1-a"},
{:name=>"c2-standard-60", :description=>"Compute Optimized: 60 vCPUs, 240 GB RAM", :zone=>"us-west1-a"}],
:next_page_token=>"Cg5jMi1zdGFuZGFyZC02MA=="},
@reason=nil,
@status=:success>

Handling errors

Let's play around with erroneous calls:
GoogleCloudPlatform::Compute::ListRegionsService.new(project: Project.find(<project id>), current_user: User.first, order_by: 'id desc').execute
=> #<ServiceResponse:0x00000002a00157f0 @http_status=nil, @message="Invalid order_by value", @payload={}, @reason=nil, @status=:error>
GoogleCloudPlatform::Compute::ListMachineTypesService.new(project: Project.find(43), current_user: User.first, zone: "us-west1")
=> #<ServiceResponse:0x0000000322a5dde8
@http_status=nil,
@message="Unsuccessful Google Cloud API request: An error has occurred when making a REST request: Invalid value for field 'zone': 'us-west1'. Unknown zone.",
@payload={},
@reason=nil,
@status=:error>
Let's list regions on a project that doesn't have the integration configured:
GoogleCloudPlatform::Compute::ListRegionsService.new(project: Project.find(44), current_user: User.first, order_by: 'id desc').execute
=> #<ServiceResponse:0x0000000319e9c188 @http_status=nil, @message="Project Artifact Registry integration not set", @payload={}, @reason=nil, @status=:error>
Merge request reports
- version 267786bea8
- version 25f8a1185a
- version 241eb7e462
- version 2391881ad9
- version 22cf92a967
- version 21539cd31f
- version 202fe846e3
- version 19c9886a4a
- version 1832e4a0e1
- version 179986539e
- version 16a201716e
- version 15e0985fa3
- version 14499c99ec
- version 136b0a5709
- version 12293ec92a
- version 11bfe04f91
- version 101f8eb8a7
- version 98982f3e0
- version 8b7de1d57
- version 75f837dc1
- version 641b90ae6
- version 5c4d845a0
- version 4a7701725
- version 36ea2f839
- version 2b1e3f584
- version 111c6c901
- master (base)
- latest version3c961e3b7 commits,
- version 267786bea87 commits,
- version 25f8a1185a7 commits,
- version 241eb7e4626 commits,
- version 2391881ad96 commits,
- version 22cf92a9675 commits,
- version 21539cd31f5 commits,
- version 202fe846e35 commits,
- version 19c9886a4a5 commits,
- version 1832e4a0e15 commits,
- version 179986539e4 commits,
- version 16a201716e4 commits,
- version 15e0985fa34 commits,
- version 14499c99ec4 commits,
- version 136b0a57094 commits,
- version 12293ec92a4 commits,
- version 11bfe04f913 commits,
- version 101f8eb8a72 commits,
- version 98982f3e02 commits,
- version 8b7de1d572 commits,
- version 75f837dc11 commit,
- version 641b90ae61 commit,
- version 5c4d845a01 commit,
- version 4a77017251 commit,
- version 36ea2f8391 commit,
- version 2b1e3f5841 commit,
- version 111c6c9011 commit,
- Side-by-side
- Inline