Skip to content

Commit

Permalink
Handle OpAsync and PollAsync in Go Async type (#10336)
Browse files Browse the repository at this point in the history
  • Loading branch information
zli82016 authored Apr 1, 2024
1 parent 53b19f4 commit 4b9acba
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 78 deletions.
147 changes: 93 additions & 54 deletions mmv1/api/async.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,30 @@
package api

import (
"strings"

"github.com/GoogleCloudPlatform/magic-modules/mmv1/google"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v3"
)

// Base class from which other Async classes can inherit.
type Async struct {
// Embed YamlValidator object
google.YamlValidator
// google.YamlValidator

// Describes an operation
Operation *Operation

// The list of methods where operations are used.
Actions []string

// Describes an operation, one of "OpAsync", "PollAsync"
Type string

OpAsync *OpAsync `yaml:",inline"`

PollAsync *PollAsync `yaml:",inline"`
}

// def validate
Expand All @@ -37,33 +48,36 @@ type Async struct {
// end

// def allow?(method)
// @actions.include?(method.downcase)
// end

// Base async operation type
type Operation struct {
google.YamlValidator

// Contains information about an long-running operation, to make
// requests for the state of an operation.

Timeouts *Timeouts

Result Result
func (a Async) Allow(method string) bool {
return slices.Contains(a.Actions, strings.ToLower(method))
}

// def validate
// check :result, type: Result
// check :timeouts, type: Api::Timeouts
// end
func (a Async) IsA(asyncType string) bool {
return a.Type == asyncType
}

// Base result class
type Result struct {
google.YamlValidator
// The main implementation of Operation,
// corresponding to common GCP Operation resources.
type Operation struct {
Timeouts *Timeouts
OpAsyncOperation `yaml:",inline"`
}

// Contains information about the result of an Operation
// def initialize(path, base_url, wait_ms, timeouts)
func NewOperation() *Operation {
// super()
op := new(Operation)
op.Timeouts = NewTimeouts()
return op
}

ResourceInsideResponse bool `yaml:"resource_inside_response"`
func NewAsync() *Async {
oa := &Async{
Actions: []string{"create", "delete", "update"},
Type: "OpAsync",
Operation: NewOperation(),
}
return oa
}

// def validate
Expand All @@ -73,11 +87,6 @@ type Result struct {

// Represents an asynchronous operation definition
type OpAsync struct {
// TODO: Should embed Async or not?
// < Async

Operation *OpAsyncOperation

Result OpAsyncResult

Status OpAsyncStatus
Expand All @@ -87,16 +96,6 @@ type OpAsync struct {
// If true, include project as an argument to OperationWaitTime.
// It is intended for resources that calculate project/region from a selflink field
IncludeProject bool `yaml:"include_project"`

// The list of methods where operations are used.
Actions []string
}

func NewOpAsync() *OpAsync {
oa := new(OpAsync)
oa.Operation = NewOpAsyncOperation()
oa.Actions = []string{"create", "delete", "update"}
return oa
}

// def initialize(operation, result, status, error)
Expand All @@ -118,11 +117,7 @@ func NewOpAsync() *OpAsync {
// check :include_project, type: :boolean, default: false
// end

// The main implementation of Operation,
// corresponding to common GCP Operation resources.
type OpAsyncOperation struct {
// TODO: Should embed Operation or not?
// < Async::Operation
Kind string

Path string
Expand All @@ -131,20 +126,10 @@ type OpAsyncOperation struct {

WaitMs int `yaml:"wait_ms"`

Timeouts *Timeouts

// Use this if the resource includes the full operation url.
FullUrl string `yaml:"full_url"`
}

// def initialize(path, base_url, wait_ms, timeouts)
func NewOpAsyncOperation() *OpAsyncOperation {
// super()
op := new(OpAsyncOperation)
op.Timeouts = NewTimeouts()
return op
}

// def validate
// super

Expand All @@ -160,7 +145,7 @@ func NewOpAsyncOperation() *OpAsyncOperation {

// Represents the results of an Operation request
type OpAsyncResult struct {
Result Result `yaml:",inline"`
ResourceInsideResponse bool `yaml:"resource_inside_response"`

Path string
}
Expand All @@ -180,7 +165,7 @@ type OpAsyncResult struct {
// Provides information to parse the result response to check operation
// status
type OpAsyncStatus struct {
google.YamlValidator
// google.YamlValidator

Path string

Expand Down Expand Up @@ -222,3 +207,57 @@ type OpAsyncError struct {
// check :path, type: String
// check :message, type: String
// end

// Async implementation for polling in Terraform
type PollAsync struct {
// Details how to poll for an eventually-consistent resource state.

// Function to call for checking the Poll response for
// creating and updating a resource
CheckResponseFuncExistence string `yaml:"check_response_func_existence"`

// Function to call for checking the Poll response for
// deleting a resource
CheckResponseFuncAbsence string `yaml:"check_response_func_absence"`

// Custom code to get a poll response, if needed.
// Will default to same logic as Read() to get current resource
CustomPollRead string `yaml:"custom_poll_read"`

// If true, will suppress errors from polling and default to the
// result of the final Read()
SuppressError bool `yaml:"suppress_error"`

// Number of times the desired state has to occur continuously
// during polling before returning a success
TargetOccurrences int `yaml:"target_occurrences"`
}

func (pa *PollAsync) UnmarshalYAML(n *yaml.Node) error {
pa.CheckResponseFuncAbsence = "transport_tpg.PollCheckForAbsence"
pa.TargetOccurrences = 1

type pollAsyncAlias PollAsync
aliasObj := (*pollAsyncAlias)(pa)

err := n.Decode(&aliasObj)
if err != nil {
return err
}

return nil
}

// return nil
// }

// def validate
// super

// check :check_response_func_existence, type: String, required: true
// check :check_response_func_absence, type: String,
// default: 'transport_tpg.PollCheckForAbsence'
// check :custom_poll_read, type: String
// check :suppress_error, type: :boolean, default: false
// check :target_occurrences, type: Integer, default: 1
// end
18 changes: 3 additions & 15 deletions mmv1/api/async.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,11 @@ class Operation < Google::YamlValidator
# Contains information about an long-running operation, to make
# requests for the state of an operation.
attr_reader :timeouts
attr_reader :result

def validate
check :result, type: Result
check :timeouts, type: Api::Timeouts
end
end

# Base result class
class Result < Google::YamlValidator
# Contains information about the result of an Operation

attr_reader :resource_inside_response

def validate
super
check :resource_inside_response, type: :boolean, default: false
end
end
end

# Represents an asynchronous operation definition
Expand Down Expand Up @@ -127,8 +113,9 @@ def validate
end

# Represents the results of an Operation request
class Result < Async::Result
class Result < Google::YamlValidator
attr_reader :path
attr_reader :resource_inside_response

def initialize(path = nil, resource_inside_response = nil)
super()
Expand All @@ -140,6 +127,7 @@ def validate
super

check :path, type: String
check :resource_inside_response, type: :boolean, default: false
end
end

Expand Down
4 changes: 2 additions & 2 deletions mmv1/api/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ type Product struct {

OperationRetry string `yaml:"operation_retry"`

Async *OpAsync
Async *Async

LegacyName string `yaml:"legacy_name"`

ClientName string `yaml:"client_name"`
}

func (p *Product) UnmarshalYAML(n *yaml.Node) error {
p.Async = NewOpAsync()
p.Async = NewAsync()

type productAlias Product
aliasObj := (*productAlias)(p)
Expand Down
4 changes: 2 additions & 2 deletions mmv1/api/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ type Resource struct {
// Add a deprecation message for a resource that's been deprecated in the API.
DeprecationMessage string `yaml:"deprecation_message"`

Async *OpAsync
Async *Async

Properties []*Type

Expand Down Expand Up @@ -447,7 +447,7 @@ func (r Resource) RootProperties() []*Type {
// if one exists.

// def async
func (r Resource) GetAsync() *OpAsync {
func (r Resource) GetAsync() *Async {
if r.Async != nil {
return r.Async
}
Expand Down
6 changes: 1 addition & 5 deletions mmv1/api/timeouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@

package api

import (
"github.com/GoogleCloudPlatform/magic-modules/mmv1/google"
)

// Default timeout for all operation types is 20, the Terraform default (https://www.terraform.io/plugin/sdkv2/resources/retries-and-customizable-timeouts)
// minutes. This can be overridden for each resource.
const DEFAULT_INSERT_TIMEOUT_MINUTES = 20
Expand All @@ -25,7 +21,7 @@ const DEFAULT_DELETE_TIMEOUT_MINUTES = 20

// Provides timeout information for the different operation types
type Timeouts struct {
google.YamlValidator
// google.YamlValidator
InsertMinutes int `yaml:"insert_minutes"`
UpdateMinutes int `yaml:"update_minutes"`
DeleteMinutes int `yaml:"delete_minutes"`
Expand Down
1 change: 1 addition & 0 deletions mmv1/products/datafusion/go_instance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ timeouts:
delete_minutes: 50
autogen_async: true
async:
type: "OpAsync"
operation:
base_url: '{{op_id}}'
path: 'name'
Expand Down
1 change: 1 addition & 0 deletions mmv1/products/datafusion/go_product.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ versions:
scopes:
- 'https://www.googleapis.com/auth/cloud-platform'
async:
type: "OpAsync"
operation:
base_url: '{{op_id}}'
path: 'name'
Expand Down
1 change: 1 addition & 0 deletions mmv1/products/pubsub/go_Schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ timeouts:
update_minutes: 20
delete_minutes: 20
async:
type: "PollAsync"
check_response_func_existence: 'transport_tpg.PollCheckForExistence'
check_response_func_absence: 'transport_tpg.PollCheckForAbsence'
suppress_error: false
Expand Down
1 change: 1 addition & 0 deletions mmv1/products/pubsub/go_Subscription.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ timeouts:
update_minutes: 20
delete_minutes: 20
async:
type: "PollAsync"
check_response_func_existence: 'transport_tpg.PollCheckForExistence'
check_response_func_absence: 'transport_tpg.PollCheckForAbsence'
suppress_error: true
Expand Down
1 change: 1 addition & 0 deletions mmv1/products/pubsub/go_Topic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ timeouts:
update_minutes: 20
delete_minutes: 20
async:
type: "PollAsync"
check_response_func_existence: 'transport_tpg.PollCheckForExistence'
check_response_func_absence: 'transport_tpg.PollCheckForAbsence'
suppress_error: true
Expand Down

0 comments on commit 4b9acba

Please sign in to comment.