Giter VIP home page Giter VIP logo

go-octopusdeploy's Introduction

go-octopusdeploy Logo

go-octopusdeploy

Go API Client for Octopus Deploy ๐Ÿ™

GitHub release PkgGoDev Go Report


Install

go get "github.com/OctopusDeploy/go-octopusdeploy/v2"

Usage

import "github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/client"

The Octopus REST API is exposed through service fields of the client. An API key is required to communicate with the API (see How to Create an API Key for more information).

apiKey := "API-YOUR_API_KEY"
octopusURL := "https://your_octopus_url"
spaceID := "space-id" // can also be blank to assume the default space

apiURL, err := url.Parse(octopusURL)
if err != nil {
    _ = fmt.Errorf("error parsing URL for Octopus API: %v", err)
    return
}

// the first parameter for NewClient can accept a http.Client if you wish to
// override the default; also, the spaceID may be an empty string (i.e. "") if
// you wish to load the default space
octopusClient, err := client.NewClient(nil, apiURL, apiKey, spaceID)
if err != nil {
    _ = fmt.Errorf("error creating API client: %v", err)
    return
}

Once the client has been initialized, APIs can be targeted through the model and services available:

usernamePasswordAccount := accounts.NewUsernamePasswordAccount(name)
usernamePasswordAccount.Username = username

createdAccount, err := accounts.Add(octopusClient, usernamePasswordAccount)
if err != nil {
    _ = fmt.Errorf("error adding account: %v", err)
}

Operations like Add, DeleteByID, GetByID, and Update are supported by most services that are exposed through the client if not exposed in the package. These operations are configured at runtime since the Octopus REST API is hypermedia-driven.

Numerous code samples that showcase the API and this client are available in the examples directory. There are also many integration and unit tests available to examine that demonstrate the capabilities of this API client.

๐Ÿค Contributions

Contributions are welcome! โค๏ธ Please read our Contributing Guide for information about how to get involved in this project.

go-octopusdeploy's People

Contributors

adminturneddevops avatar aperebus avatar benpearce1 avatar borland avatar domenicsim1 avatar droyad avatar evan-cleary avatar geofflamrock avatar hnrkndrssn avatar huyphannguyen avatar isaaccalligeros95 avatar jbristowe avatar jeff-french avatar kevjt avatar matthodge avatar mcasperson avatar mhenderson-so avatar mik-ky avatar pemaxim avatar rain-on avatar slewis74 avatar susanpann avatar tleed5 avatar toneill-newinnov avatar toneill818 avatar tothegills avatar tw17 avatar vedsmand avatar zentron avatar zlepper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-octopusdeploy's Issues

Disambiguate Deployment Targets

Is your feature request related to a problem? Please describe.
Deployment targets are ONLY differentiated by their associated endpoint (or communication style). This is non-optimal since deployment target types cannot be identified without inspection of the underlying endpoint.

Describe the solution you'd like
Deployment targets should be classified by their role (i.e. listening tentacle).

Additional context
The following types are to be implemented and based from DeploymentTarget:

  • AzureCloudServiceDeploymentTarget
  • AzureVirtualMachineDeploymentTarget (TBD)
  • AzureWebAppDeploymentTarget (TBD)
  • AzureWebAppDeploymentTarget (TBD)
  • CloudRegionDeploymentTarget
  • KubernetesClusterDeploymentTarget
  • ListeningTentacleDeploymentTarget
  • OfflinePackageDropDeploymentTarget
  • PollingTentacleDeploymentTarget
  • ServiceFabricClusterDeploymentTarget
  • SSHConnectionDeploymentTarget

Add examples to interact with Project Templates variables

Problem

I'm struggling to understand how to interact with project templates variables. The variableService object seems to only expose project variables from what I've been able to see.

This works

	vs, err := client.Variables.GetByName("Projects-1", "project_variable", &octopusdeploy.VariableScope{})
	if err != nil {
		log.Fatalf("error getting variable: %v", err)
	}
	fmt.Printf("%+#v", vs)

This doesn't:

	vs, err := client.Variables.GetByName("Projects-1", "project_template_variable", &octopusdeploy.VariableScope{})
	if err != nil {
		log.Fatalf("error getting variable: %v", err)
	}
	fmt.Printf("%+#v", vs)

If another struct can expose those, that's fine, but it's not obvious which one.

Solutions

  • Provide a example how how to use it in the repository's examples directory

I tried looking in the Octopus Terraform provider repo, but haven't been able to find something useful regarding this issue.

Screen Shot 2022-01-20 at 6 04 36 PM

Token missing from account_type

Currently, we use the terraform-octopus-deploy to configure out Octopus Servers. In May, when the account_types were changed to enums, it has caused an issue for our deployment targets to Kubernetes; the provider now complains that Token is not an appropriate Account type.

I have attempted to make the change but am having difficulty generating the enum.

Adopt Go 1.18

This issue proposes the adoption of Go 1.18 for its support of generics and various bug fixes.

Remove redundant query parameters from API surface

Example:

ProjectsQuery in the library has this shape:

type ProjectsQuery struct {
	ClonedFromProjectID string   `url:"clonedFromProjectId"`
	IDs                 []string `uri:"ids,omitempty" url:"ids,omitempty"`
	IsClone             bool     `uri:"clone,omitempty" url:"clone,omitempty"`
	Name                string   `uri:"name,omitempty" url:"name,omitempty"`
	PartialName         string   `uri:"partialName,omitempty" url:"partialName,omitempty"`
	Skip                int      `uri:"skip,omitempty" url:"skip,omitempty"`
	Take                int      `uri:"take,omitempty" url:"take,omitempty"`
}

Note the presence of both Name and PartialName.
To a casual observer, Name implies an exact name match -- however in practice the Octopus Server treats them both as a partial match.

I.e. given a project "Integrations", Query for {Name: "gr"} will find it. This is legacy behaviour in the server, and to avoid confusion we should remove the Name field from ProjectsQuery.

As part of this work, we should sweep the library's API surface and remove any other similarly redundant fields if there are others beyond Project Name

CreateReleaseV1 serializes channel incorrectly

the CreateReleaseV1 struct is serialized to JSON and passed to the CreateReleaseV1 API in the server.

The struct has

ChannelNameOrID       string   `json:"channelIdOrName,omitempty"`

However the server expects a JSON key of channelName

This results in channel name not being passed correctly through to the server, which selects the default channel rather than the specified one

Rename tag 1.7.0 to v1.7.0

Not a bug per say

We can't use a tag without the "v" in front of it when using Go Module so it defaults to v1.6.0 which is annoying because it lack many features.

Can we rename/create a tag with the proper format?

Support User Role Operations

Is your feature request related to a problem? Please describe.
Currently, user role operations (i.e. Add, GetByID, Update) are not supported.

Describe the solution you'd like
User role operations should be supported in order for the Terrform Provider to manage them.

Missing 'Expires' option on the API Key creation process

Currently, the NewAPIKey function doesn't include an option to set an Expiration date. Because the Default is 'never expires' and Octopus Deploy doesn't allow you to create an API key for longer than your current key is valid, it means you can't create API Keys using an API that expires. It seems that since the create process and return process both rely on the same object, the expiration date is also never returned.

The NewAPIKey function should be updated to include an optional Expires param.

func NewAPIKey(purpose string, userID string) *APIKey {

The APIKey struct should include an Expires key.

type APIKey struct {

Enhance coverage of Runbooks

Is your feature request related to a problem? Please describe.

The client doesn't contain the following:

  • Ability to create new runbook snapshot
  • Retrieve runbook snapshot template
  • Runbook snapshot object

Describe the solution you'd like

I'd like to be able to create runbook snapshots using the client and have the ability to programmatically publish them.

Describe alternatives you've considered

Additional context
Add any other context or screenshots about the feature request here.

ReleaseQuery and ReleasesQuery need ProjectId filter

Is your feature request related to a problem? Please describe.
Current query objects do not allow to filter by Project causing you to have to search every release in the system.

Describe the solution you'd like
Add a ProjectID filter to the query objects to return releases only related to the specified project

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

ChannelsQuery needs ProjectId filter or Project object needs channel list

Is your feature request related to a problem? Please describe.
The project object doesn't contain a list of channels associated with the project. The ChannelQuery struct only allows for ID or Partial Name, without having the list associated to the project, you're forced to use Partial Name. This can lead to a lot of results and you need to loop to retrieve all of them, then iterate through them until you find the one you're looking for.

Describe the solution you'd like
Two solutions could resolve this issue:

  • Include associated channel references on the project object
  • Include ProjectId in the ChannelQuery struct so you can limit results to channels pertinent to the project in question

Describe alternatives you've considered
This works, but has to retrieve all channels with the matching partial name

func GetChannel(client *octopusdeploy.Client, project *octopusdeploy.Project, ChannelName string) *octopusdeploy.Channel {
	channelQuery := octopusdeploy.ChannelsQuery{
		PartialName: ChannelName,
		Skip:        0,
	}

	results := []*octopusdeploy.Channel{}

	for true {
		// Call for results
		channels, err := client.Channels.Get(channelQuery)

		if err != nil {
			log.Println(err)
		}

		// Check returned number of items
		if len(channels.Items) == 0 {
			break
		}

		// append items to results
		results = append(results, channels.Items...)

		// Update query
		channelQuery.Skip += len(channels.Items)
	}

	for i := 0; i < len(results); i++ {
		if results[i].ProjectID == project.ID && results[i].Name == ChannelName {
			return results[i]
		}
	}

	return nil
}

Additional context
Add any other context or screenshots about the feature request here.

Archive/Unarchive Support for Certificates

Is your feature request related to a problem? Please describe.
Currently, the CertificateService is missing an implementation for the Archive and Unarchive endpoint operations in Octopus Deploy.

Describe the solution you'd like
The CertificateService needs to be modified to include an implementation for the Archive and Unarchive endpoint operations in Octopus Deploy. This includes the integration tests.

[BUG] Missing Support for Deployment Settings (Projects)

Deployment settings are associated with projects through the endpoint: /api/<space-id>/projects/<project-id>/deploymentsettings. Support for these settings is currently missing from the Go API client. This issue proposes supporting it.

[BUG] serverStatuService is Misspelled

Please provide all the information requested. Issues that do not follow this format are likely to stall.

Description
The type, serverStatuService is misspelled.

Expected Behavior
The type should be serverStatusService.

User Struct is Outdated

Description
The User struct definition is misaligned to the UserResource model in the API specification. It needs to be updated to properly serialize to/from its JSON representation.

Expected Behavior
The User struct should properly represent the UserResource model in the API specification.

The Space service filter should not allow Name

Description
The Space service currently supports both PartialName and Name filtering. However, the Space API in Octopus only supports PartialName, if you provide Name it will be ignored and the filter will therefore be blank, which will result in all spaces being returned.

Expected Behavior
Name should not be supported in the SpacesQuery.

Return HTTP 404 for Variable DELETEs When Not Found

The VariableService returns a generic error when performing a DELETE command against the underlying endpoint. Behind the scenes, these variables are stored in a VariableSet, which is never deleted -- but that's for another time. ;)

This issue requests correcting the behaviour associated with DELETEs for a variable if it's not found.

Related: #181

Standardize on a method of pagination

Issue by MattHodge
Wednesday Oct 24, 2018 at 10:08 GMT
Originally opened as MattHodge/go-octopusdeploy#34


Newer versions of the Octopus Deploy API support querying for a large number of records using ?take=, for example: lifecycles?take=2147483647

This can prevent multiple queries against an Octopus Deploy server but doesn't work in older versions of the API.

Is there a way a helper method can be provided for pagination to save having to do it per resource?

Add User Role

The type, User Role doesn't exist in the Go client and it should be supported.

Feature: Remove Default Space for Connections

Currently, the Go API client assumes a default space for resolving routes, etc. for the root document. This assumption should be eliminated and routes should explicitly use a space ID. Additionally, the Go API client operations MUST be partitioned to support global AND space-specific routes (i.e. create a space).

Would like to be able to access the server status API

Is your feature request related to a problem? Please describe.

Wanted to get service status. Was not able to. server_status_service.go does not seem to have any methods, and the likes of apiGet is private so cannot implement myself without re-inventing the wheel.

Describe the solution you'd like
I'd like the api for server status implemented similar to other services.

Describe alternatives you've considered

  • Not use this library and use http client instead
  • Implement the methods myself by copy-pasting code of apiGet and dependent methods to my project

Eliminate the Use of Copier

The Copier library is used in various parts of the Go API library. Unfortunately, it's been the source of many bugs in the past. This issue proposals the removal of this library.

Api errors are propagated as plain strings using an unpleasant format

In situations where the Octopus Server returns an error, the core.APIErrorChecker function is run to validate the response.

This function has a hardcoded error template string format of "octopus deploy api returned an error on endpoint %s - %s", urlPath, octopusDeployError.Errors
Note: octopusDeployError.Errors is a []string, representing a JSON array that the server sent us in the error response.

This results in a caller, (e.g. the CLI) receiving a string such as the following:

octopus deploy api returned an error on endpoint /api/Spaces-1/releases/create/v1 - [Release '5.0.2' already exists for this project. Please use a different version, or look at using a mask to auto-increment the number.]

This is not particularly friendly for end-user display. The brute force option would be to regex or string-split to pull out the contents inside the [], however this is incredibly brittle.

My preferred option would be to have the APIErrorChecker return a richer error struct, which contained the server-sent strings in an array that could be accessed by the caller. This would enable the CLI to simply print the server-sent error: Release '5.0.2' already exists for this project. Please use a different version, or look at using a mask to auto-increment the number.

Complete Tasks implementation

Is your feature request related to a problem? Please describe.
I was attempting to get a list of queued tasks so I could cancel them. I found the TasksQuery, but client doesn't have a method to pass it to.

Describe the solution you'd like
Use the TasksQuery to query tasks and return the ones matching the query.

Describe alternatives you've considered
Most likey not the best solution, but it does work,

func GetQueuedTasks(octopusURL *url.URL, APIKey string, space *octopusdeploy.Space) []interface{} {
	// Query api for tasks
	tasksApi := octopusURL.String() + "/api/" + space.ID + "/tasks?States=Queued&Name=Deploy"

	// Create http client
	httpClient := &http.Client{}

	// perform request
	request, _ := http.NewRequest("GET", tasksApi, nil)
	request.Header.Set("X-Octopus-ApiKey", APIKey)
	response, err := httpClient.Do(request)

	if err != nil {
		log.Println(err)
	}

	responseData, err := ioutil.ReadAll(response.Body)

	var f interface{}
	jsonErr := json.Unmarshal(responseData, &f)
	if jsonErr != nil {
		log.Println(err)
	}

	tasks := f.(map[string]interface{})

	// return the tasks
	return tasks["Items"].([]interface{})
}```

**Additional context**
Add any other context or screenshots about the feature request here.

Users.GetTeams should return *[]octopusdeploy.Team objects instead of *[]octopusdeploy.ProjectedTeamReferenceDataItem

Is your feature request related to a problem? Please describe.
Users.GetTeams returns *[]octopusdeploy.ProjectedTeamReferenceDataItem which reports that it's non-indexable.

Describe the solution you'd like
It would make more sense to return *[]octopusdeploy.Team.

Describe alternatives you've considered
You can get at the data, but it's a little convoluted if you're not familiar with the nuances of Go

for i := 0; i < len(*teams); i++ {
teamsReference := *teams
teamsReference[i]
}

Additional context
Add any other context or screenshots about the feature request here.

Enhancement: Disambiguate Feed Types

Is your feature request related to a problem? Please describe.
Feeds are ONLY differentiated by their associated FeedType. Furthermore, specific feeds -- such as ones for Docker -- are serialised incorrectly when used by the Terraform Provider for Octopus Deploy. This results in invalid plans to be generated through terraform plan. See Feed creation always has planned changes (#142) for more information concerning this behaviour.

Describe the solution you'd like
Feeds should be defined by their type (i.e. Docker container registry).

Additional context
The following types are to be implemented and support for feeds:

  • AwsElasticContainerRegistry
  • DockerContainerRegistry
  • GitHubRepositoryFeed
  • HelmFeed
  • MavenFeed
  • NuGetFeed

Add Support for Tenant Variable Association

Currently, the TenantService does not support operations to create, get, or update variables that are associated with a particular tenant. Associating variables with a tenant is supported by the following routes:

/tenants/{id}/variables
/{baseSpaceId}/tenants/{id}/variables

Specifically, the HTTP verbs, POST, GET, and PUT map the create, get, and update operations to associate variables with a tenant.

This issue requests adding support for these endpoints and their operations.

Disambiguate Workers

Is your feature request related to a problem? Please describe.
Workers are ONLY differentiated by their associated endpoint (or communication style). This is non-optimal since worker types cannot be identified without inspection of the underlying endpoint.

Describe the solution you'd like
Workers should be classified by their role (i.e. listening tentacle).

Additional context
The following types are to be implemented and based from Worker:

  • ListeningTentacleWorker
  • PollingTentacleWorker
  • SSHConnectionWorker

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.