mmv1/api/async.go (80 lines of code) (raw):

// Copyright 2024 Google Inc. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package api import ( "log" "strings" "golang.org/x/exp/slices" ) // Base class from which other Async classes can inherit. type Async struct { // 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 `yaml:",inline"` PollAsync `yaml:",inline"` } func (a Async) Allow(method string) bool { return slices.Contains(a.Actions, strings.ToLower(method)) } func (a Async) IsA(asyncType string) bool { return a.Type == asyncType } // The main implementation of Operation, // corresponding to common GCP Operation resources. type Operation struct { Timeouts *Timeouts OpAsyncOperation `yaml:",inline"` } func NewOperation() *Operation { op := new(Operation) op.Timeouts = NewTimeouts() return op } // It is only used in openapi-generate func NewAsync() *Async { oa := &Async{ Actions: []string{"create", "delete", "update"}, Type: "OpAsync", Operation: NewOperation(), } return oa } // Represents an asynchronous operation definition type OpAsync struct { Result OpAsyncResult // 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"` } type OpAsyncOperation struct { BaseUrl string `yaml:"base_url,omitempty"` // Use this if the resource includes the full operation url. FullUrl string `yaml:"full_url,omitempty"` } // Represents the results of an Operation request type OpAsyncResult struct { ResourceInsideResponse bool `yaml:"resource_inside_response,omitempty"` } // 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,omitempty"` // Function to call for checking the Poll response for // deleting a resource CheckResponseFuncAbsence string `yaml:"check_response_func_absence,omitempty"` // If true, will suppress errors from polling and default to the // result of the final Read() SuppressError bool `yaml:"suppress_error,omitempty"` // Number of times the desired state has to occur continuously // during polling before returning a success TargetOccurrences int `yaml:"target_occurrences,omitempty"` } func (a *Async) UnmarshalYAML(unmarshal func(any) error) error { a.Actions = []string{"create", "delete", "update"} type asyncAlias Async aliasObj := (*asyncAlias)(a) err := unmarshal(aliasObj) if err != nil { return err } if a.Type == "" { a.Type = "OpAsync" } if a.Type == "PollAsync" && a.TargetOccurrences == 0 { a.TargetOccurrences = 1 } return nil } func (a *Async) Validate() { if a.Type == "OpAsync" { if a.Operation == nil { log.Fatalf("Missing `Operation` for OpAsync") } else { if a.Operation.BaseUrl != "" && a.Operation.FullUrl != "" { log.Fatalf("`base_url` and `full_url` cannot be set at the same time in OpAsync operation.") } } } }