Skip to content

Commit

Permalink
Switch to REST API v2 (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
bendrucker authored May 6, 2021
1 parent 3f9bd9b commit 2b6bbe9
Show file tree
Hide file tree
Showing 542 changed files with 92,646 additions and 119,720 deletions.
8 changes: 8 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ jobs:
name: Test
command: |
go test -mod=vendor -cover ./...
environment:
TEST_CIRCLECI_ORGANIZATION: test
- run:
name: Build
command: |
Expand All @@ -30,6 +32,12 @@ jobs:
root: /terraform-provider-circleci
paths:
- build
lint:
docker:
- image: golangci/golangci-lint:v1.39.0
steps:
- checkout
- golangci-lint run
release:
working_directory: /build
docker:
Expand Down
9 changes: 9 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
linters:
enable:
- gci
- gofmt
- gosec
- misspell
linters-settings:
goimports:
local-prefixes: github.com/mrolla/terraform-provider-circleci
130 changes: 0 additions & 130 deletions circleci/client.go

This file was deleted.

86 changes: 86 additions & 0 deletions circleci/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package client

import (
"errors"
"fmt"
"net/url"

"github.com/CircleCI-Public/circleci-cli/api"

"github.com/mrolla/terraform-provider-circleci/circleci/client/rest"
)

// Client provides access to the CircleCI REST API
// It uses upstream client functionality where possible and defines its own methods as needed
type Client struct {
contexts *api.ContextRestClient
rest *rest.Client
vcs string
organization string
}

// Config configures a Client
type Config struct {
URL string
Token string

VCS string
Organization string
}

// New initializes a client object for the provider
func New(config Config) (*Client, error) {
u, err := url.Parse(config.URL)
if err != nil {
return nil, err
}

rootURL := fmt.Sprintf("%s://%s", u.Scheme, u.Host)

contexts, err := api.NewContextRestClient(rootURL, u.Path, config.Token)
if err != nil {
return nil, err
}

return &Client{
rest: rest.New(rootURL, u.Path, config.Token),
contexts: contexts,

vcs: config.VCS,
organization: config.Organization,
}, nil
}

// Organization returns the organization for a request. If an organization is provided,
// that is returned. Next, an organization configured in the provider is returned.
// If neither are set, an error is returned.
func (c *Client) Organization(org string) (string, error) {
if org != "" {
return org, nil
}

if c.organization != "" {
return c.organization, nil
}

return "", errors.New("organization is required")
}

// Slug returns a project slug, including the VCS, organization, and project names
func (c *Client) Slug(org, project string) (string, error) {
o, err := c.Organization(org)
if err != nil {
return "", err
}

return fmt.Sprintf("%s/%s/%s", c.vcs, o, project), nil
}

func isNotFound(err error) bool {
var httpError *rest.HTTPError
if errors.As(err, &httpError) && httpError.Code == 404 {
return true
}

return false
}
93 changes: 93 additions & 0 deletions circleci/client/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package client

import (
"errors"
"fmt"
"net/url"

"github.com/CircleCI-Public/circleci-cli/api"
"github.com/google/uuid"
)

var ErrContextNotFound = errors.New("context not found")

// GetContext gets an existing context by its ID (UUID)
func (c *Client) GetContext(id string) (*api.Context, error) {
req, err := c.rest.NewRequest("GET", &url.URL{Path: fmt.Sprintf("context/%s", id)}, nil)
if err != nil {
return nil, err
}

ctx := &api.Context{}

status, err := c.rest.DoRequest(req, ctx)
if err != nil {
if status == 404 {
return nil, ErrContextNotFound
}

return nil, err
}

return ctx, nil
}

// GetContextByName gets an existing context by its name
func (c *Client) GetContextByName(name, org string) (*api.Context, error) {
o, err := c.Organization(org)
if err != nil {
return nil, err
}

return c.contexts.ContextByName(c.vcs, o, name)
}

// GetContextByIDOrName gets a context by ID if a UUID is specified, and by name otherwise
func (c *Client) GetContextByIDOrName(org, id string) (*api.Context, error) {
if _, uuidErr := uuid.Parse(id); uuidErr == nil {
return c.GetContext(id)
} else {
return c.contexts.ContextByName(c.vcs, org, id)
}
}

type createContextRequest struct {
Name string `json:"name"`
Owner *contextOwner `json:"owner"`
}

type contextOwner struct {
Slug string `json:"slug"`
Type string `json:"type"`
}

// CreateContext creates a new context and returns the created context object
func (c *Client) CreateContext(org, name string) (*api.Context, error) {
org, err := c.Organization(org)
if err != nil {
return nil, err
}

req, err := c.rest.NewRequest("POST", &url.URL{Path: "context"}, &createContextRequest{
Name: name,
Owner: &contextOwner{
Slug: fmt.Sprintf("%s/%s", c.vcs, org),
Type: "organization",
},
})
if err != nil {
return nil, err
}

ctx := &api.Context{}
_, err = c.rest.DoRequest(req, ctx)
if err != nil {
return nil, err
}

return ctx, nil
}

func (c *Client) DeleteContext(id string) error {
return c.contexts.DeleteContext(id)
}
39 changes: 39 additions & 0 deletions circleci/client/context_environment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package client

import "github.com/CircleCI-Public/circleci-cli/api"

// CreateContextEnvironmentVariable creates a new context environment variable
func (c *Client) CreateContextEnvironmentVariable(ctx, variable, value string) error {
return c.contexts.CreateEnvironmentVariable(ctx, variable, value)
}

// ListContextEnvironmentVariables lists all environment variables for a given context
func (c *Client) ListContextEnvironmentVariables(ctx string) (*[]api.EnvironmentVariable, error) {
return c.contexts.EnvironmentVariables(ctx)
}

// HasContextEnvironmentVariable lists all environment variables for a given context and checks whether the specified variable is defined.
// If either the context or the variable does not exist, it returns false.
func (c *Client) HasContextEnvironmentVariable(ctx, variable string) (bool, error) {
envs, err := c.ListContextEnvironmentVariables(ctx)
if err != nil {
if isNotFound(err) {
return false, nil
}

return false, err
}

for _, env := range *envs {
if env.Variable == variable {
return true, nil
}
}

return false, nil
}

// DeleteContextEnvironmentVariable deletes a context environment variable by context ID and name
func (c *Client) DeleteContextEnvironmentVariable(ctx, variable string) error {
return c.contexts.DeleteEnvironmentVariable(ctx, variable)
}
Loading

0 comments on commit 2b6bbe9

Please sign in to comment.