Skip to content

Commit ec966d2

Browse files
raphinkoboukili
andauthored
Create ArgoCD clients on demand (argoproj-labs#75)
* Use new GNUMakefile to build local binaries for multiple OSes * Create clients on resource demand * Cache clients * fix: add missing scripts/gofmtcheck.sh * fix(provider): avoid inter-locking during client initialization Signed-off-by: Raphaël Pinson <[email protected]> Co-authored-by: Olivier Boukili <[email protected]>
1 parent 304dbc4 commit ec966d2

11 files changed

+496
-112
lines changed

GNUmakefile

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,40 @@
1-
TEST?=$$(go list ./... |grep -v 'vendor')
1+
TEST?=./...
22
GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
3+
PKG_NAME=pass
34

4-
default: build
5+
BINARY=terraform-provider-argocd
6+
VERSION = $(shell git describe --always)
57

6-
fmt:
7-
gofmt -w $(GOFMT_FILES)
8+
default: build-all
9+
10+
build-all: linux windows darwin
811

9-
build: fmt
12+
install: fmtcheck
1013
go install
1114

12-
test: fmt
13-
go test -i $(TEST) || exit 1
14-
echo $(TEST) | \
15-
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
15+
linux: fmtcheck
16+
@mkdir -p bin/
17+
GOOS=linux GOARCH=amd64 go build -v -o bin/$(BINARY)_$(VERSION)_linux_amd64
18+
GOOS=linux GOARCH=386 go build -v -o bin/$(BINARY)_$(VERSION)_linux_x86
19+
20+
windows: fmtcheck
21+
@mkdir -p bin/
22+
GOOS=windows GOARCH=amd64 go build -v -o bin/$(BINARY)_$(VERSION)_windows_amd64
23+
GOOS=windows GOARCH=386 go build -v -o bin/$(BINARY)_$(VERSION)_windows_x86
24+
25+
darwin: fmtcheck
26+
@mkdir -p bin/
27+
GOOS=darwin GOARCH=amd64 go build -v -o bin/$(BINARY)_$(VERSION)_darwin_amd64
28+
GOOS=darwin GOARCH=386 go build -v -o bin/$(BINARY)_$(VERSION)_darwin_x86
29+
30+
release: clean linux windows darwin
31+
for f in $(shell ls bin/); do zip bin/$${f}.zip bin/$${f}; done
32+
33+
clean:
34+
git clean -fXd -e \!vendor -e \!vendor/**/*
35+
36+
test: fmtcheck
37+
go test $(TEST) -timeout=30s -parallel=4
1638

1739
testacc_prepare_env:
1840
sh scripts/testacc_prepare_env.sh
@@ -23,4 +45,31 @@ testacc:
2345
testacc_clean_env:
2446
kind delete cluster --name argocd
2547

26-
.PHONY: build test testacc_prepare_env testacc testacc_clean_env fmt
48+
fmt:
49+
@echo "==> Fixing source code with gofmt..."
50+
gofmt -s -w ./$(PKG_NAME)
51+
52+
# Currently required by tf-deploy compile
53+
fmtcheck:
54+
@sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'"
55+
56+
lint:
57+
@echo "==> Checking source code against linters..."
58+
@GOGC=30 golangci-lint run ./$(PKG_NAME)
59+
60+
test-compile:
61+
@if [ "$(TEST)" = "./..." ]; then \
62+
echo "ERROR: Set TEST to a specific package. For example,"; \
63+
echo " make test-compile TEST=./$(PKG_NAME)"; \
64+
exit 1; \
65+
fi
66+
go test -c $(TEST) $(TESTARGS)
67+
68+
vendor:
69+
go mod tidy
70+
go mod vendor
71+
72+
vet:
73+
go vet $<
74+
75+
.PHONY: build test testacc_prepare_env testacc testacc_clean_env fmt fmtcheck lint test-compile vendor

argocd/features.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package argocd
22

33
import (
4+
"context"
45
"fmt"
6+
"sync"
7+
58
"github.com/Masterminds/semver"
69
"github.com/argoproj/argo-cd/v2/pkg/apiclient"
710
"github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
@@ -10,6 +13,9 @@ import (
1013
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds"
1114
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
1215
"github.com/argoproj/argo-cd/v2/pkg/apiclient/version"
16+
"github.com/argoproj/argo-cd/v2/util/io"
17+
"github.com/golang/protobuf/ptypes/empty"
18+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1319
)
1420

1521
const (
@@ -35,6 +41,92 @@ type ServerInterface struct {
3541
RepoCredsClient *repocreds.RepoCredsServiceClient
3642
ServerVersion *semver.Version
3743
ServerVersionMessage *version.VersionMessage
44+
ProviderData *schema.ResourceData
45+
46+
sync.Mutex
47+
initialized bool
48+
}
49+
50+
func (p *ServerInterface) initClients() error {
51+
if p.initialized {
52+
return nil
53+
}
54+
55+
d := p.ProviderData
56+
57+
p.Lock()
58+
defer p.Unlock()
59+
60+
if p.ApiClient == nil {
61+
apiClient, err := initApiClient(d)
62+
if err != nil {
63+
return err
64+
}
65+
p.ApiClient = &apiClient
66+
}
67+
68+
if p.ClusterClient == nil {
69+
_, clusterClient, err := (*p.ApiClient).NewClusterClient()
70+
if err != nil {
71+
return err
72+
}
73+
p.ClusterClient = &clusterClient
74+
}
75+
76+
if p.ApplicationClient == nil {
77+
_, applicationClient, err := (*p.ApiClient).NewApplicationClient()
78+
if err != nil {
79+
return err
80+
}
81+
p.ApplicationClient = &applicationClient
82+
}
83+
84+
if p.ProjectClient == nil {
85+
_, projectClient, err := (*p.ApiClient).NewProjectClient()
86+
if err != nil {
87+
return err
88+
}
89+
p.ProjectClient = &projectClient
90+
}
91+
92+
if p.RepositoryClient == nil {
93+
_, repositoryClient, err := (*p.ApiClient).NewRepoClient()
94+
if err != nil {
95+
return err
96+
}
97+
p.RepositoryClient = &repositoryClient
98+
}
99+
100+
if p.RepoCredsClient == nil {
101+
_, repoCredsClient, err := (*p.ApiClient).NewRepoCredsClient()
102+
if err != nil {
103+
return err
104+
}
105+
p.RepoCredsClient = &repoCredsClient
106+
}
107+
108+
acCloser, versionClient, err := (*p.ApiClient).NewVersionClient()
109+
if err != nil {
110+
return err
111+
}
112+
defer io.Close(acCloser)
113+
114+
serverVersionMessage, err := versionClient.Version(context.Background(), &empty.Empty{})
115+
if err != nil {
116+
return err
117+
}
118+
if serverVersionMessage == nil {
119+
return fmt.Errorf("could not get server version information")
120+
}
121+
p.ServerVersionMessage = serverVersionMessage
122+
serverVersion, err := semver.NewVersion(serverVersionMessage.Version)
123+
if err != nil {
124+
return fmt.Errorf("could not parse server semantic version: %s", serverVersionMessage.Version)
125+
}
126+
p.ServerVersion = serverVersion
127+
128+
p.initialized = true
129+
return nil
38130
}
39131

40132
// Checks that a specific feature is available for the current ArgoCD server version.

argocd/provider.go

Lines changed: 3 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,11 @@ package argocd
22

33
import (
44
"context"
5-
"fmt"
65
"sync"
76

8-
"github.com/Masterminds/semver"
97
"github.com/argoproj/argo-cd/v2/pkg/apiclient"
10-
"github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
11-
"github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
12-
"github.com/argoproj/argo-cd/v2/pkg/apiclient/project"
13-
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds"
14-
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
158
"github.com/argoproj/argo-cd/v2/pkg/apiclient/session"
169
"github.com/argoproj/argo-cd/v2/util/io"
17-
"github.com/golang/protobuf/ptypes/empty"
1810
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1911
)
2012

@@ -122,80 +114,12 @@ func Provider() *schema.Provider {
122114
"argocd_repository_credentials": resourceArgoCDRepositoryCredentials(),
123115
},
124116
ConfigureFunc: func(d *schema.ResourceData) (interface{}, error) {
125-
apiClient, err := initApiClient(d)
126-
if err != nil {
127-
return nil, err
128-
}
129-
_, clusterClient, err := apiClient.NewClusterClient()
130-
if err != nil {
131-
return nil, err
132-
}
133-
_, applicationClient, err := apiClient.NewApplicationClient()
134-
if err != nil {
135-
return nil, err
136-
}
137-
_, projectClient, err := apiClient.NewProjectClient()
138-
if err != nil {
139-
return nil, err
140-
}
141-
_, repositoryClient, err := apiClient.NewRepoClient()
142-
if err != nil {
143-
return nil, err
144-
}
145-
146-
_, repoCredsClient, err := apiClient.NewRepoCredsClient()
147-
if err != nil {
148-
return nil, err
149-
}
150-
return initServerInterface(
151-
apiClient,
152-
applicationClient,
153-
clusterClient,
154-
projectClient,
155-
repositoryClient,
156-
repoCredsClient,
157-
)
117+
server := ServerInterface{ProviderData: d}
118+
return &server, nil
158119
},
159120
}
160121
}
161122

162-
func initServerInterface(
163-
apiClient apiclient.Client,
164-
applicationClient application.ApplicationServiceClient,
165-
clusterClient cluster.ClusterServiceClient,
166-
projectClient project.ProjectServiceClient,
167-
repositoryClient repository.RepositoryServiceClient,
168-
repoCredsClient repocreds.RepoCredsServiceClient,
169-
) (interface{}, error) {
170-
acCloser, versionClient, err := apiClient.NewVersionClient()
171-
if err != nil {
172-
return nil, err
173-
}
174-
defer io.Close(acCloser)
175-
176-
serverVersionMessage, err := versionClient.Version(context.Background(), &empty.Empty{})
177-
if err != nil {
178-
return nil, err
179-
}
180-
if serverVersionMessage == nil {
181-
return nil, fmt.Errorf("could not get server version information")
182-
}
183-
serverVersion, err := semver.NewVersion(serverVersionMessage.Version)
184-
if err != nil {
185-
return nil, fmt.Errorf("could not parse server semantic version: %s", serverVersionMessage.Version)
186-
}
187-
188-
return ServerInterface{
189-
&apiClient,
190-
&applicationClient,
191-
&clusterClient,
192-
&projectClient,
193-
&repositoryClient,
194-
&repoCredsClient,
195-
serverVersion,
196-
serverVersionMessage}, err
197-
}
198-
199123
func initApiClient(d *schema.ResourceData) (
200124
apiClient apiclient.Client,
201125
err error) {
@@ -205,6 +129,7 @@ func initApiClient(d *schema.ResourceData) (
205129
if v, ok := d.GetOk("server_addr"); ok {
206130
opts.ServerAddr = v.(string)
207131
}
132+
208133
if v, ok := d.GetOk("plain_text"); ok {
209134
opts.PlainText = v.(bool)
210135
}

argocd/resource_argocd_application.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,16 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData
4848
if diags != nil {
4949
return diags
5050
}
51-
server := meta.(ServerInterface)
51+
server := meta.(*ServerInterface)
52+
if err := server.initClients(); err != nil {
53+
return []diag.Diagnostic{
54+
{
55+
Severity: diag.Error,
56+
Summary: fmt.Sprintf("Failed to init clients"),
57+
Detail: err.Error(),
58+
},
59+
}
60+
}
5261
c := *server.ApplicationClient
5362
app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
5463
Name: &objectMeta.Name,
@@ -154,7 +163,16 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData
154163
}
155164

156165
func resourceArgoCDApplicationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
157-
server := meta.(ServerInterface)
166+
server := meta.(*ServerInterface)
167+
if err := server.initClients(); err != nil {
168+
return []diag.Diagnostic{
169+
{
170+
Severity: diag.Error,
171+
Summary: fmt.Sprintf("Failed to init clients"),
172+
Detail: err.Error(),
173+
},
174+
}
175+
}
158176
c := *server.ApplicationClient
159177
appName := d.Id()
160178
app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
@@ -193,7 +211,16 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData
193211
if diags != nil {
194212
return diags
195213
}
196-
server := meta.(ServerInterface)
214+
server := meta.(*ServerInterface)
215+
if err := server.initClients(); err != nil {
216+
return []diag.Diagnostic{
217+
{
218+
Severity: diag.Error,
219+
Summary: fmt.Sprintf("Failed to init clients"),
220+
Detail: err.Error(),
221+
},
222+
}
223+
}
197224
c := *server.ApplicationClient
198225
appRequest := &applicationClient.ApplicationUpdateRequest{
199226
Application: &application.Application{
@@ -278,7 +305,16 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData
278305
}
279306

280307
func resourceArgoCDApplicationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
281-
server := meta.(ServerInterface)
308+
server := meta.(*ServerInterface)
309+
if err := server.initClients(); err != nil {
310+
return []diag.Diagnostic{
311+
{
312+
Severity: diag.Error,
313+
Summary: fmt.Sprintf("Failed to init clients"),
314+
Detail: err.Error(),
315+
},
316+
}
317+
}
282318
c := *server.ApplicationClient
283319
appName := d.Id()
284320
_, err := c.Delete(ctx, &applicationClient.ApplicationDeleteRequest{

0 commit comments

Comments
 (0)