forked from sbehl27-org/terraform-provider-cidr-reservator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgcpConnector.go
executable file
·145 lines (132 loc) · 4.23 KB
/
gcpConnector.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
139
140
141
142
143
144
145
package connector
import (
"cloud.google.com/go/storage"
"context"
"encoding/json"
"errors"
"fmt"
"github.com/hashicorp/terraform-plugin-log/tflog"
"io"
"strings"
"time"
"os"
"google.golang.org/api/option"
"golang.org/x/oauth2"
)
type GcpConnector struct {
BucketName string
BaseCidrRange string
FileName string
generation int64
}
type NetworkConfig struct {
Subnets map[string]string `json:"subnets"`
}
func New(bucketName string, baseCidr string) GcpConnector {
fileName := fmt.Sprintf("cidr-reservation/baseCidr-%s.json", strings.Replace(strings.Replace(baseCidr, ".", "-", -1), "/", "-", -1))
return GcpConnector{bucketName, baseCidr, fileName, -1}
}
func getStorageClient(ctx context.Context) (*storage.Client, error) {
access_token := os.Getenv("GOOGLE_OAUTH_ACCESS_TOKEN")
if access_token!= "" {
var tokenSource oauth2.TokenSource
var credOptions []option.ClientOption
tokenSource = oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: access_token,
})
credOptions = append(credOptions, option.WithTokenSource(tokenSource))
return storage.NewClient(ctx, credOptions...)
} else {
return storage.NewClient(ctx)
}
}
func (gcp *GcpConnector) ReadRemote(ctx context.Context) (*NetworkConfig, error) {
// Creates a client.
networkConfig := NetworkConfig{}
client, err := getStorageClient(ctx)
if err != nil {
return &networkConfig, err
}
defer client.Close()
// Creates a Bucket instance.
bucket := client.Bucket(gcp.BucketName)
if err != nil {
return nil, err
}
objectHandle := bucket.Object(gcp.FileName)
attrs, err := objectHandle.Attrs(ctx)
if err == nil {
gcp.generation = attrs.Generation
}
rc, err := objectHandle.NewReader(ctx)
if err != nil {
return &networkConfig, err
}
defer rc.Close()
slurp, err := io.ReadAll(rc)
if err != nil {
return &networkConfig, err
}
if err := json.Unmarshal(slurp, &networkConfig); err != nil {
return &networkConfig, err
}
return &networkConfig, nil
}
func (gcp *GcpConnector) WriteRemote(networkConfig *NetworkConfig, ctx context.Context) error {
// Creates a client.
client, err := getStorageClient(ctx)
if err != nil {
return err
}
defer client.Close()
// Creates a Bucket instance.
bucket := client.Bucket(gcp.BucketName)
var writer *storage.Writer
if gcp.generation == -1 {
writer = bucket.Object(gcp.FileName).If(storage.Conditions{DoesNotExist: true}).NewWriter(ctx)
} else {
writer = bucket.Object(gcp.FileName).If(storage.Conditions{GenerationMatch: gcp.generation}).NewWriter(ctx)
}
marshalled, err := json.Marshal(networkConfig)
if err != nil {
return err
}
_, _ = writer.Write(marshalled)
if err := writer.Close(); err != nil {
tflog.Error(ctx, "Failed to write file to GCP", map[string]interface{}{"error": err, "generation": gcp.generation})
return err
}
return nil
}
//func (gcp GcpConnector) lockCidrProviderJson(bucket *storage.BucketHandle, bucketFile string, ctx context.Context) error {
// writer := bucket.Object(fmt.Sprintf("%s.lock", bucketFile)).If(storage.Conditions{GenerationMatch: 0}).NewWriter(ctx)
// defer writer.Close()
// return gcp.recursiveTryLock(writer, 0)
//}
func (gcp *GcpConnector) RecursiveRetryReadWrite(ctx context.Context, retryCount int8) error {
if retryCount > 4 {
return errors.New("Failed to write file after 4 retries!!!")
}
networkConfig, err := gcp.ReadRemote(ctx)
if err != nil {
sleepDuration, _ := time.ParseDuration(fmt.Sprintf("%ds", 2*retryCount))
time.Sleep(sleepDuration)
return gcp.RecursiveRetryReadWrite(ctx, retryCount+1)
}
sleepDuration, _ := time.ParseDuration(fmt.Sprintf("%ds", 2*retryCount))
time.Sleep(sleepDuration)
err = gcp.WriteRemote(networkConfig, ctx)
if err != nil {
return gcp.RecursiveRetryReadWrite(ctx, retryCount+1)
}
return nil
}
//func (gcp GcpConnector) deleteLock(bucket *storage.BucketHandle, bucketFile string, ctx context.Context) {
// bucket.Object(fmt.Sprintf("%s.lock", bucketFile)).Delete(ctx)
//}
func readNetsegmentJson(ctx context.Context, cidrProviderBucket string, netsegmentName string) (NetworkConfig, error) {
return NetworkConfig{}, nil
//return readRemote(cidrProviderBucket, fmt.Sprintf("gcp-cidr-provider/%s.json", netsegmentName), ctx)
}
// TODO: implement!
func uploadNewNetsegmentJson() {}