Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/credentials/git_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ type GitCredential interface {

// gitCredential is the embedded struct used for Git credentials.
type gitCredential struct {
CredentialType Type `json:"Type" validate:"omitempty,oneof=Anonymous GitHub Reference UsernamePassword"`
CredentialType Type `json:"Type" validate:"omitempty,oneof=Anonymous GitHub Reference UsernamePassword SshKey"`
}
6 changes: 6 additions & 0 deletions pkg/credentials/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ func (r *Resource) UnmarshalJSON(b []byte) error {
return err
}
r.Details = gitHubAppGitCredential
case GitCredentialTypeSshKey:
var sshKeyGitCredential *SshKey
if err := json.Unmarshal(*gitCredentials, &sshKeyGitCredential); err != nil {
return err
}
r.Details = sshKeyGitCredential
}

return nil
Expand Down
48 changes: 48 additions & 0 deletions pkg/credentials/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,51 @@ func TestResourceWithReferenceAsJSON(t *testing.T) {

jsonassert.New(t).Assertf(expectedJSON, string(resourceAsJSON))
}

func TestResourceWithSshKeyAsJSON(t *testing.T) {
description := internal.GetRandomName()
id := internal.GetRandomName()
name := internal.GetRandomName()
selfLink := internal.GetRandomName()
privateKey := core.NewSensitiveValue(internal.GetRandomName())

restrictions := credentials.RepositoryRestrictions{
Enabled: false,
AllowedRepositories: []string{},
}

restrictionsAsJSON, err := json.Marshal(restrictions)
require.NoError(t, err)
require.NotNil(t, restrictionsAsJSON)

sshKey := credentials.NewSshKey(privateKey)
sshKey.Username = internal.GetRandomName()
sshKey.KeyName = internal.GetRandomName()

sshKeyAsJSON, err := json.Marshal(sshKey)
require.NoError(t, err)
require.NotNil(t, sshKeyAsJSON)

resource := credentials.NewResource(name, sshKey)
resource.Description = description
resource.ID = id
resource.Links["Self"] = selfLink
resource.RepositoryRestrictions = &restrictions

expectedJSON := fmt.Sprintf(`{
"Description": "%s",
"Details": %s,
"RepositoryRestrictions": %s,
"Id": "%s",
"Name": "%s",
"Links": {
"Self": "%s"
}
}`, description, sshKeyAsJSON, restrictionsAsJSON, id, name, selfLink)

resourceAsJSON, err := json.Marshal(resource)
require.NoError(t, err)
require.NotNil(t, resourceAsJSON)

jsonassert.New(t).Assertf(expectedJSON, string(resourceAsJSON))
}
69 changes: 69 additions & 0 deletions pkg/credentials/service_v2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package credentials

import (
"github.com/OctopusDeploy/go-octopusdeploy/v2/internal"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/constants"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/newclient"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/resources"
)

const templateV2 = "/api/{spaceId}/git-credentials{/id}/v2{?skip,take,name}"

type CreateGitCredentialResponseV2 struct {
ID string `json:"Id"`
}

type getGitCredentialByIdResponseV2 struct {
GitCredential *Resource `json:"GitCredential"`
}

// AddV2 creates a new Git credential and returns the ID of the newly-created credential
func AddV2(client newclient.Client, gitCredential *Resource) (*CreateGitCredentialResponseV2, error) {
if gitCredential == nil {
return nil, internal.CreateInvalidParameterError(constants.OperationAdd, constants.ParameterGitCredential)
}

return newclient.Add[CreateGitCredentialResponseV2](client, templateV2, gitCredential.SpaceID, gitCredential)
}

// GetV2 returns a page of Git credentials matching the query
func GetV2(client newclient.Client, spaceID string, query Query) (*resources.Resources[*Resource], error) {
return newclient.GetByQuery[Resource](client, templateV2, spaceID, query)
}

// GetByIDV2 returns the Git credential or an error
func GetByIDV2(client newclient.Client, spaceID string, ID string) (*Resource, error) {
if internal.IsEmpty(ID) {
return nil, internal.CreateInvalidParameterError(constants.OperationGetByID, constants.ParameterID)
}

spaceID, err := internal.GetSpaceID(spaceID, client.GetSpaceID())
if err != nil {
return nil, err
}

path, err := client.URITemplateCache().Expand(templateV2, map[string]any{
"spaceId": spaceID,
"id": ID,
})
if err != nil {
return nil, err
}

response, err := newclient.Get[getGitCredentialByIdResponseV2](client.HttpSession(), path)
if err != nil {
return nil, err
}

return response.GitCredential, nil
}

// UpdateV2 modifies a Git credential
func UpdateV2(client newclient.Client, gitCredential *Resource) error {
if gitCredential == nil {
return internal.CreateInvalidParameterError(constants.OperationUpdate, constants.ParameterGitCredential)
}

_, err := newclient.Update[Resource](client, templateV2, gitCredential.SpaceID, gitCredential.GetID(), gitCredential)
return err
}
52 changes: 52 additions & 0 deletions pkg/credentials/service_v2_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package credentials

import (
"encoding/json"
"testing"

"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/newclient"
"github.com/stretchr/testify/require"
)

func TestTemplateV2Expansion(t *testing.T) {
cache := newclient.NewClient(&newclient.HttpSession{}).URITemplateCache()

listOrCreate, err := cache.Expand(templateV2, map[string]any{"spaceId": "Spaces-1"})
require.NoError(t, err)
require.Equal(t, "/api/Spaces-1/git-credentials/v2", listOrCreate)

byIDOrModify, err := cache.Expand(templateV2, map[string]any{"spaceId": "Spaces-1", "id": "GitCredentials-1"})
require.NoError(t, err)
require.Equal(t, "/api/Spaces-1/git-credentials/GitCredentials-1/v2", byIDOrModify)

withQuery, err := cache.Expand(templateV2, map[string]any{"spaceId": "Spaces-1", "name": "foo", "skip": 5, "take": 10})
require.NoError(t, err)
require.Equal(t, "/api/Spaces-1/git-credentials/v2?skip=5&take=10&name=foo", withQuery)
}

func TestCreateGitCredentialResponseV2Unmarshal(t *testing.T) {
var response CreateGitCredentialResponseV2
err := json.Unmarshal([]byte(`{ "Id": "GitCredentials-1" }`), &response)
require.NoError(t, err)
require.Equal(t, "GitCredentials-1", response.ID)
}

func TestGetGitCredentialByIdResponseV2Unmarshal(t *testing.T) {
inputJSON := `{
"GitCredential": {
"Id": "GitCredentials-1",
"SpaceId": "Spaces-1",
"Name": "my-credential",
"Details": { "Type": "SshKey", "Username": "git", "PrivateKey": { "HasValue": true } },
"RepositoryRestrictions": { "Enabled": false, "AllowedRepositories": [] },
"Links": {}
}
}`

var response getGitCredentialByIdResponseV2
err := json.Unmarshal([]byte(inputJSON), &response)
require.NoError(t, err)
require.NotNil(t, response.GitCredential)
require.Equal(t, "GitCredentials-1", response.GitCredential.GetID())
require.Equal(t, GitCredentialTypeSshKey, response.GitCredential.Details.Type())
}
36 changes: 36 additions & 0 deletions pkg/credentials/service_v2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package credentials_test

import (
"testing"

"github.com/OctopusDeploy/go-octopusdeploy/v2/internal"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/constants"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/credentials"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/newclient"
"github.com/stretchr/testify/require"
)

func createClient() newclient.Client {
return newclient.NewClient(&newclient.HttpSession{})
}

func TestAddV2NilCredential(t *testing.T) {
response, err := credentials.AddV2(createClient(), nil)
require.Equal(t, internal.CreateInvalidParameterError(constants.OperationAdd, constants.ParameterGitCredential), err)
require.Nil(t, response)
}

func TestGetByIDV2EmptyID(t *testing.T) {
resource, err := credentials.GetByIDV2(createClient(), "Spaces-1", "")
require.Equal(t, internal.CreateInvalidParameterError(constants.OperationGetByID, constants.ParameterID), err)
require.Nil(t, resource)

resource, err = credentials.GetByIDV2(createClient(), "Spaces-1", " ")
require.Equal(t, internal.CreateInvalidParameterError(constants.OperationGetByID, constants.ParameterID), err)
require.Nil(t, resource)
}

func TestUpdateV2NilCredential(t *testing.T) {
err := credentials.UpdateV2(createClient(), nil)
require.Equal(t, internal.CreateInvalidParameterError(constants.OperationUpdate, constants.ParameterGitCredential), err)
}
30 changes: 30 additions & 0 deletions pkg/credentials/ssh_key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package credentials

import (
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/core"
)

type SshKey struct {
Username string `json:"Username,omitempty"`
PrivateKey *core.SensitiveValue `json:"PrivateKey,omitempty"`
Passphrase *core.SensitiveValue `json:"Passphrase,omitempty"`
KeyName string `json:"KeyName,omitempty"`
PrivateKeyFingerprint string `json:"PrivateKeyFingerprint,omitempty"`

gitCredential
}

func NewSshKey(privateKey *core.SensitiveValue) *SshKey {
return &SshKey{
PrivateKey: privateKey,
gitCredential: gitCredential{
CredentialType: GitCredentialTypeSshKey,
},
}
}

func (s *SshKey) Type() Type {
return s.CredentialType
}

var _ GitCredential = &SshKey{}
1 change: 1 addition & 0 deletions pkg/credentials/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ const (
GitCredentialTypeGitHubApp = Type("GitHub")
GitCredentialTypeReference = Type("Reference")
GitCredentialTypeUsernamePassword = Type("UsernamePassword")
GitCredentialTypeSshKey = Type("SshKey")
)
29 changes: 22 additions & 7 deletions pkg/platformhubgitcredential/platform_hub_git_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,35 @@ func (r *PlatformHubGitCredential) UnmarshalJSON(b []byte) error {
r.RepositoryRestrictions = &repositoryRestrictions
}

var gitCredentials *json.RawMessage

if rawResource["Details"] != nil {
detailsValue := rawResource["Details"]

if err := json.Unmarshal(*detailsValue, &gitCredentials); err != nil {
var properties map[string]*json.RawMessage
if err := json.Unmarshal(*detailsValue, &properties); err != nil {
return err
}

var usernamePasswordGitCredential *credentials.UsernamePassword
if err := json.Unmarshal(*gitCredentials, &usernamePasswordGitCredential); err != nil {
return err
credentialType := credentials.GitCredentialTypeUsernamePassword
if properties["Type"] != nil {
if err := json.Unmarshal(*properties["Type"], &credentialType); err != nil {
return err
}
}

switch credentialType {
case credentials.GitCredentialTypeSshKey:
var sshKeyGitCredential *credentials.SshKey
if err := json.Unmarshal(*detailsValue, &sshKeyGitCredential); err != nil {
return err
}
r.Details = sshKeyGitCredential
default:
var usernamePasswordGitCredential *credentials.UsernamePassword
if err := json.Unmarshal(*detailsValue, &usernamePasswordGitCredential); err != nil {
return err
}
r.Details = usernamePasswordGitCredential
}
r.Details = usernamePasswordGitCredential
}

return nil
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package platformhubgitcredential

import (
"github.com/OctopusDeploy/go-octopusdeploy/v2/internal"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/credentials"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/newclient"
"github.com/OctopusDeploy/go-octopusdeploy/v2/pkg/resources"
"github.com/OctopusDeploy/go-octopusdeploy/v2/uritemplates"
)

const templateV2 = "/api/platformhub/git-credentials{/id}/v2{?skip,take,name}"

type CreatePlatformHubGitCredentialResponseV2 struct {
ID string `json:"Id"`
}

// AddV2 creates a new Platform Hub git credential and returns the ID of the newly-created credential
func AddV2(client newclient.Client, platformHubGitCredential *PlatformHubGitCredential) (*CreatePlatformHubGitCredentialResponseV2, error) {
if platformHubGitCredential == nil {
return nil, internal.CreateRequiredParameterIsEmptyOrNilError("platformHubGitCredential")
}
if platformHubGitCredential.Name == "" {
return nil, internal.CreateRequiredParameterIsEmptyOrNilError("platformHubGitCredential.Name")
}

path, err := client.URITemplateCache().Expand(templateV2, map[string]any{})
if err != nil {
return nil, err
}

return newclient.Post[CreatePlatformHubGitCredentialResponseV2](client.HttpSession(), path, platformHubGitCredential)
}

// GetV2 returns a page of Platform Hub git credentials matching the query
func GetV2(client newclient.Client, query credentials.Query) (*resources.Resources[*PlatformHubGitCredential], error) {
values, _ := uritemplates.Struct2map(query)
if values == nil {
values = map[string]any{}
}

path, err := client.URITemplateCache().Expand(templateV2, values)
if err != nil {
return nil, err
}

return newclient.Get[resources.Resources[*PlatformHubGitCredential]](client.HttpSession(), path)
}

// GetByIDV2 returns the Platform Hub git credential or an error
func GetByIDV2(client newclient.Client, id string) (*PlatformHubGitCredential, error) {
if id == "" {
return nil, internal.CreateRequiredParameterIsEmptyOrNilError("id")
}

path, err := client.URITemplateCache().Expand(templateV2, map[string]any{"id": id})
if err != nil {
return nil, err
}

return newclient.Get[PlatformHubGitCredential](client.HttpSession(), path)
}

// UpdateV2 modifies a Platform Hub git credential
func UpdateV2(client newclient.Client, platformHubGitCredential *PlatformHubGitCredential) error {
if platformHubGitCredential == nil {
return internal.CreateRequiredParameterIsEmptyOrNilError("platformHubGitCredential")
}
if platformHubGitCredential.ID == "" {
return internal.CreateRequiredParameterIsEmptyOrNilError("platformHubGitCredential.ID")
}
if platformHubGitCredential.Name == "" {
return internal.CreateRequiredParameterIsEmptyOrNilError("platformHubGitCredential.Name")
}

path, err := client.URITemplateCache().Expand(templateV2, map[string]any{"id": platformHubGitCredential.ID})
if err != nil {
return err
}

_, err = newclient.Put[PlatformHubGitCredential](client.HttpSession(), path, platformHubGitCredential)
return err
}
Loading
Loading