diff --git a/octopusdeploy/action_template_parameter.go b/octopusdeploy/action_template_parameter.go index aac7fc44..5b9700d6 100644 --- a/octopusdeploy/action_template_parameter.go +++ b/octopusdeploy/action_template_parameter.go @@ -3,7 +3,7 @@ package octopusdeploy type ActionTemplateParameter struct { // default value - DefaultValue PropertyValueResource `json:"DefaultValue,omitempty"` + DefaultValue string `json:"DefaultValue,omitempty"` // display settings DisplaySettings map[string]string `json:"DisplaySettings,omitempty"` diff --git a/octopusdeploy/action_templates.go b/octopusdeploy/action_templates.go new file mode 100644 index 00000000..7458f9c3 --- /dev/null +++ b/octopusdeploy/action_templates.go @@ -0,0 +1,155 @@ +package octopusdeploy + +import ( + "fmt" + + "github.com/dghubble/sling" + "gopkg.in/go-playground/validator.v9" +) + +type ActionTemplateService struct { + sling *sling.Sling +} + +func NewActionTemplateService(sling *sling.Sling) *ActionTemplateService { + return &ActionTemplateService{ + sling: sling, + } +} + +type ActionTemplates struct { + Items []ActionTemplate `json:"Items"` + PagedResults +} + +type ActionTemplate struct { + ID string `json:"Id"` + Name string `json:"Name"` + Description string `json:"Description"` + ActionType string `json:"ActionType"` + Version int `json:"Version"` + CommunityActionTemplateId string `json:"CommunityActionTemplateId"` + Properties *ActionTemplateProperties `json:"Properties,omitempty"` + Parameters []ActionTemplateParameter `json:"Parameters,omitempty"` +} + +type ActionTemplateProperties struct { + ManualInstructions string `json:"Octopus.Action.Manual.Instructions,omitempty"` + ManualResponsibleTeamIds string `json:"Octopus.Action.Manual.ResponsibleTeamIds,omitempty"` + ManualBlockConcurrentDeployments bool `json:"Octopus.Action.Manual.BlockConcurrentDeployments,string,omitempty"` + RunOnServer string `json:"Octopus.Action.RunOnServer,omitempty"` + ScriptSyntax string `json:"Octopus.Action.Script.Syntax,omitempty"` + ScriptSource string `json:"Octopus.Action.Script.ScriptSource,omitempty"` + ScriptBody string `json:"Octopus.Action.Script.ScriptBody,omitempty"` +} + +func (p *ActionTemplate) Validate() error { + validate := validator.New() + + err := validate.Struct(p) + + if err != nil { + return err + } + + return nil +} + +func NewActionTemplate(name string, description string, actionType string) *ActionTemplate { + return &ActionTemplate{ + Name: name, + Description: description, + ActionType: actionType, + } +} + +func (s *ActionTemplateService) Get(actionTemplateID string) (*ActionTemplate, error) { + path := fmt.Sprintf("actiontemplates/%s", actionTemplateID) + resp, err := apiGet(s.sling, new(ActionTemplate), path) + + if err != nil { + return nil, err + } + + return resp.(*ActionTemplate), nil +} + +func (s *ActionTemplateService) GetAll() (*[]ActionTemplate, error) { + var at []ActionTemplate + + path := "actiontemplates" + + loadNextPage := true + + for loadNextPage { + resp, err := apiGet(s.sling, new(ActionTemplates), path) + + if err != nil { + return nil, err + } + + r := resp.(*ActionTemplates) + + for _, item := range r.Items { + at = append(at, item) + } + + path, loadNextPage = LoadNextPage(r.PagedResults) + } + + return &at, nil +} + +func (s *ActionTemplateService) GetByName(actionTemplateName string) (*ActionTemplate, error) { + var notFound ActionTemplate + ats, err := s.GetAll() + + if err != nil { + return nil, err + } + + for _, at := range *ats { + if at.Name == actionTemplateName { + return &at, nil + } + } + + return ¬Found, fmt.Errorf("no actiontemplate found with name %s", actionTemplateName) +} + +func (s *ActionTemplateService) Add(actionTemplate *ActionTemplate) (*ActionTemplate, error) { + err := actionTemplate.Validate() + if err != nil { + return nil, err + } + + resp, err := apiAdd(s.sling, actionTemplate, new(ActionTemplate), "actiontemplates") + + if err != nil { + return nil, err + } + + return resp.(*ActionTemplate), nil +} + +func (s *ActionTemplateService) Delete(actionTemplateID string) error { + path := fmt.Sprintf("actiontemplates/%s", actionTemplateID) + err := apiDelete(s.sling, path) + + if err != nil { + return err + } + + return nil +} + +func (s *ActionTemplateService) Update(actionTemplate *ActionTemplate) (*ActionTemplate, error) { + path := fmt.Sprintf("actiontemplates/%s", actionTemplate.ID) + resp, err := apiUpdate(s.sling, actionTemplate, new(ActionTemplate), path) + + if err != nil { + return nil, err + } + + return resp.(*ActionTemplate), nil +} diff --git a/octopusdeploy/community_action_templates.go b/octopusdeploy/community_action_templates.go new file mode 100644 index 00000000..0d21086d --- /dev/null +++ b/octopusdeploy/community_action_templates.go @@ -0,0 +1,116 @@ +package octopusdeploy + +import ( + "fmt" + + "github.com/dghubble/sling" + "gopkg.in/go-playground/validator.v9" +) + +type CommunityActionTemplateService struct { + sling *sling.Sling + spaceID string +} + +func NewCommunityActionTemplateService(sling *sling.Sling, spaceID string) *CommunityActionTemplateService { + return &CommunityActionTemplateService{ + sling: sling, + spaceID: spaceID, + } +} + +type CommunityActionTemplates struct { + Items []CommunityActionTemplate `json:"Items"` + PagedResults +} + +type CommunityActionTemplate struct { + ID string `json:"Id"` + Name string `json:"Name,omitempty"` + Label string `json:"Label,omitempty"` + HelpText string `json:"HelpText,omitempty"` + DefaultValue string `json:"DefaultValue"` +} + +func (p *CommunityActionTemplate) Validate() error { + validate := validator.New() + + err := validate.Struct(p) + + if err != nil { + return err + } + + return nil +} + +func NewCommunityActionTemplate(id string) *CommunityActionTemplate { + return &CommunityActionTemplate{ + ID: id, + } +} + +func (s *CommunityActionTemplateService) Get(communityActionTemplateID string) (*CommunityActionTemplate, error) { + path := fmt.Sprintf("communityactiontemplates/%s", communityActionTemplateID) + resp, err := apiGet(s.sling, new(CommunityActionTemplate), path) + + if err != nil { + return nil, err + } + + return resp.(*CommunityActionTemplate), nil +} + +func (s *CommunityActionTemplateService) GetAll() (*[]CommunityActionTemplate, error) { + var cat []CommunityActionTemplate + + path := "communityactiontemplates" + + loadNextPage := true + + for loadNextPage { + resp, err := apiGet(s.sling, new(CommunityActionTemplates), path) + + if err != nil { + return nil, err + } + + r := resp.(*CommunityActionTemplates) + + for _, item := range r.Items { + cat = append(cat, item) + } + + path, loadNextPage = LoadNextPage(r.PagedResults) + } + + return &cat, nil +} + +func (s *CommunityActionTemplateService) GetByName(communityActionTemplateName string) (*CommunityActionTemplate, error) { + var notFound CommunityActionTemplate + cats, err := s.GetAll() + + if err != nil { + return nil, err + } + + for _, cat := range *cats { + if cat.Name == communityActionTemplateName { + return &cat, nil + } + } + + return ¬Found, fmt.Errorf("no communityactiontemplate found with name %s", communityActionTemplateName) +} + +func (s *CommunityActionTemplateService) Add(communityActionTemplateID string) (*CommunityActionTemplate, error) { + create := fmt.Sprintf("communityactiontemplates/%s/installation/%s", communityActionTemplateID, s.spaceID) + resp, err := apiAdd(s.sling, nil, new(CommunityActionTemplate), create) + + if err != nil { + return nil, err + } + + return resp.(*CommunityActionTemplate), nil +} diff --git a/octopusdeploy/environment.go b/octopusdeploy/environment.go index edbd40a7..f289d3e1 100644 --- a/octopusdeploy/environment.go +++ b/octopusdeploy/environment.go @@ -96,9 +96,9 @@ func (s *EnvironmentService) GetByName(environmentName string) (*Environment, er return nil, err } - for _, project := range *environments { - if project.Name == environmentName { - return &project, nil + for _, env := range *environments { + if env.Name == environmentName { + return &env, nil } } diff --git a/octopusdeploy/machines.go b/octopusdeploy/machines.go index 0a9806e5..77292d1c 100644 --- a/octopusdeploy/machines.go +++ b/octopusdeploy/machines.go @@ -51,7 +51,7 @@ type MachineEndpointAuthentication struct { type MachineEndpoint struct { ID string `json:"Id"` CommunicationStyle string `json:"CommunicationStyle"` - ProxyID *string `json:"ProxyId"` + ProxyID string `json:"ProxyId,omitempty"` Thumbprint string `json:"Thumbprint"` TentacleVersionDetails MachineTentacleVersionDetails `json:"TentacleVersionDetails"` LastModifiedOn *string `json:"LastModifiedOn,omitempty"` diff --git a/octopusdeploy/octopusdeploy.go b/octopusdeploy/octopusdeploy.go index 8b323121..698a403c 100644 --- a/octopusdeploy/octopusdeploy.go +++ b/octopusdeploy/octopusdeploy.go @@ -13,24 +13,26 @@ import ( type Client struct { sling *sling.Sling // Octopus Deploy API Services - Account *AccountService - Certificate *CertificateService - DeploymentProcess *DeploymentProcessService - ProjectGroup *ProjectGroupService - Project *ProjectService - ProjectTrigger *ProjectTriggerService - Environment *EnvironmentService - Feed *FeedService - Variable *VariableService - MachinePolicy *MachinePolicyService - Machine *MachineService - Lifecycle *LifecycleService - LibraryVariableSet *LibraryVariableSetService - Interruption *InterruptionsService - TagSet *TagSetService - Tenant *TenantService - Space *SpaceService - Channel *ChannelService + Account *AccountService + ActionTemplate *ActionTemplateService + Certificate *CertificateService + CommunityActionTemplate *CommunityActionTemplateService + DeploymentProcess *DeploymentProcessService + ProjectGroup *ProjectGroupService + Project *ProjectService + ProjectTrigger *ProjectTriggerService + Environment *EnvironmentService + Feed *FeedService + Variable *VariableService + MachinePolicy *MachinePolicyService + Machine *MachineService + Lifecycle *LifecycleService + LibraryVariableSet *LibraryVariableSetService + Interruption *InterruptionsService + TagSet *TagSetService + Tenant *TenantService + Space *SpaceService + Channel *ChannelService } // NewClient returns a new Client. @@ -39,50 +41,60 @@ func NewClient(httpClient *http.Client, octopusURL, octopusAPIKey string) *Clien baseURLWithAPI = fmt.Sprintf("%s/api/", baseURLWithAPI) base := sling.New().Client(httpClient).Base(baseURLWithAPI).Set("X-Octopus-ApiKey", octopusAPIKey) return &Client{ - sling: base, - Account: NewAccountService(base.New()), - Certificate: NewCertificateService(base.New()), - DeploymentProcess: NewDeploymentProcessService(base.New()), - ProjectGroup: NewProjectGroupService(base.New()), - Project: NewProjectService(base.New()), - ProjectTrigger: NewProjectTriggerService(base.New()), - Environment: NewEnvironmentService(base.New()), - Feed: NewFeedService(base.New()), - Variable: NewVariableService(base.New()), - MachinePolicy: NewMachinePolicyService(base.New()), - Machine: NewMachineService(base.New()), - Lifecycle: NewLifecycleService(base.New()), - LibraryVariableSet: NewLibraryVariableSetService(base.New()), - Interruption: NewInterruptionService(base.New()), - TagSet: NewTagSetService(base.New()), - Tenant: NewTenantService(base.New()), - Space: NewSpaceService(base.New()), - Channel: NewChannelService(base.New()), + sling: base, + Account: NewAccountService(base.New()), + ActionTemplate: NewActionTemplateService(base.New()), + Certificate: NewCertificateService(base.New()), + CommunityActionTemplate: NewCommunityActionTemplateService(base.New(), ""), + DeploymentProcess: NewDeploymentProcessService(base.New()), + ProjectGroup: NewProjectGroupService(base.New()), + Project: NewProjectService(base.New()), + ProjectTrigger: NewProjectTriggerService(base.New()), + Environment: NewEnvironmentService(base.New()), + Feed: NewFeedService(base.New()), + Variable: NewVariableService(base.New()), + MachinePolicy: NewMachinePolicyService(base.New()), + Machine: NewMachineService(base.New()), + Lifecycle: NewLifecycleService(base.New()), + LibraryVariableSet: NewLibraryVariableSetService(base.New()), + Interruption: NewInterruptionService(base.New()), + TagSet: NewTagSetService(base.New()), + Tenant: NewTenantService(base.New()), + Space: NewSpaceService(base.New()), + Channel: NewChannelService(base.New()), } } func ForSpace(httpClient *http.Client, octopusURL, octopusAPIKey string, space *Space) *Client { baseURLWithAPI := strings.TrimRight(octopusURL, "/") - baseURLWithAPI = fmt.Sprintf("%s/api/%s/", baseURLWithAPI, space.ID) - base := sling.New().Client(httpClient).Base(baseURLWithAPI).Set("X-Octopus-ApiKey", octopusAPIKey) + baseURLWithAPI = fmt.Sprintf("%s/api", baseURLWithAPI) + fmt.Println(baseURLWithAPI) + base := sling.New().Client(httpClient).Base(baseURLWithAPI+"/").Set("X-Octopus-ApiKey", octopusAPIKey) + + baseURLWithAPI = fmt.Sprintf("%s/%s/", baseURLWithAPI, space.ID) + fmt.Println(baseURLWithAPI) + basespace := sling.New().Client(httpClient).Base(baseURLWithAPI).Set("X-Octopus-ApiKey", octopusAPIKey) + return &Client{ - sling: base, - Account: NewAccountService(base.New()), - Certificate: NewCertificateService(base.New()), - DeploymentProcess: NewDeploymentProcessService(base.New()), - ProjectGroup: NewProjectGroupService(base.New()), - Project: NewProjectService(base.New()), - ProjectTrigger: NewProjectTriggerService(base.New()), - Environment: NewEnvironmentService(base.New()), - Feed: NewFeedService(base.New()), - Variable: NewVariableService(base.New()), - MachinePolicy: NewMachinePolicyService(base.New()), - Machine: NewMachineService(base.New()), - Lifecycle: NewLifecycleService(base.New()), - LibraryVariableSet: NewLibraryVariableSetService(base.New()), - TagSet: NewTagSetService(base.New()), - Tenant: NewTenantService(base.New()), - Channel: NewChannelService(base.New()), + sling: base, + Account: NewAccountService(basespace.New()), + ActionTemplate: NewActionTemplateService(basespace.New()), + Certificate: NewCertificateService(basespace.New()), + CommunityActionTemplate: NewCommunityActionTemplateService(base.New(), space.ID), + DeploymentProcess: NewDeploymentProcessService(basespace.New()), + ProjectGroup: NewProjectGroupService(basespace.New()), + Project: NewProjectService(basespace.New()), + ProjectTrigger: NewProjectTriggerService(basespace.New()), + Environment: NewEnvironmentService(basespace.New()), + Feed: NewFeedService(basespace.New()), + Variable: NewVariableService(basespace.New()), + MachinePolicy: NewMachinePolicyService(basespace.New()), + Machine: NewMachineService(basespace.New()), + Lifecycle: NewLifecycleService(basespace.New()), + LibraryVariableSet: NewLibraryVariableSetService(basespace.New()), + TagSet: NewTagSetService(basespace.New()), + Tenant: NewTenantService(basespace.New()), + Channel: NewChannelService(basespace.New()), } }