generated from crossplane/provider-template
/
utils.go
138 lines (123 loc) · 3.44 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package utils
import (
"context"
"fmt"
"reflect"
"strings"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
)
// DepthQueryParam is used in GET requests in Cloud API
const DepthQueryParam = int32(1)
// DereferenceOrZero returns the value of a pointer or a zero value if the pointer is nil.
func DereferenceOrZero[T any](v *T) T {
if v == nil {
return *new(T)
}
return *v
}
// IsEmptyValue checks if a value is empty or not.
// nolint
func IsEmptyValue(v reflect.Value) bool {
switch v.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
return v.Len() == 0
case reflect.Bool:
return !v.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Interface, reflect.Ptr:
return v.IsNil()
case reflect.Struct:
return v.IsZero()
}
return false
}
// IsEqStringSlices will return true if the slices are equal
// (having the same length, and the same value at the same index)
func IsEqStringSlices(first, second []string) bool {
if len(first) != len(second) {
return false
}
for i, v := range first {
if v != second[i] {
return false
}
}
return true
}
// IsEqStringMaps will return true if the maps are equal
func IsEqStringMaps(first, second map[string]string) bool {
if len(first) != len(second) {
return false
}
for firstKey, firstValue := range first {
if secondValue, ok := second[firstKey]; !ok || secondValue != firstValue {
return false
}
}
return true
}
// IsStringInSlice will return true if the slice contains the specific string
func IsStringInSlice(input []string, specific string) bool {
for _, element := range input {
if element == specific {
return true
}
}
return false
}
// ContainsStringSlices will return true if the slices
// have the same length and the same elements, even if
// they are located at different indexes.
func ContainsStringSlices(first, second []string) bool {
if len(first) != len(second) {
return false
}
if len(first) == 0 {
return true
}
for _, v := range first {
if !ContainsStringInSlice(second, v) {
return false
}
}
return true
}
// ContainsStringInSlice will return true if the slice contains string
func ContainsStringInSlice(input []string, specific string) bool {
for _, element := range input {
if strings.Contains(element, specific) {
return true
}
}
return false
}
// IsResourceDeletedFunc polls api to see if resource exists based on id
type IsResourceDeletedFunc func(ctx context.Context, ids ...string) (bool, error)
// WaitForResourceToBeDeleted - keeps retrying until resource is not found(404), or until ctx is cancelled
func WaitForResourceToBeDeleted(ctx context.Context, timeoutInMinutes time.Duration, fn IsResourceDeletedFunc, ids ...string) error {
err := retry.RetryContext(ctx, timeoutInMinutes, func() *retry.RetryError {
isDeleted, err := fn(ctx, ids...)
if isDeleted {
return nil
}
if err != nil {
retry.NonRetryableError(err)
}
return retry.RetryableError(fmt.Errorf("resource with ids %v found, still trying ", ids))
})
return err
}
// MapStringToAny converts map[string]string to map[string]any
func MapStringToAny(sMap map[string]string) map[string]any {
aMap := make(map[string]any)
for k, v := range sMap {
aMap[k] = v
}
return aMap
}