Skip to content

Commit

Permalink
Merge pull request #596 from CircleCI-Public/configure-tls
Browse files Browse the repository at this point in the history
Allow users to specify self-signed certificates or ignore TLS verification
  • Loading branch information
kelvinkfli authored Jun 10, 2021
2 parents 605a617 + 9b2e018 commit 850f9ac
Show file tree
Hide file tree
Showing 23 changed files with 291 additions and 96 deletions.
9 changes: 4 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ commands:
# https://app.circleci.com/jobs/github/CircleCI-Public/circleci-cli/6480
# curl: (92) HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)
# The issue seems to be on the server-side, so force HTTP 1.1
name: 'cURL: Force HTTP 1.1'
name: "cURL: Force HTTP 1.1"
command: echo '--http1.1' >> ~/.curlrc
build-docker-image:
steps:
Expand Down Expand Up @@ -79,7 +79,7 @@ commands:
- save_cache:
key: v2-gomod-{{ arch }}-{{ checksum "go.sum" }}
paths:
- /go/pkg/mod # Linux
- /go/pkg/mod # Linux
- ~/go/pkg/mod # macOS

jobs:
Expand All @@ -104,8 +104,8 @@ jobs:
steps:
- checkout
- run: |
brew install go@1.12
echo 'export PATH="/usr/local/opt/go@1.12/bin:$PATH"' >> ~/.bash_profile
brew install go@1.13
echo 'export PATH="/usr/local/opt/go@1.13/bin:$PATH"' >> ~/.bash_profile
- gomod
- run: make test
build:
Expand Down Expand Up @@ -339,4 +339,3 @@ workflows:
filters:
branches:
only: master

14 changes: 7 additions & 7 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ package api

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"sort"
"strings"

"fmt"

"github.com/CircleCI-Public/circleci-cli/api/graphql"
"github.com/CircleCI-Public/circleci-cli/pipeline"
"github.com/CircleCI-Public/circleci-cli/references"
"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/Masterminds/semver"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -1824,17 +1824,17 @@ func ListOrbCategories(cl *graphql.Client) (*OrbCategoriesForListing, error) {

// FollowProject initiates an API request to follow a specific project on
// CircleCI. Project slugs are case-sensitive.
func FollowProject(restEndpoint string, vcs string, owner string, projectName string, cciToken string) (FollowedProject, error) {
requestPath := fmt.Sprintf("%s/api/v1.1/project/%s/%s/%s/follow", restEndpoint, vcs, owner, projectName)
func FollowProject(config settings.Config, vcs string, owner string, projectName string) (FollowedProject, error) {
requestPath := fmt.Sprintf("%s/api/v1.1/project/%s/%s/%s/follow", config.Endpoint, vcs, owner, projectName)
r, err := http.NewRequest(http.MethodPost, requestPath, nil)
if err != nil {
return FollowedProject{}, err
}
r.Header.Set("Content-Type", "application/json; charset=utf-8")
r.Header.Set("Accept", "application/json; charset=utf-8")
r.Header.Set("Circle-Token", cciToken)
client := http.Client{}
response, err := client.Do(r)
r.Header.Set("Circle-Token", config.Token)

response, err := config.HTTPClient.Do(r)
if err != nil {
return FollowedProject{}, err
}
Expand Down
19 changes: 10 additions & 9 deletions api/context_graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api

import (
"fmt"
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -47,7 +48,7 @@ func improveVcsTypeError(err error) error {
}

// CreateContext creates a new Context in the supplied organization.
func (c *GraphQLContextClient) CreateContext(vcsType, orgName, contextName string) (error) {
func (c *GraphQLContextClient) CreateContext(vcsType, orgName, contextName string) error {
cl := c.Client

org, err := getOrganization(cl, orgName, vcsType)
Expand Down Expand Up @@ -107,7 +108,7 @@ func (c *GraphQLContextClient) CreateContext(vcsType, orgName, contextName strin
// ContextByName returns the Context in the given organization with the given
// name.
func (c *GraphQLContextClient) ContextByName(vcs, org, name string) (*Context, error) {
contexts , err := c.Contexts(vcs, org)
contexts, err := c.Contexts(vcs, org)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -135,8 +136,8 @@ func (c *GraphQLContextClient) EnvironmentVariables(contextID string) (*[]Enviro
request := graphql.NewRequest(query)
request.SetToken(cl.Token)
request.Var("id", contextID)
var resp struct{
Context struct{
var resp struct {
Context struct {
Resources []EnvironmentVariable
}
}
Expand Down Expand Up @@ -216,15 +217,15 @@ func (c *GraphQLContextClient) Contexts(vcsType, orgName string) (*[]Context, er
return nil, errors.Wrapf(improveVcsTypeError(err), "failed to load context list")
}
var contexts []Context
for _, edge := range response.Organization.Contexts.Edges {
for _, edge := range response.Organization.Contexts.Edges {
context := edge.Node
created_at, err := time.Parse(time.RFC3339, context.CreatedAt)
if err != nil {
return nil, err
}
contexts = append(contexts, Context{
Name: context.Name,
ID: context.ID,
Name: context.Name,
ID: context.ID,
CreatedAt: created_at,
})
}
Expand Down Expand Up @@ -372,8 +373,8 @@ func (c *GraphQLContextClient) DeleteContext(contextId string) error {

// NewContextGraphqlClient returns a new client satisfying the
// api.ContextInterface interface via the GraphQL API.
func NewContextGraphqlClient(host, endpoint, token string, debug bool) *GraphQLContextClient {
func NewContextGraphqlClient(httpClient *http.Client, host, endpoint, token string, debug bool) *GraphQLContextClient {
return &GraphQLContextClient{
Client: graphql.NewClient(host, endpoint, token, debug),
Client: graphql.NewClient(httpClient, host, endpoint, token, debug),
}
}
54 changes: 28 additions & 26 deletions api/context_rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,46 @@ package api

import (
"bytes"
"fmt"
"net/http"
"net/url"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"

"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/pkg/errors"
)

// ContextRestClient communicates with the CircleCI REST API to ask questions
// about contexts. It satisfies api.ContextInterface.
type ContextRestClient struct {
token string
token string
server string
client *http.Client
}

type listEnvironmentVariablesResponse struct {
Items []EnvironmentVariable
Items []EnvironmentVariable
NextPageToken *string `json:"next_page_token"`
client *ContextRestClient
params *listEnvironmentVariablesParams
client *ContextRestClient
params *listEnvironmentVariablesParams
}

type listContextsResponse struct {
Items []Context
Items []Context
NextPageToken *string `json:"next_page_token"`
client *ContextRestClient
params *listContextsParams
client *ContextRestClient
params *listContextsParams
}

type errorResponse struct {
Message *string `json:"message"`
}

type listContextsParams struct {
OwnerID *string
OwnerID *string
OwnerSlug *string
OwnerType *string
PageToken *string
Expand Down Expand Up @@ -85,7 +87,7 @@ func (c *ContextRestClient) DeleteEnvironmentVariable(contextID, variable string
}

// CreateContext creates a new context in the supplied organization.
func (c *ContextRestClient) CreateContext(vcs, org, name string) (error) {
func (c *ContextRestClient) CreateContext(vcs, org, name string) error {
req, err := c.newCreateContextRequest(vcs, org, name)
if err != nil {
return err
Expand Down Expand Up @@ -217,7 +219,7 @@ func (c *ContextRestClient) ContextByName(vcs, org, name string) (*Context, erro
}
}

func (c *ContextRestClient) listAllEnvironmentVariables (params *listEnvironmentVariablesParams) (envVars []EnvironmentVariable, err error) {
func (c *ContextRestClient) listAllEnvironmentVariables(params *listEnvironmentVariablesParams) (envVars []EnvironmentVariable, err error) {
var resp *listEnvironmentVariablesResponse
for {
resp, err = c.listEnvironmentVariables(params)
Expand Down Expand Up @@ -255,7 +257,7 @@ func (c *ContextRestClient) listAllContexts(params *listContextsParams) (context
return contexts, nil
}

func (c *ContextRestClient) listEnvironmentVariables (params *listEnvironmentVariablesParams) (*listEnvironmentVariablesResponse, error) {
func (c *ContextRestClient) listEnvironmentVariables(params *listEnvironmentVariablesParams) (*listEnvironmentVariablesResponse, error) {
req, err := c.newListEnvironmentVariablesRequest(params)
if err != nil {
return nil, err
Expand Down Expand Up @@ -289,7 +291,7 @@ func (c *ContextRestClient) listEnvironmentVariables (params *listEnvironmentVar
return &dest, nil
}

func (c *ContextRestClient) listContexts (params *listContextsParams) (*listContextsResponse, error) {
func (c *ContextRestClient) listContexts(params *listContextsParams) (*listContextsResponse, error) {
req, err := c.newListContextsRequest(params)
if err != nil {
return nil, err
Expand Down Expand Up @@ -345,7 +347,7 @@ func (c *ContextRestClient) newCreateContextRequest(vcs, org, name string) (*htt
} `json:"owner"`
}{
Name: name,
Owner: struct{
Owner: struct {
Slug *string `json:"slug,omitempty"`
}{
Slug: toSlug(vcs, org),
Expand Down Expand Up @@ -374,7 +376,7 @@ func (c *ContextRestClient) newCreateEnvironmentVariableRequest(contextID, varia
}

var bodyReader io.Reader
body := struct{
body := struct {
Value string `json:"value"`
}{
Value: value,
Expand Down Expand Up @@ -505,8 +507,8 @@ func (c *ContextRestClient) EnsureExists() error {
if err != nil {
return err
}
var respBody struct{
Paths struct{
var respBody struct {
Paths struct {
ContextEndpoint interface{} `json:"/context"`
}
}
Expand All @@ -523,25 +525,25 @@ func (c *ContextRestClient) EnsureExists() error {

// NewContextRestClient returns a new client satisfying the api.ContextInterface
// interface via the REST API.
func NewContextRestClient(host, endpoint, token string) (*ContextRestClient, error) {
func NewContextRestClient(config settings.Config) (*ContextRestClient, error) {
// Ensure server ends with a slash
if !strings.HasSuffix(endpoint, "/") {
endpoint += "/"
if !strings.HasSuffix(config.Endpoint, "/") {
config.Endpoint += "/"
}
serverURL, err := url.Parse(host)
serverURL, err := url.Parse(config.Host)
if err != nil {
return nil, err
}

serverURL, err = serverURL.Parse(endpoint)
serverURL, err = serverURL.Parse(config.Endpoint)
if err != nil {
return nil, err
}

client := &ContextRestClient{
token: token,
token: config.Token,
server: serverURL.String(),
client: &http.Client{},
client: config.HTTPClient,
}

return client, nil
Expand Down
7 changes: 4 additions & 3 deletions api/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"sync/atomic"

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

// we can't dot-import ginkgo because api.Context is a thing.
"github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -36,7 +37,7 @@ func createSingleUseGraphQLServer(result interface{}, requestAssertions func(req
_, err = rw.Write(bytes)
Expect(err).ToNot(HaveOccurred())
}))
client := NewContextGraphqlClient(server.URL, server.URL, "token", false)
client := NewContextGraphqlClient(http.DefaultClient, server.URL, server.URL, "token", false)
return server, client
}

Expand All @@ -49,7 +50,7 @@ var _ = ginkgo.Describe("API", func() {
Expect(unrelatedError).Should(Equal(improveVcsTypeError(unrelatedError)))

errors := []graphql.ResponseError{
graphql.ResponseError{
{
Message: "foo",
},
}
Expand Down Expand Up @@ -121,7 +122,7 @@ var _ = ginkgo.Describe("API", func() {
})
defer server.Close()

Expect(client.CreateContext( "test-vcs", "test-org", "foo-bar")).To(Succeed())
Expect(client.CreateContext("test-vcs", "test-org", "foo-bar")).To(Succeed())

})

Expand Down
2 changes: 1 addition & 1 deletion api/graphql/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Client struct {
}

// NewClient returns a reference to a Client.
func NewClient(host, endpoint, token string, debug bool) *Client {
func NewClient(httpClient *http.Client, host, endpoint, token string, debug bool) *Client {
return &Client{
httpClient: http.DefaultClient,
Endpoint: endpoint,
Expand Down
Loading

0 comments on commit 850f9ac

Please sign in to comment.