-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split client and provider into separate packages (#2)
* Add client package * Added project import Fix token defaults * Add pipeline import * Add project tests * Refactoring * Add pipeline tests * Fix pipeline triggers * Added tests for pipeline triggers * Refactoring * Add original_yaml_string and runtime_environment to pipeline * Add pipeline revision * Added a test for pipeline revision * Fix SetVariables methods
- Loading branch information
Showing
14 changed files
with
1,753 additions
and
610 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package client | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// Client token, host, htpp.Client | ||
type Client struct { | ||
Token string | ||
Host string | ||
Client *http.Client | ||
} | ||
|
||
// RequestOptions path, method, etc | ||
type RequestOptions struct { | ||
Path string | ||
Method string | ||
Body []byte | ||
QS map[string]string | ||
} | ||
|
||
// NewClient returns a new client configured to communicate on a server with the | ||
// given hostname and to send an Authorization Header with the value of | ||
// token | ||
func NewClient(hostname string, token string) *Client { | ||
return &Client{ | ||
Host: hostname, | ||
Token: token, | ||
Client: &http.Client{}, | ||
} | ||
|
||
} | ||
|
||
// RequestAPI http request to Codefresh API | ||
func (client *Client) RequestAPI(opt *RequestOptions) ([]byte, error) { | ||
finalURL := fmt.Sprintf("%s%s", client.Host, opt.Path) | ||
if opt.QS != nil { | ||
finalURL += ToQS(opt.QS) | ||
} | ||
request, err := http.NewRequest(opt.Method, finalURL, bytes.NewBuffer(opt.Body)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
request.Header.Set("Authorization", client.Token) | ||
request.Header.Set("Content-Type", "application/json; charset=utf-8") | ||
|
||
resp, err := client.Client.Do(request) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, fmt.Errorf("Failed to read body %v %v", resp.StatusCode, resp.Status) | ||
} | ||
|
||
if resp.StatusCode != 200 { | ||
return nil, fmt.Errorf("%v, %s", resp.Status, string(body)) | ||
} | ||
return body, nil | ||
} | ||
|
||
// ToQS add extra parameters to path | ||
func ToQS(qs map[string]string) string { | ||
var arr = []string{} | ||
for k, v := range qs { | ||
arr = append(arr, fmt.Sprintf("%s=%s", k, v)) | ||
} | ||
return "?" + strings.Join(arr, "&") | ||
} | ||
|
||
// DecodeResponseInto json Unmarshall | ||
func DecodeResponseInto(body []byte, target interface{}) error { | ||
return json.Unmarshal(body, target) | ||
} | ||
|
||
// EncodeToJSON json Marshal | ||
func EncodeToJSON(object interface{}) ([]byte, error) { | ||
body, err := json.Marshal(object) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return body, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
package client | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
type ErrorResponse struct { | ||
Status int `json:"status,omitempty"` | ||
Message string `json:"message,omitempty"` | ||
Error string `json:"error,omitempty"` | ||
} | ||
|
||
type Labels struct { | ||
Tags []string `json:"tags,omitempty"` | ||
} | ||
|
||
type Metadata struct { | ||
Name string `json:"name,omitempty"` | ||
ID string `json:"id,omitempty"` | ||
Labels Labels `json:"labels,omitempty"` | ||
OriginalYamlString string `json:"originalYamlString,omitempty"` | ||
Project string `json:"project,omitempty"` | ||
ProjectId string `json:"projectId,omitempty"` | ||
Revision int `json:"revision,omitempty"` | ||
} | ||
|
||
type SpecTemplate struct { | ||
Location string `json:"location,omitempty"` | ||
Repo string `json:"repo,omitempty"` | ||
Path string `json:"path,omitempty"` | ||
Revision string `json:"revision,omitempty"` | ||
Context string `json:"context,omitempty"` | ||
} | ||
|
||
type Trigger struct { | ||
Name string `json:"name,omitempty"` | ||
Description string `json:"description,omitempty"` | ||
Type string `json:"type,omitempty"` | ||
Repo string `json:"repo,omitempty"` | ||
Events []string `json:"events,omitempty"` | ||
BranchRegex string `json:"branchRegex,omitempty"` | ||
ModifiedFilesGlob string `json:"modifiedFilesGlob,omitempty"` | ||
Provider string `json:"provider,omitempty"` | ||
Disabled bool `json:"disabled,omitempty"` | ||
Context string `json:"context,omitempty"` | ||
Variables []Variable `json:"variables,omitempty"` | ||
} | ||
|
||
type RuntimeEnvironment struct { | ||
Name string `json:"name,omitempty"` | ||
Memory string `json:"memory,omitempty"` | ||
CPU string `json:"cpu,omitempty"` | ||
DindStorage string `json:"dindStorage,omitempty"` | ||
} | ||
|
||
func (t *Trigger) SetVariables(variables map[string]string) { | ||
for key, value := range variables { | ||
t.Variables = append(t.Variables, Variable{Key: key, Value: value}) | ||
} | ||
} | ||
|
||
type Spec struct { | ||
Variables []Variable `json:"variables,omitempty"` | ||
SpecTemplate *SpecTemplate `json:"specTemplate,omitempty"` | ||
Triggers []Trigger `json:"triggers,omitempty"` | ||
Priority int `json:"priority,omitempty"` | ||
Concurrency int `json:"concurrency,omitempty"` | ||
Contexts []interface{} `json:"contexts,omitempty"` | ||
Steps map[string]interface{} `json:"steps,omitempty"` | ||
Stages []interface{} `json:"stages,omitempty"` | ||
Mode string `json:"mode,omitempty"` | ||
RuntimeEnvironment RuntimeEnvironment `json:"runtimeEnvironment,omitempty"` | ||
} | ||
|
||
type Pipeline struct { | ||
Metadata Metadata `json:"metadata,omitempty"` | ||
Spec Spec `json:"spec,omitempty"` | ||
Version string `json:"version,omitempty"` | ||
} | ||
|
||
func (p *Pipeline) SetVariables(variables map[string]string) { | ||
for key, value := range variables { | ||
p.Spec.Variables = append(p.Spec.Variables, Variable{Key: key, Value: value}) | ||
} | ||
} | ||
|
||
func (pipeline *Pipeline) GetID() string { | ||
if pipeline.Metadata.ID != "" { | ||
return pipeline.Metadata.ID | ||
} else { | ||
return pipeline.Metadata.Name | ||
} | ||
} | ||
|
||
func (client *Client) GetPipeline(name string) (*Pipeline, error) { | ||
fullPath := fmt.Sprintf("/pipelines/%s", strings.Replace(name, "/", "%2F", 1)) | ||
opts := RequestOptions{ | ||
Path: fullPath, | ||
Method: "GET", | ||
} | ||
|
||
resp, err := client.RequestAPI(&opts) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var pipeline Pipeline | ||
|
||
err = DecodeResponseInto(resp, &pipeline) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &pipeline, nil | ||
} | ||
|
||
func (client *Client) CreatePipeline(pipeline *Pipeline) (*Pipeline, error) { | ||
|
||
body, err := EncodeToJSON(pipeline) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
opts := RequestOptions{ | ||
Path: "/pipelines", | ||
Method: "POST", | ||
Body: body, | ||
} | ||
|
||
resp, err := client.RequestAPI(&opts) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var respPipeline Pipeline | ||
err = DecodeResponseInto(resp, &respPipeline) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &respPipeline, nil | ||
|
||
} | ||
|
||
func (client *Client) UpdatePipeline(pipeline *Pipeline) (*Pipeline, error) { | ||
|
||
body, err := EncodeToJSON(pipeline) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
id := pipeline.GetID() | ||
if id == "" { | ||
return nil, errors.New("[ERROR] Both Pipeline ID and Name are empty") | ||
} | ||
|
||
fullPath := fmt.Sprintf("/pipelines/%s", strings.Replace(id, "/", "%2F", 1)) | ||
opts := RequestOptions{ | ||
Path: fullPath, | ||
Method: "PUT", | ||
Body: body, | ||
} | ||
|
||
resp, err := client.RequestAPI(&opts) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var respPipeline Pipeline | ||
err = DecodeResponseInto(resp, &respPipeline) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &respPipeline, nil | ||
} | ||
|
||
func (client *Client) DeletePipeline(name string) error { | ||
|
||
fullPath := fmt.Sprintf("/pipelines/%s", strings.Replace(name, "/", "%2F", 1)) | ||
opts := RequestOptions{ | ||
Path: fullPath, | ||
Method: "DELETE", | ||
} | ||
|
||
_, err := client.RequestAPI(&opts) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.