From 32819e847884dd2d2ef78130ce0119373da7ea0a Mon Sep 17 00:00:00 2001 From: Sharad Kesarwani <108344822+sharadkesarwani@users.noreply.github.com> Date: Wed, 27 Sep 2023 13:49:30 +0530 Subject: [PATCH 1/4] Added support for account, externalId and aws credentials support (#261) --- examples/service/account/create/main.go | 34 ++++ examples/service/account/delete/main.go | 24 +++ examples/service/account/read/main.go | 31 +++ examples/service/awscredential/create/main.go | 28 +++ examples/service/awscredential/read/main.go | 31 +++ examples/service/externalid/create/main.go | 29 +++ examples/service/externalid/read/main.go | 29 +++ service/account/account.go | 37 ++++ service/account/providers/aws/account.go | 181 ++++++++++++++++++ .../account/providers/aws/awscredential.go | 141 ++++++++++++++ .../account/providers/aws/awsexternalId.go | 149 ++++++++++++++ service/account/providers/aws/service.go | 45 +++++ spotinst/client/client.go | 12 ++ spotinst/client/request.go | 43 +++++ 14 files changed, 814 insertions(+) create mode 100644 examples/service/account/create/main.go create mode 100644 examples/service/account/delete/main.go create mode 100644 examples/service/account/read/main.go create mode 100644 examples/service/awscredential/create/main.go create mode 100644 examples/service/awscredential/read/main.go create mode 100644 examples/service/externalid/create/main.go create mode 100644 examples/service/externalid/read/main.go create mode 100644 service/account/account.go create mode 100644 service/account/providers/aws/account.go create mode 100644 service/account/providers/aws/awscredential.go create mode 100644 service/account/providers/aws/awsexternalId.go create mode 100644 service/account/providers/aws/service.go diff --git a/examples/service/account/create/main.go b/examples/service/account/create/main.go new file mode 100644 index 00000000..5c5f80a2 --- /dev/null +++ b/examples/service/account/create/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/account" + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" + "log" +) + +func main() { + sess := session.New() + svc := account.New(sess) + ctx := context.Background() + out, err := svc.CloudProviderAWS().CreateAccount(ctx, &aws.CreateAccountInput{ + Account: &aws.Account{ + Name: spotinst.String("testAcct_123"), + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to create account: %v", err) + } + + // Output. + if out.Account != nil { + log.Printf("Account %q: %s", + spotinst.StringValue(out.Account.ID), + stringutil.Stringify(out.Account)) + } + +} diff --git a/examples/service/account/delete/main.go b/examples/service/account/delete/main.go new file mode 100644 index 00000000..bd983d1a --- /dev/null +++ b/examples/service/account/delete/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/account" + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "log" +) + +func main() { + sess := session.New() + svc := account.New(sess) + ctx := context.Background() + _, err := svc.CloudProviderAWS().DeleteAccount(ctx, &aws.DeleteAccountInput{ + AccountID: spotinst.String("act-123456"), + }) + + if err != nil { + log.Fatalf("spotinst: failed to delete account: %v", err) + } + +} diff --git a/examples/service/account/read/main.go b/examples/service/account/read/main.go new file mode 100644 index 00000000..9e660a81 --- /dev/null +++ b/examples/service/account/read/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/account" + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" + "log" +) + +func main() { + sess := session.New() + svc := account.New(sess) + ctx := context.Background() + out, err := svc.CloudProviderAWS().ReadAccount(ctx, &aws.ReadAccountInput{ + AccountID: spotinst.String("act-123456"), + }) + + if err != nil { + log.Fatalf("spotinst: faccount not found: %v", err) + } + + if out.Account != nil { + log.Printf("Account %q: %s", + spotinst.StringValue(out.Account.ID), + stringutil.Stringify(out.Account)) + } + +} diff --git a/examples/service/awscredential/create/main.go b/examples/service/awscredential/create/main.go new file mode 100644 index 00000000..9c67c27d --- /dev/null +++ b/examples/service/awscredential/create/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/account" + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +func main() { + sess := session.New() + svc := account.New(sess) + ctx := context.Background() + _, err := svc.CloudProviderAWS().SetCredential(ctx, &aws.SetCredentialInput{ + Credential: &aws.Credential{ + AccountId: spotinst.String("act-12345"), + IamRole: spotinst.String("arn:aws:iam::12345:role/test-role"), + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to set credential: %v", err) + } + +} diff --git a/examples/service/awscredential/read/main.go b/examples/service/awscredential/read/main.go new file mode 100644 index 00000000..0264112d --- /dev/null +++ b/examples/service/awscredential/read/main.go @@ -0,0 +1,31 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/account" + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +func main() { + sess := session.New() + svc := account.New(sess) + ctx := context.Background() + out, err := svc.CloudProviderAWS().ReadCredential(ctx, &aws.ReadCredentialInput{ + AccountId: spotinst.String("act-12345"), + }) + + if err != nil { + log.Fatalf("spotinst: failed to fetch credential: %v", err) + } + if out != nil { + log.Printf("credential %q: %s", + spotinst.StringValue(out.Credential.AccountId), + stringutil.Stringify(out.Credential.IamRole)) + } + +} diff --git a/examples/service/externalid/create/main.go b/examples/service/externalid/create/main.go new file mode 100644 index 00000000..d000e9ba --- /dev/null +++ b/examples/service/externalid/create/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/account" + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "log" +) + +func main() { + sess := session.New() + svc := account.New(sess) + ctx := context.Background() + out, err := svc.CloudProviderAWS().CreateAWSAccountExternalId(ctx, &aws.CreateAWSAccountExternalIdInput{ + AccountID: spotinst.String("act-12345678"), + }) + + if err != nil { + log.Fatalf("spotinst: failed to genrate externalId %v", err) + } + + if out != nil { + log.Printf("externalId: %s", + spotinst.StringValue(out.AWSAccountExternalId.ExternalId)) + } + +} diff --git a/examples/service/externalid/read/main.go b/examples/service/externalid/read/main.go new file mode 100644 index 00000000..4d0340f5 --- /dev/null +++ b/examples/service/externalid/read/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/account" + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "log" +) + +func main() { + sess := session.New() + svc := account.New(sess) + ctx := context.Background() + out, err := svc.CloudProviderAWS().ReadAWSAccountExternalId(ctx, &aws.ReadAWSAccountExternalIdInput{ + AccountID: spotinst.String("act-12345678"), + }) + + if err != nil { + log.Fatalf("spotinst: failed to fetch account: %v", err) + } + + if out != nil { + log.Printf("externalId: %s", + spotinst.StringValue(out.AwsAccountExternalId.ExternalId)) + } + +} diff --git a/service/account/account.go b/service/account/account.go new file mode 100644 index 00000000..08badd6e --- /dev/null +++ b/service/account/account.go @@ -0,0 +1,37 @@ +package account + +import ( + "github.com/spotinst/spotinst-sdk-go/service/account/providers/aws" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/client" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +// Service provides the API operation methods for making requests to endpoints +// of the Spotinst API. See this package's package overview docs for details on +// the service. +type Service interface { + CloudProviderAWS() aws.Service +} + +type ServiceOp struct { + Client *client.Client +} + +var _ Service = &ServiceOp{} + +func New(sess *session.Session, cfgs ...*spotinst.Config) *ServiceOp { + cfg := &spotinst.Config{} + cfg.Merge(sess.Config) + cfg.Merge(cfgs...) + + return &ServiceOp{ + Client: client.New(cfg), + } +} + +func (s *ServiceOp) CloudProviderAWS() aws.Service { + return &aws.ServiceOp{ + Client: s.Client, + } +} diff --git a/service/account/providers/aws/account.go b/service/account/providers/aws/account.go new file mode 100644 index 00000000..935c7366 --- /dev/null +++ b/service/account/providers/aws/account.go @@ -0,0 +1,181 @@ +package aws + +import ( + "context" + "encoding/json" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/client" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/jsonutil" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/uritemplates" + "io/ioutil" + "net/http" + "time" +) + +type Account struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + OrganizationId *string `json:"organizationId,omitempty"` + AccountId *string `json:"accountId,omitempty"` + CloudProvider *string `json:"cloudProvider,omitempty"` + ProviderExternalId *string `json:"providerExternalId,omitempty"` + + // Read-only fields. + CreatedAt *time.Time `json:"createdAt,omitempty"` + + // forceSendFields is a list of field names (e.g. "Keys") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + forceSendFields []string + + // nullFields is a list of field names (e.g. "Keys") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + nullFields []string +} + +func (o *Account) SetId(v *string) *Account { + if o.ID = v; o.ID == nil { + o.nullFields = append(o.nullFields, "ID") + } + return o +} +func (o *Account) SetName(v *string) *Account { + if o.Name = v; o.Name == nil { + o.nullFields = append(o.nullFields, "Name") + } + return o +} + +func (o Account) MarshalJSON() ([]byte, error) { + type noMethod Account + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +type CreateAccountInput struct { + Account *Account `json:"account,omitempty"` +} +type CreateAccountOutput struct { + Account *Account `json:"account,omitempty"` +} + +func (s *ServiceOp) CreateAccount(ctx context.Context, input *CreateAccountInput) (*CreateAccountOutput, error) { + r := client.NewRequest(http.MethodPost, "/setup/account") + r.Obj = input + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := accountsFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(CreateAccountOutput) + if len(gs) > 0 { + output.Account = gs[0] + } + + return output, nil +} + +type ReadAccountInput struct { + AccountID *string `json:"account,omitempty"` +} +type ReadAccountOutput struct { + Account *Account `json:"account,omitempty"` +} + +func (s *ServiceOp) ReadAccount(ctx context.Context, input *ReadAccountInput) (*ReadAccountOutput, error) { + path, err := uritemplates.Expand("/setup/account/{acctId}", uritemplates.Values{"acctId": spotinst.StringValue(input.AccountID)}) + r := client.NewRequest(http.MethodGet, path) + r.Obj = input + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := accountsFromHttpResponse(resp) + if err != nil { + return nil, err + } + output := new(ReadAccountOutput) + if len(gs) > 0 { + output.Account = gs[0] + } + + return output, nil + +} + +func accountsFromHttpResponse(resp *http.Response) ([]*Account, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return accountsFromJSON(body) +} + +func accountsFromJSON(in []byte) ([]*Account, error) { + var rw client.Response + if err := json.Unmarshal(in, &rw); err != nil { + return nil, err + } + out := make([]*Account, len(rw.Response.Items)) + if len(out) == 0 { + return out, nil + } + for i, rb := range rw.Response.Items { + b, err := accountFromJSON(rb) + if err != nil { + return nil, err + } + out[i] = b + } + return out, nil +} + +func accountFromJSON(in []byte) (*Account, error) { + b := new(Account) + if err := json.Unmarshal(in, b); err != nil { + return nil, err + } + return b, nil +} + +type DeleteAccountInput struct { + AccountID *string `json:"accountId,omitempty"` +} + +type DeleteAccountOutput struct{} + +func (s *ServiceOp) DeleteAccount(ctx context.Context, input *DeleteAccountInput) (*DeleteAccountOutput, error) { + path, err := uritemplates.Expand("/setup/account/{accountId}", uritemplates.Values{ + "accountId": spotinst.StringValue(input.AccountID), + }) + if err != nil { + return nil, err + } + + r := client.NewRequest(http.MethodDelete, path) + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return &DeleteAccountOutput{}, nil +} diff --git a/service/account/providers/aws/awscredential.go b/service/account/providers/aws/awscredential.go new file mode 100644 index 00000000..d6758326 --- /dev/null +++ b/service/account/providers/aws/awscredential.go @@ -0,0 +1,141 @@ +package aws + +import ( + "context" + "encoding/json" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/client" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/jsonutil" + "io/ioutil" + "net/http" +) + +type Credential struct { + IamRole *string `json:"iamRole,omitempty"` + AccountId *string `json:"accountId,omitempty"` + + forceSendFields []string + + nullFields []string +} + +func (o Credential) MarshalJSON() ([]byte, error) { + type noMethod Credential + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *Credential) SetIamRole(v *string) *Credential { + if o.IamRole = v; o.IamRole == nil { + o.nullFields = append(o.nullFields, "IamRole") + } + return o +} +func (o *Credential) SetAccountId(v *string) *Credential { + if o.AccountId = v; o.AccountId == nil { + o.nullFields = append(o.nullFields, "AccountId") + } + return o +} + +type SetCredentialInput struct { + Credential *Credential `json:"credentials,omitempty"` +} +type SetCredentialOutput struct { + Credential *Credential `json:"Credential,omitempty"` +} + +func (s *ServiceOp) SetCredential(ctx context.Context, input *SetCredentialInput) (*SetCredentialOutput, error) { + r := client.NewRequest(http.MethodPost, "/setup/credentials/aws") + + if input != nil { + r.Params.Set("accountId", spotinst.StringValue(input.Credential.AccountId)) + } + input.Credential.AccountId = nil + r.Obj = input + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := credentialsFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(SetCredentialOutput) + if len(gs) > 0 { + output.Credential = gs[0] + } + + return output, nil +} + +type ReadCredentialInput struct { + AccountId *string `json:"accountId,omitempty"` +} +type ReadCredentialOutput struct { + Credential *Credential `json:"Credential,omitempty"` +} + +func (s *ServiceOp) ReadCredential(ctx context.Context, input *ReadCredentialInput) (*ReadCredentialOutput, error) { + r := client.NewRequest(http.MethodGet, "/setup/credentials/aws") + if input != nil { + r.Params.Set("accountId", spotinst.StringValue(input.AccountId)) + } + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := credentialsFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(ReadCredentialOutput) + if len(gs) > 0 { + output.Credential = gs[0] + } + + return output, nil +} + +func credentialsFromHttpResponse(resp *http.Response) ([]*Credential, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return credentialsFromJSON(body) +} + +func credentialsFromJSON(in []byte) ([]*Credential, error) { + var rw client.Response + if err := json.Unmarshal(in, &rw); err != nil { + return nil, err + } + out := make([]*Credential, len(rw.Response.Items)) + if len(out) == 0 { + return out, nil + } + for i, rb := range rw.Response.Items { + b, err := credentialFromJSON(rb) + if err != nil { + return nil, err + } + out[i] = b + } + return out, nil +} + +func credentialFromJSON(in []byte) (*Credential, error) { + b := new(Credential) + if err := json.Unmarshal(in, b); err != nil { + return nil, err + } + return b, nil +} diff --git a/service/account/providers/aws/awsexternalId.go b/service/account/providers/aws/awsexternalId.go new file mode 100644 index 00000000..9d538370 --- /dev/null +++ b/service/account/providers/aws/awsexternalId.go @@ -0,0 +1,149 @@ +package aws + +import ( + "context" + "encoding/json" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/client" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/jsonutil" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/uritemplates" + "io/ioutil" + "net/http" +) + +type AwsAccountExternalId struct { + AccountId *string `json:"accountId,omitempty"` + ExternalId *string `json:"externalId,omitempty"` + + // forceSendFields is a list of field names (e.g. "Keys") to + // unconditionally include in API requests. By default, fields with + // empty values are omitted from API requests. However, any non-pointer, + // non-interface field appearing in ForceSendFields will be sent to the + // server regardless of whether the field is empty or not. This may be + // used to include empty fields in Patch requests. + forceSendFields []string + + // nullFields is a list of field names (e.g. "Keys") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + nullFields []string +} + +func (o *AwsAccountExternalId) SetAccountId(v *string) *AwsAccountExternalId { + if o.AccountId = v; o.AccountId == nil { + o.nullFields = append(o.nullFields, "AccountId") + } + return o +} +func (o *AwsAccountExternalId) SetExternalId(v *string) *AwsAccountExternalId { + if o.ExternalId = v; o.ExternalId == nil { + o.nullFields = append(o.nullFields, "ExternalId") + } + return o +} + +func (o AwsAccountExternalId) MarshalJSON() ([]byte, error) { + type noMethod AwsAccountExternalId + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +type CreateAWSAccountExternalIdInput struct { + AccountID *string `json:"accountId,omitempty"` +} +type CreateAWSAccountExternalIdOutput struct { + AWSAccountExternalId *AwsAccountExternalId `json:"AWSAccountExternalId,omitempty"` +} + +func (s *ServiceOp) CreateAWSAccountExternalId(ctx context.Context, input *CreateAWSAccountExternalIdInput) (*CreateAWSAccountExternalIdOutput, error) { + r := client.NewRequest(http.MethodPost, "/setup/credentials/aws/externalId") + if input != nil { + r.Params.Set("accountId", spotinst.StringValue(input.AccountID)) + } + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + gs, err := awsAccountExternalIdFromHttpResponse(resp) + gs[0].AccountId = input.AccountID + if err != nil { + return nil, err + } + output := new(CreateAWSAccountExternalIdOutput) + if len(gs) > 0 { + output.AWSAccountExternalId = gs[0] + } + + return output, nil +} + +type ReadAWSAccountExternalIdInput struct { + AccountID *string `json:"account,omitempty"` +} +type ReadAWSAccountExternalIdOutput struct { + AwsAccountExternalId *AwsAccountExternalId `json:"externalId,omitempty"` +} + +func (s *ServiceOp) ReadAWSAccountExternalId(ctx context.Context, input *ReadAWSAccountExternalIdInput) (*ReadAWSAccountExternalIdOutput, error) { + path, err := uritemplates.Expand("/setup/credentials/aws/externalId/{acctId}", uritemplates.Values{"acctId": spotinst.StringValue(input.AccountID)}) + r := client.NewRequest(http.MethodGet, path) + r.Obj = input + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := awsAccountExternalIdFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(ReadAWSAccountExternalIdOutput) + if len(gs) > 0 { + output.AwsAccountExternalId = gs[0] + } + + return output, nil + +} + +func awsAccountExternalIdFromHttpResponse(resp *http.Response) ([]*AwsAccountExternalId, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return awsAccountExternalIdsFromJSON(body) +} + +func awsAccountExternalIdsFromJSON(in []byte) ([]*AwsAccountExternalId, error) { + var rw client.Response + if err := json.Unmarshal(in, &rw); err != nil { + return nil, err + } + out := make([]*AwsAccountExternalId, len(rw.Response.Items)) + if len(out) == 0 { + return out, nil + } + for i, rb := range rw.Response.Items { + b, err := awsAccountExternalIdFromJSON(rb) + if err != nil { + return nil, err + } + out[i] = b + } + return out, nil +} + +func awsAccountExternalIdFromJSON(in []byte) (*AwsAccountExternalId, error) { + b := new(AwsAccountExternalId) + if err := json.Unmarshal(in, b); err != nil { + return nil, err + } + return b, nil +} diff --git a/service/account/providers/aws/service.go b/service/account/providers/aws/service.go new file mode 100644 index 00000000..98846a30 --- /dev/null +++ b/service/account/providers/aws/service.go @@ -0,0 +1,45 @@ +package aws + +import ( + "context" + + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/client" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +// Service provides the API operation methods for making requests to endpoints +// of the Spotinst API. See this package's package overview docs for details on +// the service. +type Service interface { + serviceAccount + serviceCredential + serviceAwsAccountExternalId +} + +type serviceAccount interface { + CreateAccount(context.Context, *CreateAccountInput) (*CreateAccountOutput, error) + DeleteAccount(context.Context, *DeleteAccountInput) (*DeleteAccountOutput, error) + ReadAccount(context.Context, *ReadAccountInput) (*ReadAccountOutput, error) +} +type serviceCredential interface { + SetCredential(context.Context, *SetCredentialInput) (*SetCredentialOutput, error) + ReadCredential(context.Context, *ReadCredentialInput) (*ReadCredentialOutput, error) +} +type serviceAwsAccountExternalId interface { + CreateAWSAccountExternalId(context.Context, *CreateAWSAccountExternalIdInput) (*CreateAWSAccountExternalIdOutput, error) + ReadAWSAccountExternalId(context.Context, *ReadAWSAccountExternalIdInput) (*ReadAWSAccountExternalIdOutput, error) +} +type ServiceOp struct { + Client *client.Client +} + +func New(sess *session.Session, cfgs ...*spotinst.Config) *ServiceOp { + cfg := &spotinst.Config{} + cfg.Merge(sess.Config) + cfg.Merge(cfgs...) + + return &ServiceOp{ + Client: client.New(sess.Config), + } +} diff --git a/spotinst/client/client.go b/spotinst/client/client.go index 0c448d96..4e2db7c1 100644 --- a/spotinst/client/client.go +++ b/spotinst/client/client.go @@ -79,3 +79,15 @@ func (c *Client) logResponse(resp *http.Response) { } } } + +// Do runs a request with our client. +func (c *Client) DoOrg(ctx context.Context, r *Request) (*http.Response, error) { + req, err := r.toHTTPOrg(ctx, c.config) + if err != nil { + return nil, err + } + c.logRequest(req) + resp, err := c.config.HTTPClient.Do(req) + c.logResponse(resp) + return resp, err +} diff --git a/spotinst/client/request.go b/spotinst/client/request.go index efbe32f9..f00a68fc 100644 --- a/spotinst/client/request.go +++ b/spotinst/client/request.go @@ -74,3 +74,46 @@ func EncodeBody(obj interface{}) (io.Reader, error) { } return buf, nil } + +// toHTTP converts the request to an HTTP request. +func (r *Request) toHTTPOrg(ctx context.Context, cfg *spotinst.Config) (*http.Request, error) { + // Set the user credentials. + creds, err := cfg.Credentials.Get() + if err != nil { + return nil, err + } + if creds.Token != "" { + r.header.Set("Authorization", "Bearer "+creds.Token) + } + + // Encode the query parameters. + r.url.RawQuery = r.Params.Encode() + + // Check if we should encode the body. + if r.body == nil && r.Obj != nil { + if b, err := EncodeBody(r.Obj); err != nil { + return nil, err + } else { + r.body = b + } + } + + // Create the HTTP request. + req, err := http.NewRequest(r.method, r.url.RequestURI(), r.body) + if err != nil { + return nil, err + } + + // Set request base URL. + req.URL.Host = cfg.BaseURL.Host + req.URL.Scheme = cfg.BaseURL.Scheme + + // Set request headers. + req.Host = cfg.BaseURL.Host + req.Header = r.header + req.Header.Set("Content-Type", cfg.ContentType) + req.Header.Add("Accept", cfg.ContentType) + req.Header.Add("User-Agent", cfg.UserAgent) + + return req.WithContext(ctx), nil +} From ff65cb35bf81edc2be31c6dce18c2c602baf6fef Mon Sep 17 00:00:00 2001 From: Anurag Sharma Date: Wed, 27 Sep 2023 14:51:27 +0530 Subject: [PATCH 2/4] chore(release): v1.175.0 --- spotinst/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spotinst/version.go b/spotinst/version.go index eb8f82c8..df1d2337 100644 --- a/spotinst/version.go +++ b/spotinst/version.go @@ -1,7 +1,7 @@ package spotinst // SDKVersion is the current version of the SDK. -const SDKVersion = "1.174.0" +const SDKVersion = "1.175.0" // SDKName is the name of the SDK. const SDKName = "spotinst-sdk-go" From 147bbfb810cce7c5a3231e66ff4a5deda65eed9a Mon Sep 17 00:00:00 2001 From: pripatra <106669742+pripatra@users.noreply.github.com> Date: Wed, 27 Sep 2023 14:57:04 +0530 Subject: [PATCH 3/4] added sdk support userGroupUserMapping and userGroupPolicyMapping (#263) --- .../policy/create/main.go | 12 +- .../policy/delete/main.go | 6 +- .../policy/list/main.go | 6 +- .../policy/read/main.go | 6 +- .../policy/update/main.go | 8 +- .../user/create/main.go | 6 +- .../user/createProg/main.go | 10 +- .../user/delete/main.go | 6 +- .../user/list/main.go | 6 +- .../user/read/main.go | 6 +- .../user/updatePolicyMapping/main.go | 52 +++++++ .../user/updateUserGroupMapping/main.go | 41 ++++++ .../userGroup/create/main.go | 8 +- .../userGroup/delete/main.go | 6 +- .../userGroup/list/main.go | 6 +- .../userGroup/read/main.go | 6 +- .../userGroup/update/main.go | 6 +- .../userGroup/updatePolicyMapping/main.go | 64 +++++++++ .../userGroup/updateUserMapping/main.go | 41 ++++++ .../policy.go | 12 +- .../service.go | 7 +- .../{administration => organization}/user.go | 129 ++++++++++++++++-- .../userGroup.go | 70 ++++++++-- 23 files changed, 439 insertions(+), 81 deletions(-) rename examples/service/{administration => organization}/policy/create/main.go (83%) rename examples/service/{administration => organization}/policy/delete/main.go (85%) rename examples/service/{administration => organization}/policy/list/main.go (87%) rename examples/service/{administration => organization}/policy/read/main.go (87%) rename examples/service/{administration => organization}/policy/update/main.go (85%) rename examples/service/{administration => organization}/user/create/main.go (89%) rename examples/service/{administration => organization}/user/createProg/main.go (85%) rename examples/service/{administration => organization}/user/delete/main.go (85%) rename examples/service/{administration => organization}/user/list/main.go (87%) rename examples/service/{administration => organization}/user/read/main.go (87%) create mode 100644 examples/service/organization/user/updatePolicyMapping/main.go create mode 100644 examples/service/organization/user/updateUserGroupMapping/main.go rename examples/service/{administration => organization}/userGroup/create/main.go (86%) rename examples/service/{administration => organization}/userGroup/delete/main.go (84%) rename examples/service/{administration => organization}/userGroup/list/main.go (87%) rename examples/service/{administration => organization}/userGroup/read/main.go (87%) rename examples/service/{administration => organization}/userGroup/update/main.go (86%) create mode 100644 examples/service/organization/userGroup/updatePolicyMapping/main.go create mode 100644 examples/service/organization/userGroup/updateUserMapping/main.go rename service/{administration => organization}/policy.go (96%) rename service/{administration => organization}/service.go (83%) rename service/{administration => organization}/user.go (77%) rename service/{administration => organization}/userGroup.go (80%) diff --git a/examples/service/administration/policy/create/main.go b/examples/service/organization/policy/create/main.go similarity index 83% rename from examples/service/administration/policy/create/main.go rename to examples/service/organization/policy/create/main.go index fc8167b2..642fb27b 100644 --- a/examples/service/administration/policy/create/main.go +++ b/examples/service/organization/policy/create/main.go @@ -4,7 +4,7 @@ import ( "context" "log" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "github.com/spotinst/spotinst-sdk-go/spotinst" "github.com/spotinst/spotinst-sdk-go/spotinst/session" "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" @@ -22,18 +22,18 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Create a new group. - out, err := svc.CreatePolicy(ctx, &administration.CreatePolicyInput{ - Policy: &administration.Policy{ + out, err := svc.CreatePolicy(ctx, &organization.CreatePolicyInput{ + Policy: &organization.Policy{ Description: spotinst.String("Automation Policy by Terraform"), Name: spotinst.String("AutomationPolicy"), - PolicyContent: &administration.PolicyContent{ - Statements: []*administration.Statement{ + PolicyContent: &organization.PolicyContent{ + Statements: []*organization.Statement{ { Actions: []string{ "ocean:deleteCluster", diff --git a/examples/service/administration/policy/delete/main.go b/examples/service/organization/policy/delete/main.go similarity index 85% rename from examples/service/administration/policy/delete/main.go rename to examples/service/organization/policy/delete/main.go index 0d6c9c0c..306199be 100644 --- a/examples/service/administration/policy/delete/main.go +++ b/examples/service/organization/policy/delete/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -21,13 +21,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Delete an existing group. - _, err := svc.DeletePolicy(ctx, &administration.DeletePolicyInput{ + _, err := svc.DeletePolicy(ctx, &organization.DeletePolicyInput{ PolicyID: spotinst.String("pol-abcd1234"), }) if err != nil { diff --git a/examples/service/administration/policy/list/main.go b/examples/service/organization/policy/list/main.go similarity index 87% rename from examples/service/administration/policy/list/main.go rename to examples/service/organization/policy/list/main.go index 0580e048..fa0d902e 100644 --- a/examples/service/administration/policy/list/main.go +++ b/examples/service/organization/policy/list/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -22,13 +22,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // List all groups. - out, err := svc.ListPolicies(ctx, &administration.ListPoliciesInput{}) + out, err := svc.ListPolicies(ctx, &organization.ListPoliciesInput{}) if err != nil { log.Fatalf("spotinst: failed to list users: %v", err) } diff --git a/examples/service/administration/policy/read/main.go b/examples/service/organization/policy/read/main.go similarity index 87% rename from examples/service/administration/policy/read/main.go rename to examples/service/organization/policy/read/main.go index 39635d6e..fcae17ae 100644 --- a/examples/service/administration/policy/read/main.go +++ b/examples/service/organization/policy/read/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -22,13 +22,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Read group configuration. - out, err := svc.ReadPolicy(ctx, &administration.ReadPolicyInput{ + out, err := svc.ReadPolicy(ctx, &organization.ReadPolicyInput{ PolicyID: spotinst.String("pol-abcd1234"), }) if err != nil { diff --git a/examples/service/administration/policy/update/main.go b/examples/service/organization/policy/update/main.go similarity index 85% rename from examples/service/administration/policy/update/main.go rename to examples/service/organization/policy/update/main.go index 426c6f62..de97098e 100644 --- a/examples/service/administration/policy/update/main.go +++ b/examples/service/organization/policy/update/main.go @@ -4,7 +4,7 @@ import ( "context" "log" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "github.com/spotinst/spotinst-sdk-go/spotinst" "github.com/spotinst/spotinst-sdk-go/spotinst/session" "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" @@ -22,14 +22,14 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Create a new group. - out, err := svc.UpdatePolicy(ctx, &administration.UpdatePolicyInput{ - Policy: &administration.Policy{ + out, err := svc.UpdatePolicy(ctx, &organization.UpdatePolicyInput{ + Policy: &organization.Policy{ PolicyID: spotinst.String("pol-abcd1234"), Name: spotinst.String("Automation-Policy-Updated"), }, diff --git a/examples/service/administration/user/create/main.go b/examples/service/organization/user/create/main.go similarity index 89% rename from examples/service/administration/user/create/main.go rename to examples/service/organization/user/create/main.go index 35df2938..da05e6a1 100644 --- a/examples/service/administration/user/create/main.go +++ b/examples/service/organization/user/create/main.go @@ -4,7 +4,7 @@ import ( "context" "log" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "github.com/spotinst/spotinst-sdk-go/spotinst" "github.com/spotinst/spotinst-sdk-go/spotinst/session" "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" @@ -22,13 +22,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Create a new group. - out, err := svc.CreateUser(ctx, &administration.User{ + out, err := svc.CreateUser(ctx, &organization.User{ Email: spotinst.String("testautomation@netapp.com"), FirstName: spotinst.String("test"), LastName: spotinst.String("user"), diff --git a/examples/service/administration/user/createProg/main.go b/examples/service/organization/user/createProg/main.go similarity index 85% rename from examples/service/administration/user/createProg/main.go rename to examples/service/organization/user/createProg/main.go index e7c6f7ec..402eaddf 100644 --- a/examples/service/administration/user/createProg/main.go +++ b/examples/service/organization/user/createProg/main.go @@ -4,7 +4,7 @@ import ( "context" "log" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "github.com/spotinst/spotinst-sdk-go/spotinst" "github.com/spotinst/spotinst-sdk-go/spotinst/session" "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" @@ -22,22 +22,22 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Create a new group. - out, err := svc.CreateProgUser(ctx, &administration.ProgrammaticUser{ + out, err := svc.CreateProgUser(ctx, &organization.ProgrammaticUser{ Name: spotinst.String("test-programmatic-user"), Description: spotinst.String("description"), - Accounts: []*administration.Account{ + Accounts: []*organization.Account{ { Id: spotinst.String("act-a1b2c3d4"), Role: spotinst.String("viewer"), }, }, //Accounts and Policies are exclusive - /*Policies: []*administration.ProgPolicy{ + /*Policies: []*organization.ProgPolicy{ { PolicyId: spotinst.String("pol-abcd1234"), AccountIds: []string{ diff --git a/examples/service/administration/user/delete/main.go b/examples/service/organization/user/delete/main.go similarity index 85% rename from examples/service/administration/user/delete/main.go rename to examples/service/organization/user/delete/main.go index 596a17c7..47ca0f8d 100644 --- a/examples/service/administration/user/delete/main.go +++ b/examples/service/organization/user/delete/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -21,13 +21,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Delete an existing group. - _, err := svc.DeleteUser(ctx, &administration.DeleteUserInput{ + _, err := svc.DeleteUser(ctx, &organization.DeleteUserInput{ UserID: spotinst.String("pu-abcd1234"), }) if err != nil { diff --git a/examples/service/administration/user/list/main.go b/examples/service/organization/user/list/main.go similarity index 87% rename from examples/service/administration/user/list/main.go rename to examples/service/organization/user/list/main.go index 8ceac63f..1ad70e3b 100644 --- a/examples/service/administration/user/list/main.go +++ b/examples/service/organization/user/list/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -22,13 +22,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // List all groups. - out, err := svc.ListUsers(ctx, &administration.ListUsersInput{}) + out, err := svc.ListUsers(ctx, &organization.ListUsersInput{}) if err != nil { log.Fatalf("spotinst: failed to list users: %v", err) } diff --git a/examples/service/administration/user/read/main.go b/examples/service/organization/user/read/main.go similarity index 87% rename from examples/service/administration/user/read/main.go rename to examples/service/organization/user/read/main.go index 4fca9e96..c5c8afa1 100644 --- a/examples/service/administration/user/read/main.go +++ b/examples/service/organization/user/read/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -22,13 +22,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Read group configuration. - out, err := svc.ReadUser(ctx, &administration.ReadUserInput{ + out, err := svc.ReadUser(ctx, &organization.ReadUserInput{ UserID: spotinst.String("u-abcd1234"), }) if err != nil { diff --git a/examples/service/organization/user/updatePolicyMapping/main.go b/examples/service/organization/user/updatePolicyMapping/main.go new file mode 100644 index 00000000..2e143594 --- /dev/null +++ b/examples/service/organization/user/updatePolicyMapping/main.go @@ -0,0 +1,52 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/organization" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +func main() { + // All clients require a Session. The Session provides the client with + // shared configuration such as account and credentials. + // A Session should be shared where possible to take advantage of + // configuration and credential caching. See the session package for + // more information. + sess := session.New() + + // Create a new instance of the service's client with a Session. + // Optional spotinst.Config values can also be provided as variadic + // arguments to the New function. This option allows you to provide + // service specific configuration. + svc := organization.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + err := svc.UpdatePolicyMappingOfUser(ctx, &organization.UpdatePolicyMappingOfUserInput{ + UserID: spotinst.String("u-0628514b"), + Policies: []*organization.UserPolicy{ + &organization.UserPolicy{ + PolicyId: spotinst.String("pol-abcd1234"), + AccountIds: []string{ + "act-1234abcd", + }, + }, + &organization.UserPolicy{ + PolicyId: spotinst.String("pol-xyzw1234"), + AccountIds: []string{ + "act-abcd1234", + }, + }, + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to update policy: %v", err) + } + +} diff --git a/examples/service/organization/user/updateUserGroupMapping/main.go b/examples/service/organization/user/updateUserGroupMapping/main.go new file mode 100644 index 00000000..1d106768 --- /dev/null +++ b/examples/service/organization/user/updateUserGroupMapping/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/organization" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +func main() { + // All clients require a Session. The Session provides the client with + // shared configuration such as account and credentials. + // A Session should be shared where possible to take advantage of + // configuration and credential caching. See the session package for + // more information. + sess := session.New() + + // Create a new instance of the service's client with a Session. + // Optional spotinst.Config values can also be provided as variadic + // arguments to the New function. This option allows you to provide + // service specific configuration. + svc := organization.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + err := svc.UpdateUserGroupMappingOfUser(ctx, &organization.UpdateUserGroupMappingOfUserInput{ + UserID: spotinst.String("u-abcd1234"), + UserGroupIds: []string{ + "ugr-abcd1234", + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to update policy: %v", err) + } + +} diff --git a/examples/service/administration/userGroup/create/main.go b/examples/service/organization/userGroup/create/main.go similarity index 86% rename from examples/service/administration/userGroup/create/main.go rename to examples/service/organization/userGroup/create/main.go index 11589d0a..696280a9 100644 --- a/examples/service/administration/userGroup/create/main.go +++ b/examples/service/organization/userGroup/create/main.go @@ -4,7 +4,7 @@ import ( "context" "log" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "github.com/spotinst/spotinst-sdk-go/spotinst" "github.com/spotinst/spotinst-sdk-go/spotinst/session" "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" @@ -22,19 +22,19 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Create a new group. - out, err := svc.CreateUserGroup(ctx, &administration.UserGroup{ + out, err := svc.CreateUserGroup(ctx, &organization.UserGroup{ Description: spotinst.String("TFUserGroup"), Name: spotinst.String("test-user-group"), UserIds: []string{ "u-abcd1234", }, - Policies: []*administration.UserGroupPolicy{ + Policies: []*organization.UserGroupPolicy{ { AccountIds: []string{ "act-abcd1234", diff --git a/examples/service/administration/userGroup/delete/main.go b/examples/service/organization/userGroup/delete/main.go similarity index 84% rename from examples/service/administration/userGroup/delete/main.go rename to examples/service/organization/userGroup/delete/main.go index cad641bd..4f151985 100644 --- a/examples/service/administration/userGroup/delete/main.go +++ b/examples/service/organization/userGroup/delete/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -21,13 +21,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Delete an existing user group. - _, err := svc.DeleteUserGroup(ctx, &administration.DeleteUserGroupInput{ + _, err := svc.DeleteUserGroup(ctx, &organization.DeleteUserGroupInput{ UserGroupID: spotinst.String("ugr-abcd1234"), }) if err != nil { diff --git a/examples/service/administration/userGroup/list/main.go b/examples/service/organization/userGroup/list/main.go similarity index 87% rename from examples/service/administration/userGroup/list/main.go rename to examples/service/organization/userGroup/list/main.go index 729d042c..b3e26bcd 100644 --- a/examples/service/administration/userGroup/list/main.go +++ b/examples/service/organization/userGroup/list/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -22,13 +22,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // List all groups. - out, err := svc.ListUserGroups(ctx, &administration.ListUserGroupsInput{}) + out, err := svc.ListUserGroups(ctx, &organization.ListUserGroupsInput{}) if err != nil { log.Fatalf("spotinst: failed to list users: %v", err) } diff --git a/examples/service/administration/userGroup/read/main.go b/examples/service/organization/userGroup/read/main.go similarity index 87% rename from examples/service/administration/userGroup/read/main.go rename to examples/service/organization/userGroup/read/main.go index 0928d8a4..61d8c084 100644 --- a/examples/service/administration/userGroup/read/main.go +++ b/examples/service/organization/userGroup/read/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "log" "github.com/spotinst/spotinst-sdk-go/spotinst" @@ -22,13 +22,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Read group configuration. - out, err := svc.ReadUserGroup(ctx, &administration.ReadUserGroupInput{ + out, err := svc.ReadUserGroup(ctx, &organization.ReadUserGroupInput{ UserGroupID: spotinst.String("ugr-abcd1234"), }) if err != nil { diff --git a/examples/service/administration/userGroup/update/main.go b/examples/service/organization/userGroup/update/main.go similarity index 86% rename from examples/service/administration/userGroup/update/main.go rename to examples/service/organization/userGroup/update/main.go index 23e362e5..d5f63203 100644 --- a/examples/service/administration/userGroup/update/main.go +++ b/examples/service/organization/userGroup/update/main.go @@ -4,7 +4,7 @@ import ( "context" "log" - "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/service/organization" "github.com/spotinst/spotinst-sdk-go/spotinst" "github.com/spotinst/spotinst-sdk-go/spotinst/session" ) @@ -21,13 +21,13 @@ func main() { // Optional spotinst.Config values can also be provided as variadic // arguments to the New function. This option allows you to provide // service specific configuration. - svc := administration.New(sess) + svc := organization.New(sess) // Create a new context. ctx := context.Background() // Create a new group. - err := svc.UpdateUserGroup(ctx, &administration.UserGroup{ + err := svc.UpdateUserGroup(ctx, &organization.UserGroup{ UserGroupId: spotinst.String("ugr-525a30dc"), Name: spotinst.String("test-user-group-updated"), }) diff --git a/examples/service/organization/userGroup/updatePolicyMapping/main.go b/examples/service/organization/userGroup/updatePolicyMapping/main.go new file mode 100644 index 00000000..b3ad11de --- /dev/null +++ b/examples/service/organization/userGroup/updatePolicyMapping/main.go @@ -0,0 +1,64 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/organization" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +func main() { + // All clients require a Session. The Session provides the client with + // shared configuration such as account and credentials. + // A Session should be shared where possible to take advantage of + // configuration and credential caching. See the session package for + // more information. + sess := session.New() + + // Create a new instance of the service's client with a Session. + // Optional spotinst.Config values can also be provided as variadic + // arguments to the New function. This option allows you to provide + // service specific configuration. + svc := organization.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + err := svc.UpdatePolicyMappingOfUserGroup(ctx, &organization.UpdatePolicyMappingOfUserGroupInput{ + UserGroupId: spotinst.String("ugr-17ae43d9"), + Policies: []*organization.UserPolicy{ + &organization.UserPolicy{ + PolicyId: spotinst.String("pol-b236db1f"), + AccountIds: []string{ + "act-abcd1234", + }, + }, + &organization.UserPolicy{ + PolicyId: spotinst.String("pol-08715c90"), + AccountIds: []string{ + "act-abcd1234", + }, + }, + &organization.UserPolicy{ + PolicyId: spotinst.String("3"), + AccountIds: []string{ + "act-abcd1234", + }, + }, + &organization.UserPolicy{ + PolicyId: spotinst.String("pol-c75d8c06"), + AccountIds: []string{ + "act-abcd1234", + }, + }, + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to update user group: %v", err) + } + +} diff --git a/examples/service/organization/userGroup/updateUserMapping/main.go b/examples/service/organization/userGroup/updateUserMapping/main.go new file mode 100644 index 00000000..f75a11ca --- /dev/null +++ b/examples/service/organization/userGroup/updateUserMapping/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/organization" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" +) + +func main() { + // All clients require a Session. The Session provides the client with + // shared configuration such as account and credentials. + // A Session should be shared where possible to take advantage of + // configuration and credential caching. See the session package for + // more information. + sess := session.New() + + // Create a new instance of the service's client with a Session. + // Optional spotinst.Config values can also be provided as variadic + // arguments to the New function. This option allows you to provide + // service specific configuration. + svc := organization.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + err := svc.UpdateUserMappingOfUserGroup(ctx, &organization.UpdateUserMappingOfUserGroupInput{ + UserGroupId: spotinst.String("ugr-abcd1234"), + UserIds: []string{ + "pu-abcd1234", + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to update user group: %v", err) + } + +} diff --git a/service/administration/policy.go b/service/organization/policy.go similarity index 96% rename from service/administration/policy.go rename to service/organization/policy.go index b07a9f6d..58a029a8 100644 --- a/service/administration/policy.go +++ b/service/organization/policy.go @@ -1,4 +1,4 @@ -package administration +package organization import ( "context" @@ -124,7 +124,7 @@ func policiesFromHttpResponse(resp *http.Response) ([]*Policy, error) { func (s *ServiceOp) ListPolicies(ctx context.Context, input *ListPoliciesInput) (*ListPoliciesOutput, error) { r := client.NewRequest(http.MethodGet, "/setup/organization/policy") - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -142,7 +142,7 @@ func (s *ServiceOp) CreatePolicy(ctx context.Context, input *CreatePolicyInput) r := client.NewRequest(http.MethodPost, "/setup/access/policy") r.Obj = input - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -164,7 +164,7 @@ func (s *ServiceOp) CreatePolicy(ctx context.Context, input *CreatePolicyInput) func (s *ServiceOp) ReadPolicy(ctx context.Context, input *ReadPolicyInput) (*ReadPolicyOutput, error) { r := client.NewRequest(http.MethodGet, "/setup/organization/policy") - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -202,7 +202,7 @@ func (s *ServiceOp) UpdatePolicy(ctx context.Context, input *UpdatePolicyInput) r := client.NewRequest(http.MethodPut, path) r.Obj = input - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -230,7 +230,7 @@ func (s *ServiceOp) DeletePolicy(ctx context.Context, input *DeletePolicyInput) } r := client.NewRequest(http.MethodDelete, path) - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } diff --git a/service/administration/service.go b/service/organization/service.go similarity index 83% rename from service/administration/service.go rename to service/organization/service.go index 496b7e17..7c580d74 100644 --- a/service/administration/service.go +++ b/service/organization/service.go @@ -1,4 +1,4 @@ -package administration +package organization import ( "context" @@ -17,7 +17,8 @@ type Service interface { CreateProgUser(context.Context, *ProgrammaticUser) (*CreateProgrammaticUserOutput, error) ReadUser(context.Context, *ReadUserInput) (*ReadUserOutput, error) ReadProgUser(context.Context, *ReadUserInput) (*ReadProgUserOutput, error) - //Update(context.Context, *UpdateUserInput) (*UpdateUserOutput, error) + UpdatePolicyMappingOfUser(context.Context, *UpdatePolicyMappingOfUserInput) error + UpdateUserGroupMappingOfUser(context.Context, *UpdateUserGroupMappingOfUserInput) error DeleteUser(context.Context, *DeleteUserInput) (*DeleteUserOutput, error) ListPolicies(context.Context, *ListPoliciesInput) (*ListPoliciesOutput, error) @@ -30,6 +31,8 @@ type Service interface { CreateUserGroup(context.Context, *UserGroup) (*CreateUserGroupOutput, error) ReadUserGroup(context.Context, *ReadUserGroupInput) (*ReadUserGroupOutput, error) UpdateUserGroup(context.Context, *UserGroup) error + UpdateUserMappingOfUserGroup(context.Context, *UpdateUserMappingOfUserGroupInput) error + UpdatePolicyMappingOfUserGroup(context.Context, *UpdatePolicyMappingOfUserGroupInput) error DeleteUserGroup(context.Context, *DeleteUserGroupInput) (*DeleteUserGroupOutput, error) } diff --git a/service/administration/user.go b/service/organization/user.go similarity index 77% rename from service/administration/user.go rename to service/organization/user.go index 3208d1e0..6589ab83 100644 --- a/service/administration/user.go +++ b/service/organization/user.go @@ -1,4 +1,4 @@ -package administration +package organization import ( "context" @@ -30,6 +30,7 @@ type User struct { Groups []*Group `json:"groups,omitempty"` DisplayName *string `json:"displayName,omitempty"` OrganizationId *int `json:"organizationId,omitempty"` + UserGroupIds []string `json:"userGroupIds,omitempty"` // forceSendFields is a list of field names (e.g. "Keys") to // unconditionally include in API requests. By default, fields with @@ -59,12 +60,13 @@ type UserPolicy struct { } type ProgrammaticUser struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Policies []*ProgPolicy `json:"policies,omitempty"` - Accounts []*Account `json:"accounts,omitempty"` - Token *string `json:"token,omitempty"` - ProgUserId *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Policies []*ProgPolicy `json:"policies,omitempty"` + Accounts []*Account `json:"accounts,omitempty"` + Token *string `json:"token,omitempty"` + ProgUserId *string `json:"id,omitempty"` + UserGroupIds []string `json:"userGroupIds,omitempty"` forceSendFields []string nullFields []string @@ -209,7 +211,7 @@ func progUsersFromHttpResponse(resp *http.Response) ([]*ProgrammaticUser, error) func (s *ServiceOp) ListUsers(ctx context.Context, input *ListUsersInput) (*ListUsersOutput, error) { r := client.NewRequest(http.MethodGet, "/setup/organization/user") - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -229,7 +231,7 @@ func (s *ServiceOp) CreateUser(ctx context.Context, input *User, generateToken * r.Params.Set("generateToken", genToken) r.Obj = input - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -252,7 +254,7 @@ func (s *ServiceOp) CreateProgUser(ctx context.Context, input *ProgrammaticUser) r := client.NewRequest(http.MethodPost, "/setup/user/programmatic") r.Obj = input - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -280,7 +282,7 @@ func (s *ServiceOp) ReadUser(ctx context.Context, input *ReadUserInput) (*ReadUs } r := client.NewRequest(http.MethodGet, path) - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -308,7 +310,7 @@ func (s *ServiceOp) ReadProgUser(ctx context.Context, input *ReadUserInput) (*Re } r := client.NewRequest(http.MethodGet, path) - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -327,6 +329,64 @@ func (s *ServiceOp) ReadProgUser(ctx context.Context, input *ReadUserInput) (*Re return output, nil } +type UpdatePolicyMappingOfUserInput struct { + UserID *string `json:"userId,omitempty"` + Policies []*UserPolicy `json:"policies,omitempty"` +} + +func (s *ServiceOp) UpdatePolicyMappingOfUser(ctx context.Context, input *UpdatePolicyMappingOfUserInput) error { + path, err := uritemplates.Expand("/setup/user/{userId}/policyMapping", uritemplates.Values{ + "userId": spotinst.StringValue(input.UserID), + }) + + if err != nil { + return err + } + + // We do not need the ID anymore so let's drop it. + input.UserID = nil + + r := client.NewRequest(http.MethodPut, path) + r.Obj = input + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +type UpdateUserGroupMappingOfUserInput struct { + UserID *string `json:"userId,omitempty"` + UserGroupIds []string `json:"userGroupIds,omitempty"` +} + +func (s *ServiceOp) UpdateUserGroupMappingOfUser(ctx context.Context, input *UpdateUserGroupMappingOfUserInput) error { + path, err := uritemplates.Expand("/setup/user/{userId}/userGroupMapping", uritemplates.Values{ + "userId": spotinst.StringValue(input.UserID), + }) + + if err != nil { + return err + } + + // We do not need the ID anymore so let's drop it. + input.UserID = nil + + r := client.NewRequest(http.MethodPut, path) + r.Obj = input + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + func (s *ServiceOp) DeleteUser(ctx context.Context, input *DeleteUserInput) (*DeleteUserOutput, error) { path, err := uritemplates.Expand("/setup/user/{userId}", uritemplates.Values{ "userId": spotinst.StringValue(input.UserID), @@ -336,7 +396,7 @@ func (s *ServiceOp) DeleteUser(ctx context.Context, input *DeleteUserInput) (*De } r := client.NewRequest(http.MethodDelete, path) - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -388,6 +448,13 @@ func (o *User) SetRole(v *string) *User { return o } +func (o *User) SetUserGroupIds(v []string) *User { + if o.UserGroupIds = v; o.UserGroupIds == nil { + o.nullFields = append(o.nullFields, "UserGroupIds") + } + return o +} + // endregion // region ProgrammaticUser @@ -419,6 +486,13 @@ func (o *ProgrammaticUser) SetPolicies(v []*ProgPolicy) *ProgrammaticUser { return o } +func (o *User) SetUserPolicies(v []*UserPolicy) *User { + if o.Policies = v; o.Policies == nil { + o.nullFields = append(o.nullFields, "Policies") + } + return o +} + func (o *ProgrammaticUser) SetAccounts(v []*Account) *ProgrammaticUser { if o.Accounts = v; o.Accounts == nil { o.nullFields = append(o.nullFields, "Accounts") @@ -426,6 +500,13 @@ func (o *ProgrammaticUser) SetAccounts(v []*Account) *ProgrammaticUser { return o } +func (o *ProgrammaticUser) SetProgUserGroupIds(v []string) *ProgrammaticUser { + if o.UserGroupIds = v; o.UserGroupIds == nil { + o.nullFields = append(o.nullFields, "UserGroupIds") + } + return o +} + // endregion func (o ProgPolicy) MarshalJSON() ([]byte, error) { @@ -450,6 +531,28 @@ func (o *ProgPolicy) SetPolicyId(v *string) *ProgPolicy { //end region +func (o UserPolicy) MarshalJSON() ([]byte, error) { + type noMethod UserPolicy + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *UserPolicy) SetUserPolicyAccountIds(v []string) *UserPolicy { + if o.AccountIds = v; o.AccountIds == nil { + o.nullFields = append(o.nullFields, "AccountIds") + } + return o +} + +func (o *UserPolicy) SetUserPolicyId(v *string) *UserPolicy { + if o.PolicyId = v; o.PolicyId == nil { + o.nullFields = append(o.nullFields, "PolicyId") + } + return o +} + +//end region + func (o Account) MarshalJSON() ([]byte, error) { type noMethod Account raw := noMethod(o) diff --git a/service/administration/userGroup.go b/service/organization/userGroup.go similarity index 80% rename from service/administration/userGroup.go rename to service/organization/userGroup.go index 4a2752cb..ed06cb91 100644 --- a/service/administration/userGroup.go +++ b/service/organization/userGroup.go @@ -1,4 +1,4 @@ -package administration +package organization import ( "context" @@ -124,7 +124,7 @@ func userGroupsFromHttpResponse(resp *http.Response) ([]*UserGroup, error) { func (s *ServiceOp) ListUserGroups(ctx context.Context, input *ListUserGroupsInput) (*ListUserGroupsOutput, error) { r := client.NewRequest(http.MethodGet, "/setup/access/userGroup") - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -142,7 +142,7 @@ func (s *ServiceOp) CreateUserGroup(ctx context.Context, input *UserGroup) (*Cre r := client.NewRequest(http.MethodPost, "/setup/access/userGroup") r.Obj = input - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func (s *ServiceOp) ReadUserGroup(ctx context.Context, input *ReadUserGroupInput } r := client.NewRequest(http.MethodGet, path) - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -203,7 +203,63 @@ func (s *ServiceOp) UpdateUserGroup(ctx context.Context, input *UserGroup) error r := client.NewRequest(http.MethodPut, path) r.Obj = input - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +type UpdateUserMappingOfUserGroupInput struct { + UserGroupId *string `json:"userGroupId,omitempty"` + UserIds []string `json:"userIds,omitempty"` +} + +func (s *ServiceOp) UpdateUserMappingOfUserGroup(ctx context.Context, input *UpdateUserMappingOfUserGroupInput) error { + path, err := uritemplates.Expand("/setup/access/userGroup/{userGroupId}/userMapping", uritemplates.Values{ + "userGroupId": spotinst.StringValue(input.UserGroupId), + }) + if err != nil { + return err + } + + // We do not need the ID anymore so let's drop it. + input.UserGroupId = nil + + r := client.NewRequest(http.MethodPut, path) + r.Obj = input + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +type UpdatePolicyMappingOfUserGroupInput struct { + UserGroupId *string `json:"userGroupId,omitempty"` + Policies []*UserPolicy `json:"policies,omitempty"` +} + +func (s *ServiceOp) UpdatePolicyMappingOfUserGroup(ctx context.Context, input *UpdatePolicyMappingOfUserGroupInput) error { + path, err := uritemplates.Expand("/setup/access/userGroup/{userGroupId}/policyMapping", uritemplates.Values{ + "userGroupId": spotinst.StringValue(input.UserGroupId), + }) + if err != nil { + return err + } + + // We do not need the ID anymore so let's drop it. + input.UserGroupId = nil + + r := client.NewRequest(http.MethodPut, path) + r.Obj = input + + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return err } @@ -221,7 +277,7 @@ func (s *ServiceOp) DeleteUserGroup(ctx context.Context, input *DeleteUserGroupI } r := client.NewRequest(http.MethodDelete, path) - resp, err := client.RequireOK(s.Client.Do(ctx, r)) + resp, err := client.RequireOK(s.Client.DoOrg(ctx, r)) if err != nil { return nil, err } @@ -230,8 +286,6 @@ func (s *ServiceOp) DeleteUserGroup(ctx context.Context, input *DeleteUserGroupI return &DeleteUserGroupOutput{}, nil } -// region User - func (o UserGroup) MarshalJSON() ([]byte, error) { type noMethod UserGroup raw := noMethod(o) From bef56d42addbf259e29a1581f217076d837f0cf4 Mon Sep 17 00:00:00 2001 From: Anurag Sharma Date: Wed, 27 Sep 2023 14:58:29 +0530 Subject: [PATCH 4/4] chore(release): v1.176.0 --- spotinst/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spotinst/version.go b/spotinst/version.go index df1d2337..7aa11021 100644 --- a/spotinst/version.go +++ b/spotinst/version.go @@ -1,7 +1,7 @@ package spotinst // SDKVersion is the current version of the SDK. -const SDKVersion = "1.175.0" +const SDKVersion = "1.176.0" // SDKName is the name of the SDK. const SDKName = "spotinst-sdk-go"