Skip to content

Commit 2b6bbe9

Browse files
authored
Switch to REST API v2 (#44)
1 parent 3f9bd9b commit 2b6bbe9

File tree

542 files changed

+92646
-119720
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

542 files changed

+92646
-119720
lines changed

.circleci/config.yml

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ jobs:
1010
name: Test
1111
command: |
1212
go test -mod=vendor -cover ./...
13+
environment:
14+
TEST_CIRCLECI_ORGANIZATION: test
1315
- run:
1416
name: Build
1517
command: |
@@ -30,6 +32,12 @@ jobs:
3032
root: /terraform-provider-circleci
3133
paths:
3234
- build
35+
lint:
36+
docker:
37+
- image: golangci/golangci-lint:v1.39.0
38+
steps:
39+
- checkout
40+
- golangci-lint run
3341
release:
3442
working_directory: /build
3543
docker:

.golangci.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
linters:
2+
enable:
3+
- gci
4+
- gofmt
5+
- gosec
6+
- misspell
7+
linters-settings:
8+
goimports:
9+
local-prefixes: github.com/mrolla/terraform-provider-circleci

circleci/client.go

-130
This file was deleted.

circleci/client/client.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package client
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"net/url"
7+
8+
"github.com/CircleCI-Public/circleci-cli/api"
9+
10+
"github.com/mrolla/terraform-provider-circleci/circleci/client/rest"
11+
)
12+
13+
// Client provides access to the CircleCI REST API
14+
// It uses upstream client functionality where possible and defines its own methods as needed
15+
type Client struct {
16+
contexts *api.ContextRestClient
17+
rest *rest.Client
18+
vcs string
19+
organization string
20+
}
21+
22+
// Config configures a Client
23+
type Config struct {
24+
URL string
25+
Token string
26+
27+
VCS string
28+
Organization string
29+
}
30+
31+
// New initializes a client object for the provider
32+
func New(config Config) (*Client, error) {
33+
u, err := url.Parse(config.URL)
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
rootURL := fmt.Sprintf("%s://%s", u.Scheme, u.Host)
39+
40+
contexts, err := api.NewContextRestClient(rootURL, u.Path, config.Token)
41+
if err != nil {
42+
return nil, err
43+
}
44+
45+
return &Client{
46+
rest: rest.New(rootURL, u.Path, config.Token),
47+
contexts: contexts,
48+
49+
vcs: config.VCS,
50+
organization: config.Organization,
51+
}, nil
52+
}
53+
54+
// Organization returns the organization for a request. If an organization is provided,
55+
// that is returned. Next, an organization configured in the provider is returned.
56+
// If neither are set, an error is returned.
57+
func (c *Client) Organization(org string) (string, error) {
58+
if org != "" {
59+
return org, nil
60+
}
61+
62+
if c.organization != "" {
63+
return c.organization, nil
64+
}
65+
66+
return "", errors.New("organization is required")
67+
}
68+
69+
// Slug returns a project slug, including the VCS, organization, and project names
70+
func (c *Client) Slug(org, project string) (string, error) {
71+
o, err := c.Organization(org)
72+
if err != nil {
73+
return "", err
74+
}
75+
76+
return fmt.Sprintf("%s/%s/%s", c.vcs, o, project), nil
77+
}
78+
79+
func isNotFound(err error) bool {
80+
var httpError *rest.HTTPError
81+
if errors.As(err, &httpError) && httpError.Code == 404 {
82+
return true
83+
}
84+
85+
return false
86+
}

circleci/client/context.go

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package client
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"net/url"
7+
8+
"github.com/CircleCI-Public/circleci-cli/api"
9+
"github.com/google/uuid"
10+
)
11+
12+
var ErrContextNotFound = errors.New("context not found")
13+
14+
// GetContext gets an existing context by its ID (UUID)
15+
func (c *Client) GetContext(id string) (*api.Context, error) {
16+
req, err := c.rest.NewRequest("GET", &url.URL{Path: fmt.Sprintf("context/%s", id)}, nil)
17+
if err != nil {
18+
return nil, err
19+
}
20+
21+
ctx := &api.Context{}
22+
23+
status, err := c.rest.DoRequest(req, ctx)
24+
if err != nil {
25+
if status == 404 {
26+
return nil, ErrContextNotFound
27+
}
28+
29+
return nil, err
30+
}
31+
32+
return ctx, nil
33+
}
34+
35+
// GetContextByName gets an existing context by its name
36+
func (c *Client) GetContextByName(name, org string) (*api.Context, error) {
37+
o, err := c.Organization(org)
38+
if err != nil {
39+
return nil, err
40+
}
41+
42+
return c.contexts.ContextByName(c.vcs, o, name)
43+
}
44+
45+
// GetContextByIDOrName gets a context by ID if a UUID is specified, and by name otherwise
46+
func (c *Client) GetContextByIDOrName(org, id string) (*api.Context, error) {
47+
if _, uuidErr := uuid.Parse(id); uuidErr == nil {
48+
return c.GetContext(id)
49+
} else {
50+
return c.contexts.ContextByName(c.vcs, org, id)
51+
}
52+
}
53+
54+
type createContextRequest struct {
55+
Name string `json:"name"`
56+
Owner *contextOwner `json:"owner"`
57+
}
58+
59+
type contextOwner struct {
60+
Slug string `json:"slug"`
61+
Type string `json:"type"`
62+
}
63+
64+
// CreateContext creates a new context and returns the created context object
65+
func (c *Client) CreateContext(org, name string) (*api.Context, error) {
66+
org, err := c.Organization(org)
67+
if err != nil {
68+
return nil, err
69+
}
70+
71+
req, err := c.rest.NewRequest("POST", &url.URL{Path: "context"}, &createContextRequest{
72+
Name: name,
73+
Owner: &contextOwner{
74+
Slug: fmt.Sprintf("%s/%s", c.vcs, org),
75+
Type: "organization",
76+
},
77+
})
78+
if err != nil {
79+
return nil, err
80+
}
81+
82+
ctx := &api.Context{}
83+
_, err = c.rest.DoRequest(req, ctx)
84+
if err != nil {
85+
return nil, err
86+
}
87+
88+
return ctx, nil
89+
}
90+
91+
func (c *Client) DeleteContext(id string) error {
92+
return c.contexts.DeleteContext(id)
93+
}
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package client
2+
3+
import "github.com/CircleCI-Public/circleci-cli/api"
4+
5+
// CreateContextEnvironmentVariable creates a new context environment variable
6+
func (c *Client) CreateContextEnvironmentVariable(ctx, variable, value string) error {
7+
return c.contexts.CreateEnvironmentVariable(ctx, variable, value)
8+
}
9+
10+
// ListContextEnvironmentVariables lists all environment variables for a given context
11+
func (c *Client) ListContextEnvironmentVariables(ctx string) (*[]api.EnvironmentVariable, error) {
12+
return c.contexts.EnvironmentVariables(ctx)
13+
}
14+
15+
// HasContextEnvironmentVariable lists all environment variables for a given context and checks whether the specified variable is defined.
16+
// If either the context or the variable does not exist, it returns false.
17+
func (c *Client) HasContextEnvironmentVariable(ctx, variable string) (bool, error) {
18+
envs, err := c.ListContextEnvironmentVariables(ctx)
19+
if err != nil {
20+
if isNotFound(err) {
21+
return false, nil
22+
}
23+
24+
return false, err
25+
}
26+
27+
for _, env := range *envs {
28+
if env.Variable == variable {
29+
return true, nil
30+
}
31+
}
32+
33+
return false, nil
34+
}
35+
36+
// DeleteContextEnvironmentVariable deletes a context environment variable by context ID and name
37+
func (c *Client) DeleteContextEnvironmentVariable(ctx, variable string) error {
38+
return c.contexts.DeleteEnvironmentVariable(ctx, variable)
39+
}

0 commit comments

Comments
 (0)