Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Mongey authored Oct 5, 2022
2 parents d2c1020 + a77d125 commit 4faf29b
Show file tree
Hide file tree
Showing 27 changed files with 819 additions and 582 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ orbs:
executors:
go:
docker:
- image: cimg/go:1.18
- image: cimg/go:1.19
environment:
CGO_ENABLED: 0
mac:
Expand Down Expand Up @@ -105,8 +105,8 @@ jobs:
- checkout
- run: |
brew update
brew install go@1.18
echo 'export PATH="/usr/local/opt/go@1.18/bin:$PATH"' >> ~/.bash_profile
brew install go@1.19
echo 'export PATH="/usr/local/opt/go@1.19/bin:$PATH"' >> ~/.bash_profile
- gomod
- run: make test
build:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM cimg/go:1.18.3
FROM cimg/go:1.19.1

ENV CIRCLECI_CLI_SKIP_UPDATE_CHECK true

Expand Down
60 changes: 60 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
version: '3'

tasks:
lint:
desc: Lint code
cmds:
- golangci-lint run -c .golangci.yml
summary: Lint the project with golangci-lint

clean:
desc: Cleans out the build, out, docs, and dist directories
cmds:
- GO111MODULE=off go clean -i
- rm -rf build out docs dist

fmt:
desc: Run `go fmt` to format the code
cmds:
- go fmt ./...

test:
desc: Run the tests
cmds:
- TESTING=true go test -v ./...

tidy:
desc: Run 'go mod tidy' to clean up module files.
cmds:
- go mod tidy -v

doc:
desc: run's the godocs
cmds:
- godoc -http=:6060

check-go-mod:
desc: Check go.mod is tidy
cmds:
- go mod tidy -v
- git diff --exit-code -- go.mod go.sum

vendor:
desc: go mod vendor
cmds:
- go mod vendor

build:
desc: Build main
cmds:
- go build -v -o build/darwin/amd64/circleci .

build-linux:
desc: Build main
cmds:
- go build -v -o build/linux/amd64/circleci .

cover:
desc: tests and generates a cover profile
cmds:
- TESTING=true go test -race -coverprofile=coverage.txt ./...
120 changes: 0 additions & 120 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"strings"

"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"
Expand Down Expand Up @@ -513,125 +512,6 @@ func WhoamiQuery(cl *graphql.Client) (*WhoamiResponse, error) {
return &response, nil
}

// ConfigQueryLegacy calls the GQL API to validate and process config with the legacy orgSlug
func ConfigQueryLegacy(cl *graphql.Client, configPath string, orgSlug string, params pipeline.Parameters, values pipeline.Values) (*ConfigResponse, error) {
var response BuildConfigResponse
var query string
config, err := loadYaml(configPath)
if err != nil {
return nil, err
}
// GraphQL isn't forwards-compatible, so we are unusually selective here about
// passing only non-empty fields on to the API, to minimize user impact if the
// backend is out of date.
var fieldAddendums string
if orgSlug != "" {
fieldAddendums += ", orgSlug: $orgSlug"
}
if len(params) > 0 {
fieldAddendums += ", pipelineParametersJson: $pipelineParametersJson"
}
query = fmt.Sprintf(
`query ValidateConfig ($config: String!, $pipelineParametersJson: String, $pipelineValues: [StringKeyVal!], $orgSlug: String) {
buildConfig(configYaml: $config, pipelineValues: $pipelineValues%s) {
valid,
errors { message },
sourceYaml,
outputYaml
}
}`,
fieldAddendums)

request := graphql.NewRequest(query)
request.Var("config", config)

if values != nil {
request.Var("pipelineValues", pipeline.PrepareForGraphQL(values))
}
if params != nil {
pipelineParameters, err := json.Marshal(params)
if err != nil {
return nil, fmt.Errorf("unable to serialize pipeline values: %s", err.Error())
}
request.Var("pipelineParametersJson", string(pipelineParameters))
}

if orgSlug != "" {
request.Var("orgSlug", orgSlug)
}

request.SetToken(cl.Token)

err = cl.Run(request, &response)
if err != nil {
return nil, errors.Wrap(err, "Unable to validate config")
}
if len(response.BuildConfig.ConfigResponse.Errors) > 0 {
return nil, &response.BuildConfig.ConfigResponse.Errors
}

return &response.BuildConfig.ConfigResponse, nil
}

// ConfigQuery calls the GQL API to validate and process config with the org id
func ConfigQuery(cl *graphql.Client, configPath string, orgId string, params pipeline.Parameters, values pipeline.Values) (*ConfigResponse, error) {
var response BuildConfigResponse
var query string
config, err := loadYaml(configPath)
if err != nil {
return nil, err
}
// GraphQL isn't forwards-compatible, so we are unusually selective here about
// passing only non-empty fields on to the API, to minimize user impact if the
// backend is out of date.
var fieldAddendums string
if orgId != "" {
fieldAddendums += ", orgId: $orgId"
}
if len(params) > 0 {
fieldAddendums += ", pipelineParametersJson: $pipelineParametersJson"
}
query = fmt.Sprintf(
`query ValidateConfig ($config: String!, $pipelineParametersJson: String, $pipelineValues: [StringKeyVal!], $orgId: UUID!) {
buildConfig(configYaml: $config, pipelineValues: $pipelineValues%s) {
valid,
errors { message },
sourceYaml,
outputYaml
}
}`,
fieldAddendums)

request := graphql.NewRequest(query)
request.Var("config", config)

if values != nil {
request.Var("pipelineValues", pipeline.PrepareForGraphQL(values))
}
if params != nil {
pipelineParameters, err := json.Marshal(params)
if err != nil {
return nil, fmt.Errorf("unable to serialize pipeline values: %s", err.Error())
}
request.Var("pipelineParametersJson", string(pipelineParameters))
}

if orgId != "" {
request.Var("orgId", orgId)
}
request.SetToken(cl.Token)

err = cl.Run(request, &response)
if err != nil {
return nil, errors.Wrap(err, "Unable to validate config")
}
if len(response.BuildConfig.ConfigResponse.Errors) > 0 {
return nil, &response.BuildConfig.ConfigResponse.Errors
}

return &response.BuildConfig.ConfigResponse, nil
}

// OrbQuery validated and processes an orb.
func OrbQuery(cl *graphql.Client, configPath string) (*ConfigResponse, error) {
var response OrbConfigResponse
Expand Down
4 changes: 2 additions & 2 deletions api/context_rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ func (c *ContextRestClient) listContexts(params *listContextsParams) (*listConte
return &dest, nil
}

//newCreateContextRequest posts a new context creation with orgname and vcs type using a slug
// newCreateContextRequest posts a new context creation with orgname and vcs type using a slug
func (c *ContextRestClient) newCreateContextRequest(vcs, org, name string) (*http.Request, error) {
var err error
queryURL, err := url.Parse(c.server)
Expand Down Expand Up @@ -398,7 +398,7 @@ func (c *ContextRestClient) newCreateContextRequest(vcs, org, name string) (*htt
return c.newHTTPRequest("POST", queryURL.String(), bodyReader)
}

//newCreateContextRequestWithOrgID posts a new context creation with an orgID
// newCreateContextRequestWithOrgID posts a new context creation with an orgID
func (c *ContextRestClient) newCreateContextRequestWithOrgID(orgID *string, name string) (*http.Request, error) {
var err error
queryURL, err := url.Parse(c.server)
Expand Down
2 changes: 1 addition & 1 deletion api/graphql/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type Client struct {
// NewClient returns a reference to a Client.
func NewClient(httpClient *http.Client, host, endpoint, token string, debug bool) *Client {
return &Client{
httpClient: http.DefaultClient,
httpClient: httpClient,
Endpoint: endpoint,
Host: host,
Token: token,
Expand Down
2 changes: 1 addition & 1 deletion api/info/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type InfoRESTClient struct {
client *http.Client
}

//organization json org info
// organization json org info
type Organization struct {
ID string `json:"id"`
Name string `json:"name"`
Expand Down
69 changes: 69 additions & 0 deletions api/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,75 @@ type DecisionRequest struct {
Metadata map[string]interface{} `json:"metadata,omitempty"`
}

// GetSettings calls the GET decision-settings API of policy-service.
func (c Client) GetSettings(ownerID string, context string) (interface{}, error) {
path := fmt.Sprintf("%s/api/v1/owner/%s/context/%s/decision/settings", c.serverUrl, ownerID, context)
req, err := http.NewRequest("GET", path, nil)
if err != nil {
return nil, fmt.Errorf("failed to construct request: %v", err)
}

resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
var payload httpError
if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
return nil, fmt.Errorf("unexpected status-code: %d", resp.StatusCode)
}
return nil, fmt.Errorf("unexpected status-code: %d - %s", resp.StatusCode, payload.Error)
}

var body interface{}
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
return nil, fmt.Errorf("failed to decode response body: %v", err)
}

return body, nil
}

// DecisionSettings represents a request to Policy-Service to configure decision settings.
type DecisionSettings struct {
Enabled *bool `json:"enabled,omitempty"`
}

// SetSettings calls the PATCH decision-settings API of policy-service.
func (c Client) SetSettings(ownerID string, context string, request DecisionSettings) (interface{}, error) {
payload, err := json.Marshal(request)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %w", err)
}
path := fmt.Sprintf("%s/api/v1/owner/%s/context/%s/decision/settings", c.serverUrl, ownerID, context)
req, err := http.NewRequest("PATCH", path, bytes.NewReader(payload))
if err != nil {
return nil, fmt.Errorf("failed to construct request: %v", err)
}

resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
var payload httpError
if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
return nil, fmt.Errorf("unexpected status-code: %d", resp.StatusCode)
}
return nil, fmt.Errorf("unexpected status-code: %d - %s", resp.StatusCode, payload.Error)
}

var body interface{}
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
return nil, fmt.Errorf("failed to decode response body: %v", err)
}

return body, nil
}

// MakeDecision sends a requests to Policy-Service public decision endpoint and returns the decision response
func (c Client) MakeDecision(ownerID string, context string, req DecisionRequest) (*cpa.Decision, error) {
payload, err := json.Marshal(req)
Expand Down
Loading

0 comments on commit 4faf29b

Please sign in to comment.