Skip to content

Commit

Permalink
feat: get/create/delete commands for agent types (#207)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucaspin authored Nov 15, 2022
1 parent f4c2c6e commit 302a770
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 1 deletion.
87 changes: 87 additions & 0 deletions api/client/agent_types_v1_alpha.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package client

import (
"errors"
"fmt"

models "github.com/semaphoreci/cli/api/models"
)

type AgentTypeApiV1AlphaApi struct {
BaseClient BaseClient
ResourceNameSingular string
ResourceNamePlural string
}

func NewAgentTypeApiV1AlphaApi() AgentTypeApiV1AlphaApi {
baseClient := NewBaseClientFromConfig()
baseClient.SetApiVersion("v1alpha")

return AgentTypeApiV1AlphaApi{
BaseClient: baseClient,
ResourceNamePlural: "self_hosted_agent_types",
ResourceNameSingular: "self_hosted_agent_type",
}
}

func (c *AgentTypeApiV1AlphaApi) ListAgentTypes() (*models.AgentTypeListV1Alpha, error) {
body, status, err := c.BaseClient.List(c.ResourceNamePlural)

if err != nil {
return nil, errors.New(fmt.Sprintf("connecting to Semaphore failed '%s'", err))
}

if status != 200 {
return nil, errors.New(fmt.Sprintf("http status %d with message \"%s\" received from upstream", status, body))
}

return models.NewAgentTypeListV1AlphaFromJson(body)
}

func (c *AgentTypeApiV1AlphaApi) GetAgentType(name string) (*models.AgentTypeV1Alpha, error) {
body, status, err := c.BaseClient.Get(c.ResourceNamePlural, name)

if err != nil {
return nil, errors.New(fmt.Sprintf("connecting to Semaphore failed '%s'", err))
}

if status != 200 {
return nil, errors.New(fmt.Sprintf("http status %d with message \"%s\" received from upstream", status, body))
}

return models.NewAgentTypeV1AlphaFromJson(body)
}

func (c *AgentTypeApiV1AlphaApi) DeleteAgentType(name string) error {
body, status, err := c.BaseClient.Delete(c.ResourceNamePlural, name)

if err != nil {
return err
}

if status != 200 {
return fmt.Errorf("http status %d with message \"%s\" received from upstream", status, body)
}

return nil
}

func (c *AgentTypeApiV1AlphaApi) CreateAgentType(d *models.AgentTypeV1Alpha) (*models.AgentTypeV1Alpha, error) {
json_body, err := d.ToJson()

if err != nil {
return nil, errors.New(fmt.Sprintf("failed to serialize object '%s'", err))
}

body, status, err := c.BaseClient.Post(c.ResourceNamePlural, json_body)

if err != nil {
return nil, errors.New(fmt.Sprintf("creating %s on Semaphore failed '%s'", c.ResourceNameSingular, err))
}

if status != 200 {
return nil, errors.New(fmt.Sprintf("http status %d with message \"%s\" received from upstream", status, body))
}

return models.NewAgentTypeV1AlphaFromJson(body)
}
28 changes: 28 additions & 0 deletions api/models/agent_type_list_v1_alpha.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package models

import "encoding/json"

type AgentTypeListV1Alpha struct {
AgentTypes []AgentTypeV1Alpha `json:"agent_types" yaml:"agent_types"`
}

func NewAgentTypeListV1AlphaFromJson(data []byte) (*AgentTypeListV1Alpha, error) {
list := AgentTypeListV1Alpha{}

err := json.Unmarshal(data, &list)
if err != nil {
return nil, err
}

for _, s := range list.AgentTypes {
if s.ApiVersion == "" {
s.ApiVersion = "v1alpha"
}

if s.Kind == "" {
s.Kind = "SelfHostedAgentType"
}
}

return &list, nil
}
74 changes: 74 additions & 0 deletions api/models/agent_type_v1_alpha.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package models

import (
"encoding/json"
"fmt"

yaml "gopkg.in/yaml.v2"
)

type AgentTypeV1Alpha struct {
ApiVersion string `json:"apiVersion,omitempty" yaml:"apiVersion"`
Kind string `json:"kind,omitempty" yaml:"kind"`
Metadata AgentTypeV1AlphaMetadata `json:"metadata" yaml:"metadata"`
Status AgentTypeV1AlphaStatus `json:"status" yaml:"status"`
}

type AgentTypeV1AlphaMetadata struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
CreateTime json.Number `json:"create_time,omitempty" yaml:"create_time,omitempty"`
UpdateTime json.Number `json:"update_time,omitempty" yaml:"update_time,omitempty"`
}

type AgentTypeV1AlphaStatus struct {
TotalAgentCount int `json:"total_agent_count,omitempty" yaml:"total_agent_count,omitempty"`
RegistrationToken string `json:"registration_token,omitempty" yaml:"registration_token,omitempty"`
}

func NewAgentTypeV1Alpha(name string) AgentTypeV1Alpha {
a := AgentTypeV1Alpha{}
a.Metadata.Name = name
a.setApiVersionAndKind()
return a
}

func NewAgentTypeV1AlphaFromJson(data []byte) (*AgentTypeV1Alpha, error) {
a := AgentTypeV1Alpha{}

err := json.Unmarshal(data, &a)
if err != nil {
return nil, err
}

a.setApiVersionAndKind()
return &a, nil
}

func NewAgentTypeV1AlphaFromYaml(data []byte) (*AgentTypeV1Alpha, error) {
a := AgentTypeV1Alpha{}

err := yaml.UnmarshalStrict(data, &a)
if err != nil {
return nil, err
}

a.setApiVersionAndKind()
return &a, nil
}

func (s *AgentTypeV1Alpha) setApiVersionAndKind() {
s.ApiVersion = "v1alpha"
s.Kind = "SelfHostedAgentType"
}

func (s *AgentTypeV1Alpha) ObjectName() string {
return fmt.Sprintf("SelfHostedAgentType/%s", s.Metadata.Name)
}

func (s *AgentTypeV1Alpha) ToJson() ([]byte, error) {
return json.Marshal(s)
}

func (s *AgentTypeV1Alpha) ToYaml() ([]byte, error) {
return yaml.Marshal(s)
}
33 changes: 33 additions & 0 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ var createCmd = &cobra.Command{
utils.Check(err)

fmt.Printf("Job '%s' created.\n", job.Metadata.Id)
case "SelfHostedAgentType":
at, err := models.NewAgentTypeV1AlphaFromYaml(data)
utils.Check(err)

c := client.NewAgentTypeApiV1AlphaApi()
newAgentType, err := c.CreateAgentType(at)
utils.Check(err)

y, err := newAgentType.ToYaml()
utils.Check(err)
fmt.Printf("%s", y)
default:
utils.Fail(fmt.Sprintf("Unsupported resource kind '%s'", kind))
}
Expand Down Expand Up @@ -121,6 +132,27 @@ var CreateDashboardCmd = &cobra.Command{
},
}

var CreateAgentTypeCmd = &cobra.Command{
Use: "agent_type [NAME]",
Short: "Create a self-hosted agent type.",
Long: ``,
Aliases: []string{"agenttype", "agentType"},
Args: cobra.ExactArgs(1),

Run: func(cmd *cobra.Command, args []string) {
name := args[0]

c := client.NewAgentTypeApiV1AlphaApi()
at := models.NewAgentTypeV1Alpha(name)
agentType, err := c.CreateAgentType(&at)
utils.Check(err)

y, err := agentType.ToYaml()
utils.Check(err)
fmt.Printf("%s", y)
},
}

var CreateWorkflowCmd = &cobra.Command{
Use: "workflow [NAME]",
Short: "Create a workflow from snapshot.",
Expand Down Expand Up @@ -185,6 +217,7 @@ func init() {
createCmd.AddCommand(createJobCmd)
createCmd.AddCommand(CreateWorkflowCmd)
createCmd.AddCommand(createNotificationCmd)
createCmd.AddCommand(CreateAgentTypeCmd)

// Create Flags

Expand Down
63 changes: 63 additions & 0 deletions cmd/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,66 @@ func Test__CreateDashboard__WithSubcommand__Response200(t *testing.T) {
t.Errorf("Expected the API to receive POST dashboard with: %s, got: %s", expected, received)
}
}

func Test__CreateAgentType__FromYaml__Response200(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

yaml_file := `
apiVersion: v1alpha
kind: SelfHostedAgentType
metadata:
name: s1-testing-from-yaml
`

yaml_file_path := "/tmp/agent_type.yaml"

ioutil.WriteFile(yaml_file_path, []byte(yaml_file), 0644)

received := ""

httpmock.RegisterResponder("POST", "https://org.semaphoretext.xyz/api/v1alpha/self_hosted_agent_types",
func(req *http.Request) (*http.Response, error) {
body, _ := ioutil.ReadAll(req.Body)

received = string(body)

return httpmock.NewStringResponse(200, received), nil
},
)

RootCmd.SetArgs([]string{"create", "-f", yaml_file_path})
RootCmd.Execute()

expected := `{"apiVersion":"v1alpha","kind":"SelfHostedAgentType","metadata":{"name":"s1-testing-from-yaml"},"status":{}}`

if received != expected {
t.Errorf("Expected the API to receive POST self_hosted_agent_types with: %s, got: %s", expected, received)
}
}

func Test__CreateAgentType__Response200(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

received := ""

httpmock.RegisterResponder("POST", "https://org.semaphoretext.xyz/api/v1alpha/self_hosted_agent_types",
func(req *http.Request) (*http.Response, error) {
body, _ := ioutil.ReadAll(req.Body)

received = string(body)

return httpmock.NewStringResponse(200, received), nil
},
)

RootCmd.SetArgs([]string{"create", "agent_type", "s1-testing"})
RootCmd.Execute()

expected := `{"apiVersion":"v1alpha","kind":"SelfHostedAgentType","metadata":{"name":"s1-testing"},"status":{}}`

if received != expected {
t.Errorf("Expected the API to receive POST self_hosted_agent_types with: %s, got: %s", expected, received)
}
}
18 changes: 18 additions & 0 deletions cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ var DeleteSecretCmd = &cobra.Command{
},
}

var DeleteAgentTypeCmd = &cobra.Command{
Use: "agent_type [NAME]",
Short: "Delete a self-hosted agent type.",
Long: ``,
Aliases: []string{"agenttype", "agentType"},
Args: cobra.ExactArgs(1),

Run: func(cmd *cobra.Command, args []string) {
name := args[0]
c := client.NewAgentTypeApiV1AlphaApi()
err := c.DeleteAgentType(name)
utils.Check(err)

fmt.Printf("Self-hosted agent type '%s' deleted.\n", name)
},
}

var DeleteProjectCmd = &cobra.Command{
Use: "project [NAME]",
Short: "Delete a project.",
Expand Down Expand Up @@ -102,4 +119,5 @@ func init() {
deleteCmd.AddCommand(DeleteProjectCmd)
deleteCmd.AddCommand(DeleteSecretCmd)
deleteCmd.AddCommand(DeleteNotificationCmd)
deleteCmd.AddCommand(DeleteAgentTypeCmd)
}
22 changes: 22 additions & 0 deletions cmd/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,25 @@ func TestDeleteDashboardCmd__Response200(t *testing.T) {
t.Error("Expected the API to receive DELETE test dash")
}
}

func TestDeleteAgentTypeCmd__Response200(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

received := false

httpmock.RegisterResponder("DELETE", "https://org.semaphoretext.xyz/api/v1alpha/self_hosted_agent_types/s1-testing",
func(req *http.Request) (*http.Response, error) {
received = true

return httpmock.NewStringResponse(200, ""), nil
},
)

RootCmd.SetArgs([]string{"delete", "agent_type", "s1-testing"})
RootCmd.Execute()

if received == false {
t.Error("Expected the API to receive DELETE agent_type s1-testing")
}
}
Loading

0 comments on commit 302a770

Please sign in to comment.