Skip to content

Commit

Permalink
Adds argocd_repository resource (#17)
Browse files Browse the repository at this point in the history
* support for pre-1.6.0 repository service api client
  • Loading branch information
oboukili authored Jul 8, 2020
1 parent 874105c commit 52e9c9e
Show file tree
Hide file tree
Showing 8 changed files with 407 additions and 19 deletions.
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ provider "argocd" {
auth_token = "1234..." # env ARGOCD_AUTH_TOKEN
# username = "admin" # env ARGOCD_AUTH_USERNAME
# password = "foo" # env ARGOCD_AUTH_PASSWORD
insecure = false # env ARGOCD_INSECURE
insecure = false # env ARGOCD_INSECURE
}
resource "argocd_repository" "nginx_helm" {
repo = "https://helm.nginx.com/stable"
name = "nginx-stable"
type = "helm"
}
resource "argocd_project" "myproject" {
Expand Down Expand Up @@ -157,15 +163,13 @@ resource "argocd_application" "kustomize" {
path = "examples/helloWorld"
target_revision = "master"
kustomize {
name_prefix = "foo-"
name_suffix = "-bar"
images = [
"hashicorp/terraform:light",
]
common_labels = {
"this.is.a.common" = "la-bel"
"another.io/one" = "true"
}
name_prefix = "foo-"
name_suffix = "-bar"
images = ["hashicorp/terraform:light"]
common_labels = {
"this.is.a.common" = "la-bel"
"another.io/one" = "true"
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions argocd/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import (
"github.com/argoproj/argo-cd/pkg/apiclient"
"github.com/argoproj/argo-cd/pkg/apiclient/application"
"github.com/argoproj/argo-cd/pkg/apiclient/project"
"github.com/argoproj/argo-cd/pkg/apiclient/repository"
"github.com/argoproj/argo-cd/pkg/apiclient/version"
)

const (
featureApplicationLevelSyncOptions = iota
featureRepositoryGet
featureTokenIDs
)

var (
featureVersionConstraintsMap = map[int]*semver.Version{
featureApplicationLevelSyncOptions: semver.MustParse("1.5.0"),
featureRepositoryGet: semver.MustParse("1.6.0"),
featureTokenIDs: semver.MustParse("1.5.3"),
}
)
Expand All @@ -25,6 +28,7 @@ type ServerInterface struct {
ApiClient apiclient.Client
ApplicationClient application.ApplicationServiceClient
ProjectClient project.ProjectServiceClient
RepositoryClient repository.RepositoryServiceClient
ServerVersion *semver.Version
ServerVersionMessage *version.VersionMessage
}
Expand Down
18 changes: 17 additions & 1 deletion argocd/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/argoproj/argo-cd/pkg/apiclient"
"github.com/argoproj/argo-cd/pkg/apiclient/application"
"github.com/argoproj/argo-cd/pkg/apiclient/project"
"github.com/argoproj/argo-cd/pkg/apiclient/repository"
"github.com/argoproj/argo-cd/pkg/apiclient/session"
util "github.com/argoproj/gitops-engine/pkg/utils/io"
"github.com/golang/protobuf/ptypes/empty"
Expand Down Expand Up @@ -103,6 +104,7 @@ func Provider(doneCh chan bool) terraform.ResourceProvider {
"argocd_application": resourceArgoCDApplication(),
"argocd_project": resourceArgoCDProject(),
"argocd_project_token": resourceArgoCDProjectToken(),
"argocd_repository": resourceArgoCDRepository(),
},
ConfigureFunc: func(d *schema.ResourceData) (interface{}, error) {
apiClient, err := initApiClient(d)
Expand All @@ -118,13 +120,25 @@ func Provider(doneCh chan bool) terraform.ResourceProvider {
if err != nil {
return nil, err
}

rcCloser, repositoryClient, err := apiClient.NewRepoClient()
if err != nil {
return nil, err
}

// Clients connection pooling, close when the provider execution ends
go func(done chan bool) {
<-done
util.Close(pcCloser)
util.Close(acCloser)
util.Close(rcCloser)
}(doneCh)
return initServerInterface(apiClient, projectClient, applicationClient)
return initServerInterface(
apiClient,
projectClient,
applicationClient,
repositoryClient,
)
},
}
}
Expand All @@ -133,6 +147,7 @@ func initServerInterface(
apiClient apiclient.Client,
projectClient project.ProjectServiceClient,
applicationClient application.ApplicationServiceClient,
repositoryClient repository.RepositoryServiceClient,
) (interface{}, error) {
acCloser, versionClient, err := apiClient.NewVersionClient()
if err != nil {
Expand All @@ -156,6 +171,7 @@ func initServerInterface(
apiClient,
applicationClient,
projectClient,
repositoryClient,
serverVersion,
serverVersionMessage}, err
}
Expand Down
149 changes: 149 additions & 0 deletions argocd/resource_argocd_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package argocd

import (
"context"
"fmt"
"github.com/argoproj/argo-cd/pkg/apiclient/repository"
application "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"strings"
)

func resourceArgoCDRepository() *schema.Resource {
return &schema.Resource{
Create: resourceArgoCDRepositoryCreate,
Read: resourceArgoCDRepositoryRead,
Update: resourceArgoCDRepositoryUpdate,
Delete: resourceArgoCDRepositoryDelete,
// TODO: add importer acceptance tests
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: repositorySchema(),
}
}

func resourceArgoCDRepositoryCreate(d *schema.ResourceData, meta interface{}) error {
server := meta.(ServerInterface)
c := server.RepositoryClient
repo := expandRepository(d)
r, err := c.CreateRepository(
context.Background(),
&repository.RepoCreateRequest{
Repo: repo,
Upsert: false,
CredsOnly: false,
},
)
if err != nil {
return err
}
if r.ConnectionState.Status == application.ConnectionStatusFailed {
return fmt.Errorf(
"could not connect to repository %s: %s",
repo.Repo,
r.ConnectionState.Message,
)
}
d.SetId(r.Repo)
return resourceArgoCDRepositoryRead(d, meta)
}

func resourceArgoCDRepositoryRead(d *schema.ResourceData, meta interface{}) error {
server := meta.(ServerInterface)
c := server.RepositoryClient
r := &application.Repository{}

featureRepositoryGetSupported, err := server.isFeatureSupported(featureRepositoryGet)
if err != nil {
panic(err)
}

switch featureRepositoryGetSupported {
case true:
r, err = c.Get(context.Background(), &repository.RepoQuery{
Repo: d.Id(),
ForceRefresh: false,
})
if err != nil {
switch strings.Contains(err.Error(), "NotFound") {
// Repository has already been deleted in an out-of-band fashion
case true:
d.SetId("")
return nil
default:
return err
}
}
case false:
rl, err := c.ListRepositories(context.Background(), &repository.RepoQuery{
Repo: d.Id(),
ForceRefresh: false,
})
if err != nil {
// TODO: check for NotFound condition?
return err
}
if rl == nil {
// Repository has already been deleted in an out-of-band fashion
d.SetId("")
return nil
}
for i, _r := range rl.Items {
if _r.Repo == d.Id() {
r = _r
break
}
// Repository has already been deleted in an out-of-band fashion
if i == len(rl.Items)-1 {
d.SetId("")
return nil
}
}

}
return flattenRepository(r, d)
}

func resourceArgoCDRepositoryUpdate(d *schema.ResourceData, meta interface{}) error {
server := meta.(ServerInterface)
c := server.RepositoryClient
repo := expandRepository(d)
r, err := c.UpdateRepository(
context.Background(),
&repository.RepoUpdateRequest{Repo: repo},
)
if err != nil {
switch strings.Contains(err.Error(), "NotFound") {
// Repository has already been deleted in an out-of-band fashion
case true:
d.SetId("")
return nil
default:
return err
}
}
if r.ConnectionState.Status == application.ConnectionStatusFailed {
return fmt.Errorf(
"could not connect to repository %s: %s",
repo.Repo,
r.ConnectionState.Message,
)
}
d.SetId(r.Repo)
return resourceArgoCDRepositoryRead(d, meta)
}

func resourceArgoCDRepositoryDelete(d *schema.ResourceData, meta interface{}) error {
server := meta.(ServerInterface)
c := server.RepositoryClient
_, err := c.DeleteRepository(
context.Background(),
&repository.RepoQuery{Repo: d.Id()},
)
if err != nil {
return err
}
d.SetId("")
return nil
}
54 changes: 54 additions & 0 deletions argocd/resource_argocd_repository_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package argocd

import (
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"testing"
)

func TestAccArgoCDRepository(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccArgoCDRepositorySimple(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"argocd_repository.simple",
"connection_state_status",
"Successful",
),
),
},
{
Config: testAccArgoCDRepositoryHelm(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"argocd_repository.helm",
"connection_state_status",
"Successful",
),
),
},
},
})
}

func testAccArgoCDRepositorySimple() string {
return fmt.Sprintf(`
resource "argocd_repository" "simple" {
repo = "https://github.com/kubernetes-sigs/kustomize"
}
`)
}

func testAccArgoCDRepositoryHelm() string {
return fmt.Sprintf(`
resource "argocd_repository" "helm" {
repo = "https://helm.nginx.com/stable"
name = "nginx-stable"
type = "helm"
}
`)
}
Loading

0 comments on commit 52e9c9e

Please sign in to comment.