packer-cn/vendor/github.com/oracle/oci-go-sdk/example/helpers/helper.go

112 lines
2.6 KiB
Go

// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
//
// Helper methods for OCI GOSDK Samples
//
package helpers
import (
"fmt"
"log"
"math/rand"
"reflect"
"strings"
"time"
)
// LogIfError is equivalent to Println() followed by a call to os.Exit(1) if error is not nil
func LogIfError(err error) {
if err != nil {
log.Fatalln(err.Error())
}
}
// RetryUntilTrueOrError retries a function until the predicate is true or it reaches a timeout.
// The operation is retried at the give frequency
func RetryUntilTrueOrError(operation func() (interface{}, error), predicate func(interface{}) (bool, error), frequency, timeout <-chan time.Time) error {
for {
select {
case <-timeout:
return fmt.Errorf("timeout reached")
case <-frequency:
result, err := operation()
if err != nil {
return err
}
isTrue, err := predicate(result)
if err != nil {
return err
}
if isTrue {
return nil
}
}
}
}
// FindLifecycleFieldValue finds lifecycle value inside the struct based on reflection
func FindLifecycleFieldValue(request interface{}) (string, error) {
val := reflect.ValueOf(request)
if val.Kind() == reflect.Ptr {
if val.IsNil() {
return "", fmt.Errorf("can not unmarshal to response a pointer to nil structure")
}
val = val.Elem()
}
var err error
typ := val.Type()
for i := 0; i < typ.NumField(); i++ {
if err != nil {
return "", err
}
sf := typ.Field(i)
//unexported
if sf.PkgPath != "" {
continue
}
sv := val.Field(i)
if sv.Kind() == reflect.Struct {
lif, err := FindLifecycleFieldValue(sv.Interface())
if err == nil {
return lif, nil
}
}
if !strings.Contains(strings.ToLower(sf.Name), "lifecyclestate") {
continue
}
return sv.String(), nil
}
return "", fmt.Errorf("request does not have a lifecycle field")
}
// CheckLifecycleState returns a function that checks for that a struct has the given lifecycle
func CheckLifecycleState(lifecycleState string) func(interface{}) (bool, error) {
return func(request interface{}) (bool, error) {
fieldLifecycle, err := FindLifecycleFieldValue(request)
if err != nil {
return false, err
}
isEqual := fieldLifecycle == lifecycleState
log.Printf("Current lifecycle state is: %s, waiting for it becomes to: %s", fieldLifecycle, lifecycleState)
return isEqual, nil
}
}
// GetRandomString returns a random string with length equals to n
func GetRandomString(n int) string {
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}