From 477b163c35aa70a9d16655f59407542acefcaa07 Mon Sep 17 00:00:00 2001 From: pripatra <106669742+pripatra@users.noreply.github.com> Date: Fri, 18 Aug 2023 22:47:31 +0530 Subject: [PATCH] feat(accounts/userManagement): Added support for userManagement apis (#258) --- .../administration/policy/create/main.go | 62 +++ .../administration/policy/delete/main.go | 36 ++ .../administration/policy/list/main.go | 44 ++ .../administration/policy/read/main.go | 44 ++ .../administration/policy/update/main.go | 48 ++ .../administration/user/create/main.go | 49 ++ .../administration/user/createProg/main.go | 60 +++ .../administration/user/delete/main.go | 36 ++ .../service/administration/user/list/main.go | 44 ++ .../service/administration/user/read/main.go | 44 ++ .../administration/userGroup/create/main.go | 57 +++ .../administration/userGroup/delete/main.go | 36 ++ .../administration/userGroup/list/main.go | 44 ++ .../administration/userGroup/read/main.go | 44 ++ .../administration/userGroup/update/main.go | 39 ++ service/administration/policy.go | 315 ++++++++++++ service/administration/service.go | 50 ++ service/administration/user.go | 471 ++++++++++++++++++ service/administration/userGroup.go | 291 +++++++++++ 19 files changed, 1814 insertions(+) create mode 100644 examples/service/administration/policy/create/main.go create mode 100644 examples/service/administration/policy/delete/main.go create mode 100644 examples/service/administration/policy/list/main.go create mode 100644 examples/service/administration/policy/read/main.go create mode 100644 examples/service/administration/policy/update/main.go create mode 100644 examples/service/administration/user/create/main.go create mode 100644 examples/service/administration/user/createProg/main.go create mode 100644 examples/service/administration/user/delete/main.go create mode 100644 examples/service/administration/user/list/main.go create mode 100644 examples/service/administration/user/read/main.go create mode 100644 examples/service/administration/userGroup/create/main.go create mode 100644 examples/service/administration/userGroup/delete/main.go create mode 100644 examples/service/administration/userGroup/list/main.go create mode 100644 examples/service/administration/userGroup/read/main.go create mode 100644 examples/service/administration/userGroup/update/main.go create mode 100644 service/administration/policy.go create mode 100644 service/administration/service.go create mode 100644 service/administration/user.go create mode 100644 service/administration/userGroup.go diff --git a/examples/service/administration/policy/create/main.go b/examples/service/administration/policy/create/main.go new file mode 100644 index 00000000..fc8167b2 --- /dev/null +++ b/examples/service/administration/policy/create/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + out, err := svc.CreatePolicy(ctx, &administration.CreatePolicyInput{ + Policy: &administration.Policy{ + Description: spotinst.String("Automation Policy by Terraform"), + Name: spotinst.String("AutomationPolicy"), + PolicyContent: &administration.PolicyContent{ + Statements: []*administration.Statement{ + { + Actions: []string{ + "ocean:deleteCluster", + "ocean:updateCluster", + }, + Effect: spotinst.String("ALLOW"), + Resources: []string{ + "*", + }, + }, + }, + }, + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to create policy: %v", err) + } + + // Output. + if out.Policy != nil { + log.Printf("Policy %q: %s", + spotinst.StringValue(out.Policy.PolicyID), + stringutil.Stringify(out.Policy)) + } +} diff --git a/examples/service/administration/policy/delete/main.go b/examples/service/administration/policy/delete/main.go new file mode 100644 index 00000000..0d6c9c0c --- /dev/null +++ b/examples/service/administration/policy/delete/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Delete an existing group. + _, err := svc.DeletePolicy(ctx, &administration.DeletePolicyInput{ + PolicyID: spotinst.String("pol-abcd1234"), + }) + if err != nil { + log.Fatalf("spotinst: failed to delete policy: %v", err) + } +} diff --git a/examples/service/administration/policy/list/main.go b/examples/service/administration/policy/list/main.go new file mode 100644 index 00000000..0580e048 --- /dev/null +++ b/examples/service/administration/policy/list/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // List all groups. + out, err := svc.ListPolicies(ctx, &administration.ListPoliciesInput{}) + if err != nil { + log.Fatalf("spotinst: failed to list users: %v", err) + } + + // Output all groups, if any. + if len(out.Policies) > 0 { + for _, Policy := range out.Policies { + log.Printf("Policy %q: %s", + spotinst.StringValue(Policy.PolicyID), + stringutil.Stringify(Policy)) + } + } +} diff --git a/examples/service/administration/policy/read/main.go b/examples/service/administration/policy/read/main.go new file mode 100644 index 00000000..39635d6e --- /dev/null +++ b/examples/service/administration/policy/read/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Read group configuration. + out, err := svc.ReadPolicy(ctx, &administration.ReadPolicyInput{ + PolicyID: spotinst.String("pol-abcd1234"), + }) + if err != nil { + log.Fatalf("spotinst: failed to read policy: %v", err) + } + + // Output. + if out.Policy != nil { + log.Printf("User %q: %s", + spotinst.StringValue(out.Policy.PolicyID), + stringutil.Stringify(out.Policy)) + } +} diff --git a/examples/service/administration/policy/update/main.go b/examples/service/administration/policy/update/main.go new file mode 100644 index 00000000..426c6f62 --- /dev/null +++ b/examples/service/administration/policy/update/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + out, err := svc.UpdatePolicy(ctx, &administration.UpdatePolicyInput{ + Policy: &administration.Policy{ + PolicyID: spotinst.String("pol-abcd1234"), + Name: spotinst.String("Automation-Policy-Updated"), + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to update policy: %v", err) + } + + // Output. + if out.Policy != nil { + log.Printf("Policy %q: %s", + spotinst.StringValue(out.Policy.PolicyID), + stringutil.Stringify(out.Policy)) + } +} diff --git a/examples/service/administration/user/create/main.go b/examples/service/administration/user/create/main.go new file mode 100644 index 00000000..35df2938 --- /dev/null +++ b/examples/service/administration/user/create/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + out, err := svc.CreateUser(ctx, &administration.User{ + Email: spotinst.String("testautomation@netapp.com"), + FirstName: spotinst.String("test"), + LastName: spotinst.String("user"), + Password: spotinst.String("testUser@123"), + Role: spotinst.String("viewer"), + }, spotinst.Bool(true)) + + if err != nil { + log.Fatalf("spotinst: failed to create user: %v", err) + } + + // Output. + if out.User != nil { + log.Printf("User %q: %s", + spotinst.StringValue(out.User.UserID), + stringutil.Stringify(out.User)) + } +} diff --git a/examples/service/administration/user/createProg/main.go b/examples/service/administration/user/createProg/main.go new file mode 100644 index 00000000..e7c6f7ec --- /dev/null +++ b/examples/service/administration/user/createProg/main.go @@ -0,0 +1,60 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + out, err := svc.CreateProgUser(ctx, &administration.ProgrammaticUser{ + Name: spotinst.String("test-programmatic-user"), + Description: spotinst.String("description"), + Accounts: []*administration.Account{ + { + Id: spotinst.String("act-a1b2c3d4"), + Role: spotinst.String("viewer"), + }, + }, //Accounts and Policies are exclusive + /*Policies: []*administration.ProgPolicy{ + { + PolicyId: spotinst.String("pol-abcd1234"), + AccountIds: []string{ + "act-a1b2c3d4", + }, + }, + },*/ + }) + + if err != nil { + log.Fatalf("spotinst: failed to create user: %v", err) + } + + // Output. + if out.ProgrammaticUser != nil { + log.Printf("User %q: %s", + spotinst.StringValue(out.ProgrammaticUser.ProgUserId), + stringutil.Stringify(out.ProgrammaticUser)) + } +} diff --git a/examples/service/administration/user/delete/main.go b/examples/service/administration/user/delete/main.go new file mode 100644 index 00000000..596a17c7 --- /dev/null +++ b/examples/service/administration/user/delete/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Delete an existing group. + _, err := svc.DeleteUser(ctx, &administration.DeleteUserInput{ + UserID: spotinst.String("pu-abcd1234"), + }) + if err != nil { + log.Fatalf("spotinst: failed to delete user: %v", err) + } +} diff --git a/examples/service/administration/user/list/main.go b/examples/service/administration/user/list/main.go new file mode 100644 index 00000000..8ceac63f --- /dev/null +++ b/examples/service/administration/user/list/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // List all groups. + out, err := svc.ListUsers(ctx, &administration.ListUsersInput{}) + if err != nil { + log.Fatalf("spotinst: failed to list users: %v", err) + } + + // Output all groups, if any. + if len(out.Users) > 0 { + for _, User := range out.Users { + log.Printf("User %q: %s", + spotinst.StringValue(User.UserID), + stringutil.Stringify(User)) + } + } +} diff --git a/examples/service/administration/user/read/main.go b/examples/service/administration/user/read/main.go new file mode 100644 index 00000000..4fca9e96 --- /dev/null +++ b/examples/service/administration/user/read/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Read group configuration. + out, err := svc.ReadUser(ctx, &administration.ReadUserInput{ + UserID: spotinst.String("u-abcd1234"), + }) + if err != nil { + log.Fatalf("spotinst: failed to read group: %v", err) + } + + // Output. + if out.User != nil { + log.Printf("User %q: %s", + spotinst.StringValue(out.User.UserID), + stringutil.Stringify(out.User)) + } +} diff --git a/examples/service/administration/userGroup/create/main.go b/examples/service/administration/userGroup/create/main.go new file mode 100644 index 00000000..11589d0a --- /dev/null +++ b/examples/service/administration/userGroup/create/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/administration" + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + out, err := svc.CreateUserGroup(ctx, &administration.UserGroup{ + Description: spotinst.String("TFUserGroup"), + Name: spotinst.String("test-user-group"), + UserIds: []string{ + "u-abcd1234", + }, + Policies: []*administration.UserGroupPolicy{ + { + AccountIds: []string{ + "act-abcd1234", + }, + PolicyId: spotinst.String("pol-abcd1234"), + }, + }, + }) + + if err != nil { + log.Fatalf("spotinst: failed to create user group: %v", err) + } + + // Output. + if out.UserGroup != nil { + log.Printf("UserGroup %q: %s", + spotinst.StringValue(out.UserGroup.UserGroupId), + stringutil.Stringify(out.UserGroup)) + } +} diff --git a/examples/service/administration/userGroup/delete/main.go b/examples/service/administration/userGroup/delete/main.go new file mode 100644 index 00000000..cad641bd --- /dev/null +++ b/examples/service/administration/userGroup/delete/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Delete an existing user group. + _, err := svc.DeleteUserGroup(ctx, &administration.DeleteUserGroupInput{ + UserGroupID: spotinst.String("ugr-abcd1234"), + }) + if err != nil { + log.Fatalf("spotinst: failed to delete user group: %v", err) + } +} diff --git a/examples/service/administration/userGroup/list/main.go b/examples/service/administration/userGroup/list/main.go new file mode 100644 index 00000000..729d042c --- /dev/null +++ b/examples/service/administration/userGroup/list/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // List all groups. + out, err := svc.ListUserGroups(ctx, &administration.ListUserGroupsInput{}) + if err != nil { + log.Fatalf("spotinst: failed to list users: %v", err) + } + + // Output all groups, if any. + if len(out.UserGroups) > 0 { + for _, UserGroup := range out.UserGroups { + log.Printf("UserGroup %q: %s", + spotinst.StringValue(UserGroup.UserGroupId), + stringutil.Stringify(UserGroup)) + } + } +} diff --git a/examples/service/administration/userGroup/read/main.go b/examples/service/administration/userGroup/read/main.go new file mode 100644 index 00000000..0928d8a4 --- /dev/null +++ b/examples/service/administration/userGroup/read/main.go @@ -0,0 +1,44 @@ +package main + +import ( + "context" + "github.com/spotinst/spotinst-sdk-go/service/administration" + "log" + + "github.com/spotinst/spotinst-sdk-go/spotinst" + "github.com/spotinst/spotinst-sdk-go/spotinst/session" + "github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil" +) + +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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Read group configuration. + out, err := svc.ReadUserGroup(ctx, &administration.ReadUserGroupInput{ + UserGroupID: spotinst.String("ugr-abcd1234"), + }) + if err != nil { + log.Fatalf("spotinst: failed to read user group: %v", err) + } + + // Output. + if out.UserGroup != nil { + log.Printf("UserGroup %q: %s", + spotinst.StringValue(out.UserGroup.UserGroupId), + stringutil.Stringify(out.UserGroup)) + } +} diff --git a/examples/service/administration/userGroup/update/main.go b/examples/service/administration/userGroup/update/main.go new file mode 100644 index 00000000..23e362e5 --- /dev/null +++ b/examples/service/administration/userGroup/update/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "context" + "log" + + "github.com/spotinst/spotinst-sdk-go/service/administration" + "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 := administration.New(sess) + + // Create a new context. + ctx := context.Background() + + // Create a new group. + err := svc.UpdateUserGroup(ctx, &administration.UserGroup{ + UserGroupId: spotinst.String("ugr-525a30dc"), + Name: spotinst.String("test-user-group-updated"), + }) + + if err != nil { + log.Fatalf("spotinst: failed to update user group: %v", err) + } + +} diff --git a/service/administration/policy.go b/service/administration/policy.go new file mode 100644 index 00000000..b07a9f6d --- /dev/null +++ b/service/administration/policy.go @@ -0,0 +1,315 @@ +package administration + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + + "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" +) + +type Policy struct { + Description *string `json:"description,omitempty"` + Name *string `json:"name,omitempty"` + PolicyContent *PolicyContent `json:"policyContent,omitempty"` + PolicyID *string `json:"id,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 +} + +type PolicyContent struct { + Statements []*Statement `json:"statements,omitempty"` + + forceSendFields []string + nullFields []string +} + +type Statement struct { + Actions []string `json:"actions,omitempty"` + Effect *string `json:"effect,omitempty"` + Resources []string `json:"resources,omitempty"` + + forceSendFields []string + nullFields []string +} + +type ListPoliciesInput struct{} + +type ListPoliciesOutput struct { + Policies []*Policy `json:"policies,omitempty"` +} + +type CreatePolicyInput struct { + Policy *Policy `json:"policy,omitempty"` +} + +type CreatePolicyOutput struct { + Policy *Policy `json:"policy,omitempty"` +} + +type ReadPolicyInput struct { + PolicyID *string `json:"policyId,omitempty"` +} + +type ReadPolicyOutput struct { + Policy *Policy `json:"policy,omitempty"` +} + +type UpdatePolicyInput struct { + Policy *Policy `json:"policy,omitempty"` +} + +type UpdatePolicyOutput struct { + Policy *Policy `json:"policy,omitempty"` +} + +type DeletePolicyInput struct { + PolicyID *string `json:"id,omitempty"` +} + +type DeletePolicyOutput struct{} + +func policyFromJSON(in []byte) (*Policy, error) { + b := new(Policy) + if err := json.Unmarshal(in, b); err != nil { + return nil, err + } + return b, nil +} + +func policiesFromJSON(in []byte) ([]*Policy, error) { + var rw client.Response + if err := json.Unmarshal(in, &rw); err != nil { + return nil, err + } + out := make([]*Policy, len(rw.Response.Items)) + if len(out) == 0 { + return out, nil + } + for i, rb := range rw.Response.Items { + b, err := policyFromJSON(rb) + if err != nil { + return nil, err + } + out[i] = b + } + return out, nil +} + +func policiesFromHttpResponse(resp *http.Response) ([]*Policy, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return policiesFromJSON(body) +} + +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)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := policiesFromHttpResponse(resp) + if err != nil { + return nil, err + } + + return &ListPoliciesOutput{Policies: gs}, nil +} + +func (s *ServiceOp) CreatePolicy(ctx context.Context, input *CreatePolicyInput) (*CreatePolicyOutput, error) { + r := client.NewRequest(http.MethodPost, "/setup/access/policy") + r.Obj = input + + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := policiesFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(CreatePolicyOutput) + if len(ss) > 0 { + output.Policy = ss[0] + } + + return output, nil +} + +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)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := policiesFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(ReadPolicyOutput) + if len(gs) > 0 { + for i, value := range gs { + if spotinst.StringValue(input.PolicyID) == spotinst.StringValue(value.PolicyID) { + output.Policy = gs[i] + break + } + } + } + + return output, nil +} + +func (s *ServiceOp) UpdatePolicy(ctx context.Context, input *UpdatePolicyInput) (*UpdatePolicyOutput, error) { + path, err := uritemplates.Expand("/setup/access/policy/{policyId}", uritemplates.Values{ + "policyId": spotinst.StringValue(input.Policy.PolicyID), + }) + if err != nil { + return nil, err + } + + // We do not need the ID anymore so let's drop it. + input.Policy.PolicyID = nil + + r := client.NewRequest(http.MethodPut, path) + r.Obj = input + + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := policiesFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(UpdatePolicyOutput) + if len(ss) > 0 { + output.Policy = ss[0] + } + + return output, nil +} + +func (s *ServiceOp) DeletePolicy(ctx context.Context, input *DeletePolicyInput) (*DeletePolicyOutput, error) { + path, err := uritemplates.Expand("/setup/access/policy/{policyId}", uritemplates.Values{ + "policyId": spotinst.StringValue(input.PolicyID), + }) + if err != nil { + return nil, err + } + + r := client.NewRequest(http.MethodDelete, path) + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return &DeletePolicyOutput{}, nil +} + +// region Policy + +func (o Policy) MarshalJSON() ([]byte, error) { + type noMethod Policy + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *Policy) SetDescription(v *string) *Policy { + if o.Description = v; o.Description == nil { + o.nullFields = append(o.nullFields, "Description") + } + return o +} + +func (o *Policy) SetName(v *string) *Policy { + if o.Name = v; o.Name == nil { + o.nullFields = append(o.nullFields, "Name") + } + return o +} + +func (o *Policy) SetPolicyContent(v *PolicyContent) *Policy { + if o.PolicyContent = v; o.PolicyContent == nil { + o.nullFields = append(o.nullFields, "PolicyContent") + } + return o +} + +// endregion + +func (o PolicyContent) MarshalJSON() ([]byte, error) { + type noMethod PolicyContent + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *PolicyContent) SetStatements(v []*Statement) *PolicyContent { + if o.Statements = v; o.Statements == nil { + o.nullFields = append(o.nullFields, "Statements") + } + return o +} + +// endregion + +func (o Statement) MarshalJSON() ([]byte, error) { + type noMethod Statement + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *Statement) SetEffect(v *string) *Statement { + if o.Effect = v; o.Effect == nil { + o.nullFields = append(o.nullFields, "Effect") + } + return o +} + +func (o *Statement) SetResources(v []string) *Statement { + if o.Resources = v; o.Resources == nil { + o.nullFields = append(o.nullFields, "Resources") + } + return o +} + +func (o *Statement) SetActions(v []string) *Statement { + if o.Actions = v; o.Actions == nil { + o.nullFields = append(o.nullFields, "Actions") + } + return o +} + +// endregion diff --git a/service/administration/service.go b/service/administration/service.go new file mode 100644 index 00000000..496b7e17 --- /dev/null +++ b/service/administration/service.go @@ -0,0 +1,50 @@ +package administration + +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 { + ListUsers(context.Context, *ListUsersInput) (*ListUsersOutput, error) + CreateUser(context.Context, *User, *bool) (*CreateUserOutput, error) + CreateProgUser(context.Context, *ProgrammaticUser) (*CreateProgrammaticUserOutput, error) + ReadUser(context.Context, *ReadUserInput) (*ReadUserOutput, error) + ReadProgUser(context.Context, *ReadUserInput) (*ReadProgUserOutput, error) + //Update(context.Context, *UpdateUserInput) (*UpdateUserOutput, error) + DeleteUser(context.Context, *DeleteUserInput) (*DeleteUserOutput, error) + + ListPolicies(context.Context, *ListPoliciesInput) (*ListPoliciesOutput, error) + CreatePolicy(context.Context, *CreatePolicyInput) (*CreatePolicyOutput, error) + ReadPolicy(context.Context, *ReadPolicyInput) (*ReadPolicyOutput, error) + UpdatePolicy(context.Context, *UpdatePolicyInput) (*UpdatePolicyOutput, error) + DeletePolicy(context.Context, *DeletePolicyInput) (*DeletePolicyOutput, error) + + ListUserGroups(context.Context, *ListUserGroupsInput) (*ListUserGroupsOutput, error) + CreateUserGroup(context.Context, *UserGroup) (*CreateUserGroupOutput, error) + ReadUserGroup(context.Context, *ReadUserGroupInput) (*ReadUserGroupOutput, error) + UpdateUserGroup(context.Context, *UserGroup) error + DeleteUserGroup(context.Context, *DeleteUserGroupInput) (*DeleteUserGroupOutput, error) +} + +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(sess.Config), + } +} diff --git a/service/administration/user.go b/service/administration/user.go new file mode 100644 index 00000000..3208d1e0 --- /dev/null +++ b/service/administration/user.go @@ -0,0 +1,471 @@ +package administration + +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" + "strconv" +) + +type User struct { + Email *string `json:"email,omitempty"` + FirstName *string `json:"firstName,omitempty"` + LastName *string `json:"lastName,omitempty"` + Password *string `json:"password,omitempty"` + Role *string `json:"role,omitempty"` + UserID *string `json:"userId,omitempty"` + Username *string `json:"username,omitempty"` + Type *string `json:"type,omitempty"` + Mfa *bool `json:"mfa,omitempty"` + Policies []*UserPolicy `json:"policies,omitempty"` + Tokens []*Token `json:"tokens,omitempty"` + PersonalAccessToken *string `json:"personalAccessToken,omitempty"` + Id *int `json:"id,omitempty"` + GroupNames []*string `json:"groupNames,omitempty"` + Groups []*Group `json:"groups,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + OrganizationId *int `json:"organizationId,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 +} + +type UserPolicy struct { + PolicyId *string `json:"policyId,omitempty"` + PolicyName *string `json:"policyName,omitempty"` + PolicyType *string `json:"policyType,omitempty"` + AccountIds []string `json:"accountIds,omitempty"` + + forceSendFields []string + nullFields []string +} + +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"` + + forceSendFields []string + nullFields []string +} + +type ProgPolicy struct { + PolicyId *string `json:"policyId,omitempty"` + AccountIds []string `json:"accountIds,omitempty"` + + forceSendFields []string + nullFields []string +} + +type Account struct { + Id *string `json:"id,omitempty"` + Role *string `json:"role,omitempty"` + + forceSendFields []string + nullFields []string +} + +type Token struct { + Name *string `json:"name,omitempty"` + CreatedAt *string `json:"createdAt,omitempty"` + TokenId *int `json:"tokenId,omitempty"` + TokenLastDigits *string `json:"tokenLastDigits,omitempty"` + + forceSendFields []string + nullFields []string +} + +type Group struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + PolicyNames []*string `json:"policyNames,omitempty"` + + forceSendFields []string + nullFields []string +} + +type ListUsersInput struct{} + +type ListUsersOutput struct { + Users []*User `json:"users,omitempty"` +} + +type CreateUserOutput struct { + User *User `json:"user,omitempty"` +} + +type CreateProgrammaticUserOutput struct { + ProgrammaticUser *ProgrammaticUser `json:"user,omitempty"` +} + +type ReadUserInput struct { + UserID *string `json:"userId,omitempty"` +} + +type ReadUserOutput struct { + User *User `json:"user,omitempty"` +} + +type ReadProgUserOutput struct { + ProgUser *ProgrammaticUser `json:"user,omitempty"` +} + +type DeleteUserInput struct { + UserID *string `json:"userId,omitempty"` +} + +type DeleteUserOutput struct{} + +func userFromJSON(in []byte) (*User, error) { + b := new(User) + if err := json.Unmarshal(in, b); err != nil { + return nil, err + } + return b, nil +} + +func usersFromJSON(in []byte) ([]*User, error) { + var rw client.Response + if err := json.Unmarshal(in, &rw); err != nil { + return nil, err + } + out := make([]*User, len(rw.Response.Items)) + if len(out) == 0 { + return out, nil + } + for i, rb := range rw.Response.Items { + b, err := userFromJSON(rb) + if err != nil { + return nil, err + } + out[i] = b + } + return out, nil +} + +func usersFromHttpResponse(resp *http.Response) ([]*User, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return usersFromJSON(body) +} + +func progUserFromJSON(in []byte) (*ProgrammaticUser, error) { + b := new(ProgrammaticUser) + if err := json.Unmarshal(in, b); err != nil { + return nil, err + } + return b, nil +} + +func progUsersFromJSON(in []byte) ([]*ProgrammaticUser, error) { + var rw client.Response + if err := json.Unmarshal(in, &rw); err != nil { + return nil, err + } + out := make([]*ProgrammaticUser, len(rw.Response.Items)) + if len(out) == 0 { + return out, nil + } + for i, rb := range rw.Response.Items { + b, err := progUserFromJSON(rb) + if err != nil { + return nil, err + } + out[i] = b + } + return out, nil +} + +func progUsersFromHttpResponse(resp *http.Response) ([]*ProgrammaticUser, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return progUsersFromJSON(body) +} + +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)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := usersFromHttpResponse(resp) + if err != nil { + return nil, err + } + + return &ListUsersOutput{Users: gs}, nil +} + +func (s *ServiceOp) CreateUser(ctx context.Context, input *User, generateToken *bool) (*CreateUserOutput, error) { + r := client.NewRequest(http.MethodPost, "/setup/user") + genToken := strconv.FormatBool(spotinst.BoolValue(generateToken)) + r.Params.Set("generateToken", genToken) + r.Obj = input + + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := usersFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(CreateUserOutput) + if len(ss) > 0 { + output.User = ss[0] + } + + return output, nil +} + +func (s *ServiceOp) CreateProgUser(ctx context.Context, input *ProgrammaticUser) (*CreateProgrammaticUserOutput, error) { + r := client.NewRequest(http.MethodPost, "/setup/user/programmatic") + r.Obj = input + + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := progUsersFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(CreateProgrammaticUserOutput) + if len(ss) > 0 { + output.ProgrammaticUser = ss[0] + } + + return output, nil +} + +func (s *ServiceOp) ReadUser(ctx context.Context, input *ReadUserInput) (*ReadUserOutput, error) { + path, err := uritemplates.Expand("/setup/user/{userId}", uritemplates.Values{ + "userId": spotinst.StringValue(input.UserID), + }) + if err != nil { + return nil, err + } + + r := client.NewRequest(http.MethodGet, path) + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := usersFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(ReadUserOutput) + if len(ss) > 0 { + output.User = ss[0] + } + + return output, nil +} + +func (s *ServiceOp) ReadProgUser(ctx context.Context, input *ReadUserInput) (*ReadProgUserOutput, error) { + path, err := uritemplates.Expand("/setup/user/{userId}", uritemplates.Values{ + "userId": spotinst.StringValue(input.UserID), + }) + if err != nil { + return nil, err + } + + r := client.NewRequest(http.MethodGet, path) + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := progUsersFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(ReadProgUserOutput) + if len(ss) > 0 { + output.ProgUser = ss[0] + } + + return output, 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), + }) + if err != nil { + return nil, err + } + + r := client.NewRequest(http.MethodDelete, path) + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return &DeleteUserOutput{}, nil +} + +// region User + +func (o User) MarshalJSON() ([]byte, error) { + type noMethod User + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *User) SetEmail(v *string) *User { + if o.Email = v; o.Email == nil { + o.nullFields = append(o.nullFields, "Email") + } + return o +} + +func (o *User) SetFirstName(v *string) *User { + if o.FirstName = v; o.FirstName == nil { + o.nullFields = append(o.nullFields, "FirstName") + } + return o +} + +func (o *User) SetLastName(v *string) *User { + if o.LastName = v; o.LastName == nil { + o.nullFields = append(o.nullFields, "LastName") + } + return o +} + +func (o *User) SetPassword(v *string) *User { + if o.Password = v; o.Password == nil { + o.nullFields = append(o.nullFields, "Password") + } + return o +} + +func (o *User) SetRole(v *string) *User { + if o.Role = v; o.Role == nil { + o.nullFields = append(o.nullFields, "Role") + } + return o +} + +// endregion + +// region ProgrammaticUser + +func (o ProgrammaticUser) MarshalJSON() ([]byte, error) { + type noMethod ProgrammaticUser + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *ProgrammaticUser) SetName(v *string) *ProgrammaticUser { + if o.Name = v; o.Name == nil { + o.nullFields = append(o.nullFields, "Name") + } + return o +} + +func (o *ProgrammaticUser) SetDescription(v *string) *ProgrammaticUser { + if o.Description = v; o.Description == nil { + o.nullFields = append(o.nullFields, "Description") + } + return o +} + +func (o *ProgrammaticUser) SetPolicies(v []*ProgPolicy) *ProgrammaticUser { + 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") + } + return o +} + +// endregion + +func (o ProgPolicy) MarshalJSON() ([]byte, error) { + type noMethod ProgPolicy + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *ProgPolicy) SetAccountIds(v []string) *ProgPolicy { + if o.AccountIds = v; o.AccountIds == nil { + o.nullFields = append(o.nullFields, "AccountIds") + } + return o +} + +func (o *ProgPolicy) SetPolicyId(v *string) *ProgPolicy { + 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) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *Account) SetAccountId(v *string) *Account { + if o.Id = v; o.Id == nil { + o.nullFields = append(o.nullFields, "Id") + } + return o +} + +func (o *Account) SetRole(v *string) *Account { + if o.Role = v; o.Role == nil { + o.nullFields = append(o.nullFields, "Role") + } + return o +} diff --git a/service/administration/userGroup.go b/service/administration/userGroup.go new file mode 100644 index 00000000..4a2752cb --- /dev/null +++ b/service/administration/userGroup.go @@ -0,0 +1,291 @@ +package administration + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + + "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" +) + +type UserGroup struct { + Description *string `json:"description,omitempty"` + Name *string `json:"name,omitempty"` + Policies []*UserGroupPolicy `json:"policies,omitempty"` + UserIds []string `json:"userIds,omitempty"` + UserGroupId *string `json:"id,omitempty"` + Users []*GetGroupUser `json:"users,omitempty"` + CreatedAt *string `json:"createdAt,omitempty"` + PolicyNames []string `json:"policyNames,omitempty"` + UsersCount *int `json:"usersCount,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 +} + +type UserGroupPolicy struct { + AccountIds []string `json:"accountIds,omitempty"` + PolicyId *string `json:"policyId,omitempty"` + PolicyName *string `json:"policyName,omitempty"` + PolicyType *string `json:"policyType,omitempty"` + + forceSendFields []string + nullFields []string +} + +type GetGroupUser struct { + Type *string `json:"type,omitempty"` + UserId *string `json:"userId,omitempty"` + UserName *string `json:"userName,omitempty"` + + forceSendFields []string + nullFields []string +} + +type ListUserGroupsInput struct{} + +type ListUserGroupsOutput struct { + UserGroups []*UserGroup `json:"userGroups,omitempty"` +} + +type CreateUserGroupOutput struct { + UserGroup *UserGroup `json:"userGroup,omitempty"` +} + +type ReadUserGroupInput struct { + UserGroupID *string `json:"id,omitempty"` +} + +type ReadUserGroupOutput struct { + UserGroup *UserGroup `json:"userGroup,omitempty"` +} + +type UpdateUserGroupInput struct { + UserGroupID *string `json:"id,omitempty"` +} + +type DeleteUserGroupInput struct { + UserGroupID *string `json:"id,omitempty"` +} + +type DeleteUserGroupOutput struct{} + +func userGroupFromJSON(in []byte) (*UserGroup, error) { + b := new(UserGroup) + if err := json.Unmarshal(in, b); err != nil { + return nil, err + } + return b, nil +} + +func userGroupsFromJSON(in []byte) ([]*UserGroup, error) { + var rw client.Response + if err := json.Unmarshal(in, &rw); err != nil { + return nil, err + } + out := make([]*UserGroup, len(rw.Response.Items)) + if len(out) == 0 { + return out, nil + } + for i, rb := range rw.Response.Items { + b, err := userGroupFromJSON(rb) + if err != nil { + return nil, err + } + out[i] = b + } + return out, nil +} + +func userGroupsFromHttpResponse(resp *http.Response) ([]*UserGroup, error) { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return userGroupsFromJSON(body) +} + +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)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + gs, err := userGroupsFromHttpResponse(resp) + if err != nil { + return nil, err + } + + return &ListUserGroupsOutput{UserGroups: gs}, nil +} + +func (s *ServiceOp) CreateUserGroup(ctx context.Context, input *UserGroup) (*CreateUserGroupOutput, error) { + r := client.NewRequest(http.MethodPost, "/setup/access/userGroup") + r.Obj = input + + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := userGroupsFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(CreateUserGroupOutput) + if len(ss) > 0 { + output.UserGroup = ss[0] + } + + return output, nil +} + +func (s *ServiceOp) ReadUserGroup(ctx context.Context, input *ReadUserGroupInput) (*ReadUserGroupOutput, error) { + path, err := uritemplates.Expand("/setup/access/userGroup/{userGroupId}", uritemplates.Values{ + "userGroupId": spotinst.StringValue(input.UserGroupID), + }) + if err != nil { + return nil, err + } + + r := client.NewRequest(http.MethodGet, path) + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + ss, err := userGroupsFromHttpResponse(resp) + if err != nil { + return nil, err + } + + output := new(ReadUserGroupOutput) + if len(ss) > 0 { + output.UserGroup = ss[0] + } + + return output, nil +} + +func (s *ServiceOp) UpdateUserGroup(ctx context.Context, input *UserGroup) error { + path, err := uritemplates.Expand("/setup/access/userGroup/{userGroupId}", 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.Do(ctx, r)) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +func (s *ServiceOp) DeleteUserGroup(ctx context.Context, input *DeleteUserGroupInput) (*DeleteUserGroupOutput, error) { + path, err := uritemplates.Expand("/setup/access/userGroup/{userGroupId}", uritemplates.Values{ + "userGroupId": spotinst.StringValue(input.UserGroupID), + }) + if err != nil { + return nil, err + } + + r := client.NewRequest(http.MethodDelete, path) + resp, err := client.RequireOK(s.Client.Do(ctx, r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return &DeleteUserGroupOutput{}, nil +} + +// region User + +func (o UserGroup) MarshalJSON() ([]byte, error) { + type noMethod UserGroup + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *UserGroup) SetDescription(v *string) *UserGroup { + if o.Description = v; o.Description == nil { + o.nullFields = append(o.nullFields, "Description") + } + return o +} + +func (o *UserGroup) SetName(v *string) *UserGroup { + if o.Name = v; o.Name == nil { + o.nullFields = append(o.nullFields, "Name") + } + return o +} + +func (o *UserGroup) SetPolicies(v []*UserGroupPolicy) *UserGroup { + if o.Policies = v; o.Policies == nil { + o.nullFields = append(o.nullFields, "Policies") + } + return o +} + +func (o *UserGroup) SetUserIds(v []string) *UserGroup { + if o.UserIds = v; o.UserIds == nil { + o.nullFields = append(o.nullFields, "UserIds") + } + return o +} + +// endregion + +func (o UserGroupPolicy) MarshalJSON() ([]byte, error) { + type noMethod UserGroupPolicy + raw := noMethod(o) + return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields) +} + +func (o *UserGroupPolicy) SetPolicyId(v *string) *UserGroupPolicy { + if o.PolicyId = v; o.PolicyId == nil { + o.nullFields = append(o.nullFields, "PolicyId") + } + return o +} + +func (o *UserGroupPolicy) SetAccountIds(v []string) *UserGroupPolicy { + if o.AccountIds = v; o.AccountIds == nil { + o.nullFields = append(o.nullFields, "AccountIds") + } + return o +} + +//end region