Merge pull request #16931 from spotinst/spotinst/feature/add_aggressiveScaleDown

Spotinst: add aggressive scale down feature
This commit is contained in:
Kubernetes Prow Robot 2024-11-10 16:54:44 +00:00 committed by GitHub
commit 417cb3fcbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 3931 additions and 4808 deletions

View File

@ -204,11 +204,13 @@ metadata:
```
| Label | Description | Default |
|-----------------------------------------------------------------|----------------------------------------------------------------------------------------|---|
|---|----------------------------------------------------------------------------------------|---|
| `spotinst.io/strategy-cluster-spread-nodes-by` | Specify how Ocean will spread the nodes across markets by this value [vcpu,count]. | `count` |
| `spotinst.io/strategy-cluster-orientation-availability-vs-cost` | Specify approach [cost,balanced,cheapest] that Ocean takes while launching nodes. | `balanced` |
| `spotinst.io/resource-tag-specification-volumes` | Specify if Volume resources will be tagged with Virtual Node Group tags or Ocean tags. | `false` |
| `spotinst.io/autoscaler-aggressive-scale-down` | Specify if nodes to be promptly scaled down without any waiting period. | `false` |
## Documentation

2
go.mod
View File

@ -58,7 +58,7 @@ require (
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.19.0
github.com/spotinst/spotinst-sdk-go v1.171.0
github.com/spotinst/spotinst-sdk-go v1.372.0
github.com/stretchr/testify v1.9.0
github.com/weaveworks/mesh v0.0.0-20191105120815-58dbcc3e8e63
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0

4
go.sum
View File

@ -627,8 +627,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/spotinst/spotinst-sdk-go v1.171.0 h1:ZihMPEjkpIkSpawWLJt9RtCRY4mOQMGlfrkVmA03000=
github.com/spotinst/spotinst-sdk-go v1.171.0/go.mod h1:Ku9c4p+kRWnQqmXkzGcTMHLcQKgLHrQZISxeKY7mPqE=
github.com/spotinst/spotinst-sdk-go v1.372.0 h1:B4/+HK3D2Fe0821DOmw5RO4Lrzo2gi7oa6QWWjr5/7A=
github.com/spotinst/spotinst-sdk-go v1.372.0/go.mod h1:Tn4/eb0SFY6IXmxz71CClujvbD/PuT+EO6Ta8v6AML4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=

View File

@ -143,6 +143,10 @@ const (
// SpotClusterLabelResourceTagSpecificationVolumes
// Specify if Volume resources will be tagged with Virtual Node Group tags or Ocean tags.
SpotClusterLabelResourceTagSpecificationVolumes = "spotinst.io/resource-tag-specification-volumes"
// SpotClusterLabelAutoScalerAggressiveScaleDown
// configure the aggressive scale down feature, the default is false. cluster.autoScaler.down.aggressiveScaleDown.isEnabled
SpotClusterLabelAutoScalerAggressiveScaleDown = "spotinst.io/autoscaler-aggressive-scale-down"
)
// SpotInstanceGroupModelBuilder configures SpotInstanceGroup objects
@ -406,6 +410,11 @@ func (b *SpotInstanceGroupModelBuilder) buildOcean(c *fi.CloudupModelBuilderCont
if err != nil {
return err
}
case SpotClusterLabelAutoScalerAggressiveScaleDown:
ocean.AutoScalerAggressiveScaleDown, err = parseBool(v)
if err != nil {
return err
}
}
}

View File

@ -67,6 +67,7 @@ type Ocean struct {
SpreadNodesBy *string
AvailabilityVsCost *string
ResourceTagSpecificationVolumes *bool
AutoScalerAggressiveScaleDown *bool
}
var (
@ -324,11 +325,16 @@ func (o *Ocean) Find(c *fi.CloudupContext) (*Ocean, error) {
// Scale down.
if down := ocean.AutoScaler.Down; down != nil {
if down.MaxScaleDownPercentage != nil || down.EvaluationPeriods != nil {
actual.AutoScalerOpts.Down = &AutoScalerDownOpts{
MaxPercentage: down.MaxScaleDownPercentage,
EvaluationPeriods: down.EvaluationPeriods,
}
}
if down.AggressiveScaleDown != nil {
actual.AutoScalerAggressiveScaleDown = down.AggressiveScaleDown.IsEnabled
}
}
// Resource limits.
if limits := ocean.AutoScaler.ResourceLimits; limits != nil {
@ -585,6 +591,16 @@ func (_ *Ocean) create(cloud awsup.AWSCloud, a, e, changes *Ocean) error {
MaxMemoryGiB: limits.MaxMemory,
}
}
// create AutoScalerAggressiveScaleDown
{
if e.AutoScalerAggressiveScaleDown != nil {
aggressiveScaleDown := new(aws.AggressiveScaleDown)
if down := autoScaler.Down; down == nil {
autoScaler.Down = new(aws.AutoScalerDown)
}
autoScaler.Down.SetAggressiveScaleDown(aggressiveScaleDown.SetIsEnabled(fi.PtrTo(*e.AutoScalerAggressiveScaleDown)))
}
}
ocean.SetAutoScaler(autoScaler)
}
@ -1084,6 +1100,15 @@ func (_ *Ocean) update(cloud awsup.AWSCloud, a, e, changes *Ocean) error {
} else if a.AutoScalerOpts.ResourceLimits != nil {
autoScaler.SetResourceLimits(nil)
}
// AutoScaler aggressive scale down
if changes.AutoScalerAggressiveScaleDown != nil {
aggressiveScaleDown := new(aws.AggressiveScaleDown)
if down := autoScaler.Down; down == nil {
autoScaler.Down = new(aws.AutoScalerDown)
}
autoScaler.Down.SetAggressiveScaleDown(aggressiveScaleDown.SetIsEnabled(fi.PtrTo(*changes.AutoScalerAggressiveScaleDown)))
changes.AutoScalerAggressiveScaleDown = nil
}
ocean.SetAutoScaler(autoScaler)
changed = true

View File

@ -2,7 +2,6 @@ package elastigroup
import (
"github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/aws"
"github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure"
azurev3 "github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3"
"github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/gcp"
"github.com/spotinst/spotinst-sdk-go/spotinst"
@ -15,7 +14,6 @@ import (
// the service.
type Service interface {
CloudProviderAWS() aws.Service
CloudProviderAzure() azure.Service
CloudProviderAzureV3() azurev3.Service
CloudProviderGCP() gcp.Service
}
@ -42,12 +40,6 @@ func (s *ServiceOp) CloudProviderAWS() aws.Service {
}
}
func (s *ServiceOp) CloudProviderAzure() azure.Service {
return &azure.ServiceOp{
Client: s.Client,
}
}
func (s *ServiceOp) CloudProviderAzureV3() azurev3.Service {
return &azurev3.ServiceOp{
Client: s.Client,

View File

@ -70,6 +70,7 @@ type Group struct {
Scaling *Scaling `json:"scaling,omitempty"`
Scheduling *Scheduling `json:"scheduling,omitempty"`
Integration *Integration `json:"thirdPartiesIntegration,omitempty"`
Logging *Logging `json:"logging,omitempty"`
// Read-only fields.
CreatedAt *time.Time `json:"createdAt,omitempty"`
@ -100,7 +101,6 @@ type Integration struct {
Rancher *RancherIntegration `json:"rancher,omitempty"`
Kubernetes *KubernetesIntegration `json:"kubernetes,omitempty"`
Mesosphere *MesosphereIntegration `json:"mesosphere,omitempty"`
Multai *MultaiIntegration `json:"mlbRuntime,omitempty"`
Nomad *NomadIntegration `json:"nomad,omitempty"`
Chef *ChefIntegration `json:"chef,omitempty"`
Gitlab *GitlabIntegration `json:"gitlab,omitempty"`
@ -317,13 +317,6 @@ type MesosphereIntegration struct {
nullFields []string
}
type MultaiIntegration struct {
DeploymentID *string `json:"deploymentId,omitempty"`
forceSendFields []string
nullFields []string
}
type NomadIntegration struct {
MasterHost *string `json:"masterHost,omitempty"`
MasterPort *int `json:"masterPort,omitempty"`
@ -541,6 +534,7 @@ type Strategy struct {
MinimumInstanceLifetime *int `json:"minimumInstanceLifetime,omitempty"`
ConsiderODPricing *bool `json:"considerODPricing,omitempty"`
ImmediateODRecoverThreshold *int `json:"immediateODRecoverThreshold,omitempty"`
RestrictSingleAz *bool `json:"restrictSingleAz,omitempty"`
forceSendFields []string
nullFields []string
@ -702,6 +696,7 @@ type LaunchSpecification struct {
CPUOptions *CPUOptions `json:"cpuOptions,omitempty"`
ResourceTagSpecification *ResourceTagSpecification `json:"resourceTagSpecification,omitempty"`
ITF *ITF `json:"itf,omitempty"`
AutoHealing *bool `json:"autoHealing,omitempty"`
forceSendFields []string
nullFields []string
@ -842,10 +837,6 @@ type LoadBalancer struct {
Name *string `json:"name,omitempty"`
Arn *string `json:"arn,omitempty"`
Type *string `json:"type,omitempty"`
BalancerID *string `json:"balancerId,omitempty"`
TargetSetID *string `json:"targetSetId,omitempty"`
ZoneAwareness *bool `json:"azAwareness,omitempty"`
AutoWeight *bool `json:"autoWeight,omitempty"`
forceSendFields []string
nullFields []string
@ -885,6 +876,26 @@ type EBS struct {
VolumeSize *int `json:"volumeSize,omitempty"`
IOPS *int `json:"iops,omitempty"`
Throughput *int `json:"throughput,omitempty"`
DynamicIOPS *DynamicIOPS `json:"dynamicIops,omitempty"`
DynamicVolumeSize *DynamicVolumeSize `json:"dynamicVolumeSize,omitempty"`
forceSendFields []string
nullFields []string
}
type DynamicIOPS struct {
BaseSize *int `json:"baseSize,omitempty"`
Resource *string `json:"resource,omitempty"`
SizePerResourceUnit *int `json:"sizePerResourceUnit,omitempty"`
forceSendFields []string
nullFields []string
}
type DynamicVolumeSize struct {
BaseSize *int `json:"baseSize,omitempty"`
Resource *string `json:"resource,omitempty"`
SizePerResourceUnit *int `json:"sizePerResourceUnit,omitempty"`
forceSendFields []string
nullFields []string
@ -1105,6 +1116,33 @@ type DeploymentStatusInput struct {
RollID *string `json:"id,omitempty"`
}
type RollStatusInput struct {
GroupID *string `json:"groupId,omitempty"`
RollID *string `json:"id,omitempty"`
}
type BGInstance struct {
InstanceID *string `json:"instanceId,omitempty"`
Lifecycle *string `json:"lifeCycle,omitempty"`
BatchNum *int `json:"batchNum,omitempty"`
Status *string `json:"status,omitempty"`
}
type BGInstances struct {
Blue []*BGInstance `json:"blue,omitempty"`
Green []*BGInstance `json:"green,omitempty"`
}
type RollStatusOutput struct {
Progress *Progress `json:"progress,omitempty"`
NumberOfBatches *int `json:"numberOfBatches,omitempty"`
CurrentBatch *int `json:"currentBatch,omitempty"`
GracePeriod *int `json:"gracePeriod,omitempty"`
StrategyAction *string `json:"strategyAction,omitempty"`
HealthCheck *string `json:"healthCheck,omitempty"`
Instances []*BGInstances `json:"instances,omitempty"`
}
type Roll struct {
Status *string `json:"status,omitempty"`
}
@ -1188,6 +1226,25 @@ type DeallocateStatefulInstanceInput struct {
type DeallocateStatefulInstanceOutput struct{}
type Logging struct {
Export *Export `json:"export,omitempty"`
forceSendFields []string
nullFields []string
}
type Export struct {
S3 *S3 `json:"s3,omitempty"`
forceSendFields []string
nullFields []string
}
type S3 struct {
Id *string `json:"id,omitempty"`
forceSendFields []string
nullFields []string
}
func deploymentStatusFromJSON(in []byte) (*RollGroupStatus, error) {
b := new(RollGroupStatus)
if err := json.Unmarshal(in, b); err != nil {
@ -1214,7 +1271,6 @@ func deploymentStatusesFromJSON(in []byte) ([]*RollGroupStatus, error) {
}
return out, nil
}
func deploymentStatusFromHttpResponse(resp *http.Response) ([]*RollGroupStatus, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
@ -1223,6 +1279,38 @@ func deploymentStatusFromHttpResponse(resp *http.Response) ([]*RollGroupStatus,
return deploymentStatusesFromJSON(body)
}
func rollStatusOutputFromJSON(in []byte) (*RollStatusOutput, error) {
b := new(RollStatusOutput)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}
func rollStatusFromJSON(in []byte) (*RollStatusOutput, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
if len(rw.Response.Items) == 0 {
return nil, nil
}
// Only 1 roll allowed at a time
rollStatusOutput, err := rollStatusOutputFromJSON(rw.Response.Items[0])
if err != nil {
return nil, err
}
return rollStatusOutput, nil
}
func rollStatusFromHttpResponse(resp *http.Response) (*RollStatusOutput, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return rollStatusFromJSON(body)
}
func groupFromJSON(in []byte) (*Group, error) {
b := new(Group)
if err := json.Unmarshal(in, b); err != nil {
@ -1685,6 +1773,31 @@ func (s *ServiceOp) Roll(ctx context.Context, input *RollGroupInput) (*RollGroup
return &RollGroupOutput{deployments}, nil
}
func (s *ServiceOp) RollStatus(ctx context.Context, input *RollStatusInput) (*RollStatusOutput, error) {
path, err := uritemplates.Expand("/aws/ec2/group/{groupId}/roll/{rollId}/status", uritemplates.Values{
"groupId": spotinst.StringValue(input.GroupID),
"rollId": spotinst.StringValue(input.RollID),
})
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()
status, err := rollStatusFromHttpResponse(resp)
if err != nil {
return nil, err
}
return status, nil
}
func (s *ServiceOp) RollECS(ctx context.Context, input *RollECSGroupInput) (*RollGroupOutput, error) {
path, err := uritemplates.Expand("/aws/ec2/group/{groupId}/clusterRoll", uritemplates.Values{
"groupId": spotinst.StringValue(input.GroupID),
@ -2099,6 +2212,13 @@ func (o *Group) SetRegion(v *string) *Group {
return o
}
func (o *Group) SetLogging(v *Logging) *Group {
if o.Logging = v; o.Logging == nil {
o.nullFields = append(o.nullFields, "Logging")
}
return o
}
// endregion
// region Integration
@ -2172,13 +2292,6 @@ func (o *Integration) SetMesosphere(v *MesosphereIntegration) *Integration {
return o
}
func (o *Integration) SetMultai(v *MultaiIntegration) *Integration {
if o.Multai = v; o.Multai == nil {
o.nullFields = append(o.nullFields, "Multai")
}
return o
}
func (o *Integration) SetNomad(v *NomadIntegration) *Integration {
if o.Nomad = v; o.Nomad == nil {
o.nullFields = append(o.nullFields, "Nomad")
@ -2806,23 +2919,6 @@ func (o *MesosphereIntegration) SetServer(v *string) *MesosphereIntegration {
// endregion
// region MultaiIntegration
func (o MultaiIntegration) MarshalJSON() ([]byte, error) {
type noMethod MultaiIntegration
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *MultaiIntegration) SetDeploymentId(v *string) *MultaiIntegration {
if o.DeploymentID = v; o.DeploymentID == nil {
o.nullFields = append(o.nullFields, "DeploymentID")
}
return o
}
// endregion
// region NomadIntegration
func (o NomadIntegration) MarshalJSON() ([]byte, error) {
@ -3619,6 +3715,12 @@ func (o *Strategy) SetMinimumInstanceLifetime(v *int) *Strategy {
}
return o
}
func (o *Strategy) SetRestrictSingleAz(v *bool) *Strategy {
if o.RestrictSingleAz = v; o.RestrictSingleAz == nil {
o.nullFields = append(o.nullFields, "RestrictSingleAz")
}
return o
}
func (o *Strategy) SetConsiderODPricing(v *bool) *Strategy {
if o.ConsiderODPricing = v; o.ConsiderODPricing == nil {
o.nullFields = append(o.nullFields, "ConsiderODPricing")
@ -4260,6 +4362,13 @@ func (o *LaunchSpecification) SetITF(v *ITF) *LaunchSpecification {
return o
}
func (o *LaunchSpecification) SetAutoHealing(v *bool) *LaunchSpecification {
if o.AutoHealing = v; o.AutoHealing == nil {
o.nullFields = append(o.nullFields, "AutoHealing")
}
return o
}
// endregion
// region Matcher
@ -4572,34 +4681,6 @@ func (o *LoadBalancer) SetType(v *string) *LoadBalancer {
return o
}
func (o *LoadBalancer) SetBalancerId(v *string) *LoadBalancer {
if o.BalancerID = v; o.BalancerID == nil {
o.nullFields = append(o.nullFields, "BalancerID")
}
return o
}
func (o *LoadBalancer) SetTargetSetId(v *string) *LoadBalancer {
if o.TargetSetID = v; o.TargetSetID == nil {
o.nullFields = append(o.nullFields, "TargetSetID")
}
return o
}
func (o *LoadBalancer) SetZoneAwareness(v *bool) *LoadBalancer {
if o.ZoneAwareness = v; o.ZoneAwareness == nil {
o.nullFields = append(o.nullFields, "ZoneAwareness")
}
return o
}
func (o *LoadBalancer) SetAutoWeight(v *bool) *LoadBalancer {
if o.AutoWeight = v; o.AutoWeight == nil {
o.nullFields = append(o.nullFields, "AutoWeight")
}
return o
}
// endregion
// region NetworkInterface
@ -4777,6 +4858,74 @@ func (o *EBS) SetThroughput(v *int) *EBS {
return o
}
func (o *EBS) SetDynamicIOPS(v *DynamicIOPS) *EBS {
if o.DynamicIOPS = v; o.DynamicIOPS == nil {
o.nullFields = append(o.nullFields, "DynamicIOPS")
}
return o
}
func (o *EBS) SetDynamicVolumeSize(v *DynamicVolumeSize) *EBS {
if o.DynamicVolumeSize = v; o.DynamicVolumeSize == nil {
o.nullFields = append(o.nullFields, "DynamicVolumeSize")
}
return o
}
func (o DynamicVolumeSize) MarshalJSON() ([]byte, error) {
type noMethod DynamicVolumeSize
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *DynamicVolumeSize) SetBaseSize(v *int) *DynamicVolumeSize {
if o.BaseSize = v; o.BaseSize == nil {
o.nullFields = append(o.nullFields, "BaseSize")
}
return o
}
func (o *DynamicVolumeSize) SetResource(v *string) *DynamicVolumeSize {
if o.Resource = v; o.Resource == nil {
o.nullFields = append(o.nullFields, "Resource")
}
return o
}
func (o *DynamicVolumeSize) SetSizePerResourceUnit(v *int) *DynamicVolumeSize {
if o.SizePerResourceUnit = v; o.SizePerResourceUnit == nil {
o.nullFields = append(o.nullFields, "SizePerResourceUnit")
}
return o
}
func (o DynamicIOPS) MarshalJSON() ([]byte, error) {
type noMethod DynamicIOPS
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *DynamicIOPS) SetBaseSize(v *int) *DynamicIOPS {
if o.BaseSize = v; o.BaseSize == nil {
o.nullFields = append(o.nullFields, "BaseSize")
}
return o
}
func (o *DynamicIOPS) SetResource(v *string) *DynamicIOPS {
if o.Resource = v; o.Resource == nil {
o.nullFields = append(o.nullFields, "Resource")
}
return o
}
func (o *DynamicIOPS) SetSizePerResourceUnit(v *int) *DynamicIOPS {
if o.SizePerResourceUnit = v; o.SizePerResourceUnit == nil {
o.nullFields = append(o.nullFields, "SizePerResourceUnit")
}
return o
}
// endregion
// region IAMInstanceProfile
@ -5502,3 +5651,54 @@ func (o *AMIs) SetShouldTag(v *bool) *AMIs {
}
// endregion
// region Logging
func (o Logging) MarshalJSON() ([]byte, error) {
type noMethod Logging
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Logging) SetExport(v *Export) *Logging {
if o.Export = v; o.Export == nil {
o.nullFields = append(o.nullFields, "Export")
}
return o
}
// endregion
// region Export
func (o Export) MarshalJSON() ([]byte, error) {
type noMethod Export
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Export) SetS3(v *S3) *Export {
if o.S3 = v; o.S3 == nil {
o.nullFields = append(o.nullFields, "S3")
}
return o
}
// endregion
// region S3
func (o S3) MarshalJSON() ([]byte, error) {
type noMethod S3
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *S3) SetId(v *string) *S3 {
if o.Id = v; o.Id == nil {
o.nullFields = append(o.nullFields, "Id")
}
return o
}
// endregion

View File

@ -26,6 +26,7 @@ type Service interface {
StopDeployment(context.Context, *StopDeploymentInput) (*StopDeploymentOutput, error)
Roll(context.Context, *RollGroupInput) (*RollGroupOutput, error)
RollStatus(context.Context, *RollStatusInput) (*RollStatusOutput, error)
RollECS(context.Context, *RollECSGroupInput) (*RollGroupOutput, error)
GetInstanceHealthiness(context.Context, *GetInstanceHealthinessInput) (*GetInstanceHealthinessOutput, error)

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +0,0 @@
package azure
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 {
List(context.Context, *ListGroupsInput) (*ListGroupsOutput, error)
Create(context.Context, *CreateGroupInput) (*CreateGroupOutput, error)
Read(context.Context, *ReadGroupInput) (*ReadGroupOutput, error)
Update(context.Context, *UpdateGroupInput) (*UpdateGroupOutput, error)
Delete(context.Context, *DeleteGroupInput) (*DeleteGroupOutput, error)
Status(context.Context, *StatusGroupInput) (*StatusGroupOutput, error)
Detach(context.Context, *DetachGroupInput) (*DetachGroupOutput, error)
Scale(context.Context, *ScaleGroupInput) (*ScaleGroupOutput, error)
CreateNodeSignal(context.Context, *NodeSignalInput) (*NodeSignalOutput, error)
Roll(context.Context, *RollGroupInput) (*RollGroupOutput, error)
GetRollStatus(context.Context, *RollStatusInput) (*RollStatusOutput, error)
ListRollStatus(context.Context, *ListRollStatusInput) (*ListRollStatusOutput, error)
StopRoll(context.Context, *StopRollInput) (*StopRollOutput, error)
ListTasks(context.Context, *ListTasksInput) (*ListTasksOutput, error)
CreateTask(context.Context, *CreateTaskInput) (*CreateTaskOutput, error)
ReadTask(context.Context, *ReadTaskInput) (*ReadTaskOutput, error)
UpdateTask(context.Context, *UpdateTaskInput) (*UpdateTaskOutput, error)
DeleteTask(context.Context, *DeleteTaskInput) (*DeleteTaskOutput, 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),
}
}

View File

@ -1,31 +0,0 @@
package azure
import "github.com/spotinst/spotinst-sdk-go/spotinst/util/jsonutil"
type Tag struct {
Key *string `json:"tagKey,omitempty"`
Value *string `json:"tagValue,omitempty"`
forceSendFields []string
nullFields []string
}
func (o Tag) MarshalJSON() ([]byte, error) {
type noMethod Tag
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Tag) SetKey(v *string) *Tag {
if o.Key = v; o.Key == nil {
o.nullFields = append(o.nullFields, "Key")
}
return o
}
func (o *Tag) SetValue(v *string) *Tag {
if o.Value = v; o.Value == nil {
o.nullFields = append(o.nullFields, "Value")
}
return o
}

File diff suppressed because it is too large Load Diff

View File

@ -376,6 +376,8 @@ type Strategy struct {
PreemptiblePercentage *int `json:"preemptiblePercentage,omitempty"`
OnDemandCount *int `json:"onDemandCount,omitempty"`
ProvisioningModel *string `json:"provisioningModel,omitempty"`
RevertToPreemptible *RevertToPreemptible `json:"revertToPreemptible,omitempty"`
OptimizationWindows []string `json:"optimizationWindows,omitempty"`
forceSendFields []string
nullFields []string
@ -537,6 +539,13 @@ type UpdateGroupOutput struct {
Group *Group `json:"group,omitempty"`
}
type RevertToPreemptible struct {
PerformAt *string `json:"performAt,omitempty"`
forceSendFields []string
nullFields []string
}
// endregion
// region API Operations
@ -2142,6 +2151,12 @@ func (o Strategy) MarshalJSON() ([]byte, error) {
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o RevertToPreemptible) MarshalJSON() ([]byte, error) {
type noMethod RevertToPreemptible
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
// SetDrainingTimeout sets the time to keep an instance alive after detaching it from the group
func (o *Strategy) SetDrainingTimeout(v *int) *Strategy {
if o.DrainingTimeout = v; o.DrainingTimeout == nil {
@ -2181,4 +2196,25 @@ func (o *Strategy) SetProvisioningModel(v *string) *Strategy {
return o
}
func (o *Strategy) SetRevertToPreemptible(v *RevertToPreemptible) *Strategy {
if o.RevertToPreemptible = v; o.RevertToPreemptible == nil {
o.nullFields = append(o.nullFields, "RevertToPreemptible")
}
return o
}
func (o *RevertToPreemptible) SetPerformAt(v *string) *RevertToPreemptible {
if o.PerformAt = v; o.PerformAt == nil {
o.nullFields = append(o.nullFields, "PerformAt")
}
return o
}
func (o *Strategy) SetOptimizationWindows(v []string) *Strategy {
if o.OptimizationWindows = v; o.OptimizationWindows == nil {
o.nullFields = append(o.nullFields, "OptimizationWindows")
}
return o
}
// endregion

View File

@ -2,9 +2,9 @@ package ocean
import (
"github.com/spotinst/spotinst-sdk-go/service/ocean/providers/aws"
"github.com/spotinst/spotinst-sdk-go/service/ocean/providers/azure"
"github.com/spotinst/spotinst-sdk-go/service/ocean/providers/azure_np"
"github.com/spotinst/spotinst-sdk-go/service/ocean/providers/gcp"
"github.com/spotinst/spotinst-sdk-go/service/ocean/right_sizing"
"github.com/spotinst/spotinst-sdk-go/service/ocean/spark"
"github.com/spotinst/spotinst-sdk-go/spotinst"
"github.com/spotinst/spotinst-sdk-go/spotinst/client"
@ -17,9 +17,9 @@ import (
type Service interface {
CloudProviderAWS() aws.Service
CloudProviderGCP() gcp.Service
CloudProviderAzure() azure.Service
Spark() spark.Service
CloudProviderAzureNP() azure_np.Service
RightSizing() right_sizing.Service
}
type ServiceOp struct {
@ -50,12 +50,6 @@ func (s *ServiceOp) CloudProviderGCP() gcp.Service {
}
}
func (s *ServiceOp) CloudProviderAzure() azure.Service {
return &azure.ServiceOp{
Client: s.Client,
}
}
func (s *ServiceOp) Spark() spark.Service {
return &spark.ServiceOp{
Client: s.Client,
@ -67,3 +61,9 @@ func (s *ServiceOp) CloudProviderAzureNP() azure_np.Service {
Client: s.Client,
}
}
func (s *ServiceOp) RightSizing() right_sizing.Service {
return &right_sizing.ServiceOp{
Client: s.Client,
}
}

View File

@ -122,6 +122,45 @@ type Task struct {
IsEnabled *bool `json:"isEnabled,omitempty"`
Type *string `json:"taskType,omitempty"`
CronExpression *string `json:"cronExpression,omitempty"`
Parameter *Parameter `json:"parameters,omitempty"`
forceSendFields []string
nullFields []string
}
type Parameter struct {
AmiAutoUpdate *AmiAutoUpdate `json:"amiAutoUpdate,omitempty"`
ClusterRoll *ParameterClusterRoll `json:"clusterRoll,omitempty"`
forceSendFields []string
nullFields []string
}
type AmiAutoUpdate struct {
ApplyRoll *bool `json:"applyRoll,omitempty"`
AmiAutoUpdateClusterRoll *AmiAutoUpdateClusterRoll `json:"clusterRoll,omitempty"`
MinorVersion *bool `json:"minorVersion,omitempty"`
Patch *bool `json:"patch,omitempty"`
forceSendFields []string
nullFields []string
}
type AmiAutoUpdateClusterRoll struct {
BatchMinHealthyPercentage *int `json:"batchMinHealthyPercentage,omitempty"`
BatchSizePercentage *int `json:"batchSizePercentage,omitempty"`
Comment *string `json:"comment,omitempty"`
RespectPdb *bool `json:"respectPdb,omitempty"`
forceSendFields []string
nullFields []string
}
type ParameterClusterRoll struct {
BatchMinHealthyPercentage *int `json:"batchMinHealthyPercentage,omitempty"`
BatchSizePercentage *int `json:"batchSizePercentage,omitempty"`
Comment *string `json:"comment,omitempty"`
RespectPdb *bool `json:"respectPdb,omitempty"`
forceSendFields []string
nullFields []string
@ -172,6 +211,7 @@ type LaunchSpecification struct {
Tags []*Tag `json:"tags,omitempty"`
LoadBalancers []*LoadBalancer `json:"loadBalancers,omitempty"`
RootVolumeSize *int `json:"rootVolumeSize,omitempty"`
HealthCheckUnhealthyDurationBeforeReplacement *int `json:"healthCheckUnhealthyDurationBeforeReplacement,omitempty"`
Monitoring *bool `json:"monitoring,omitempty"`
EBSOptimized *bool `json:"ebsOptimized,omitempty"`
UseAsTemplateOnly *bool `json:"useAsTemplateOnly,omitempty"`
@ -237,6 +277,14 @@ type AutoScalerResourceLimits struct {
type AutoScalerDown struct {
EvaluationPeriods *int `json:"evaluationPeriods,omitempty"`
MaxScaleDownPercentage *float64 `json:"maxScaleDownPercentage,omitempty"`
AggressiveScaleDown *AggressiveScaleDown `json:"aggressiveScaleDown,omitempty"`
forceSendFields []string
nullFields []string
}
type AggressiveScaleDown struct {
IsEnabled *bool `json:"isEnabled,omitempty"`
forceSendFields []string
nullFields []string
@ -1349,6 +1397,125 @@ func (o *Task) SetCronExpression(v *string) *Task {
// endregion
// region Parameter
func (o *Task) SetParameter(v *Parameter) *Task {
if o.Parameter = v; o.Parameter == nil {
o.nullFields = append(o.nullFields, "Parameter")
}
return o
}
func (o *Parameter) SetAmiAutoUpdate(v *AmiAutoUpdate) *Parameter {
if o.AmiAutoUpdate = v; o.AmiAutoUpdate == nil {
o.nullFields = append(o.nullFields, "AmiAutoUpdate")
}
return o
}
func (o *Parameter) SetClusterRoll(v *ParameterClusterRoll) *Parameter {
if o.ClusterRoll = v; o.ClusterRoll == nil {
o.nullFields = append(o.nullFields, "ClusterRoll")
}
return o
}
// region AmiAutoUpdate
func (o *AmiAutoUpdate) SetApplyRoll(v *bool) *AmiAutoUpdate {
if o.ApplyRoll = v; o.ApplyRoll == nil {
o.nullFields = append(o.nullFields, "ApplyRoll")
}
return o
}
func (o *AmiAutoUpdate) SetClusterRoll(v *AmiAutoUpdateClusterRoll) *AmiAutoUpdate {
if o.AmiAutoUpdateClusterRoll = v; o.AmiAutoUpdateClusterRoll == nil {
o.nullFields = append(o.nullFields, "ClusterRoll")
}
return o
}
func (o *AmiAutoUpdate) SetMinorVersion(v *bool) *AmiAutoUpdate {
if o.MinorVersion = v; o.MinorVersion == nil {
o.nullFields = append(o.nullFields, "MinorVersion")
}
return o
}
func (o *AmiAutoUpdate) SetPatch(v *bool) *AmiAutoUpdate {
if o.Patch = v; o.Patch == nil {
o.nullFields = append(o.nullFields, "Patch")
}
return o
}
// endregion
// region ParameterClusterRoll
func (o *ParameterClusterRoll) SetBatchMinHealthyPercentage(v *int) *ParameterClusterRoll {
if o.BatchMinHealthyPercentage = v; o.BatchMinHealthyPercentage == nil {
o.nullFields = append(o.nullFields, "BatchMinHealthyPercentage")
}
return o
}
func (o *ParameterClusterRoll) SetBatchSizePercentage(v *int) *ParameterClusterRoll {
if o.BatchSizePercentage = v; o.BatchSizePercentage == nil {
o.nullFields = append(o.nullFields, "BatchSizePercentage")
}
return o
}
func (o *ParameterClusterRoll) SetComment(v *string) *ParameterClusterRoll {
if o.Comment = v; o.Comment == nil {
o.nullFields = append(o.nullFields, "Comment")
}
return o
}
func (o *ParameterClusterRoll) SetRespectPdb(v *bool) *ParameterClusterRoll {
if o.RespectPdb = v; o.RespectPdb == nil {
o.nullFields = append(o.nullFields, "RespectPdb")
}
return o
}
// endregion
// region ParameterClusterRoll
func (o *AmiAutoUpdateClusterRoll) SetBatchMinHealthyPercentage(v *int) *AmiAutoUpdateClusterRoll {
if o.BatchMinHealthyPercentage = v; o.BatchMinHealthyPercentage == nil {
o.nullFields = append(o.nullFields, "BatchMinHealthyPercentage")
}
return o
}
func (o *AmiAutoUpdateClusterRoll) SetBatchSizePercentage(v *int) *AmiAutoUpdateClusterRoll {
if o.BatchSizePercentage = v; o.BatchSizePercentage == nil {
o.nullFields = append(o.nullFields, "BatchSizePercentage")
}
return o
}
func (o *AmiAutoUpdateClusterRoll) SetComment(v *string) *AmiAutoUpdateClusterRoll {
if o.Comment = v; o.Comment == nil {
o.nullFields = append(o.nullFields, "Comment")
}
return o
}
func (o *AmiAutoUpdateClusterRoll) SetRespectPdb(v *bool) *AmiAutoUpdateClusterRoll {
if o.RespectPdb = v; o.RespectPdb == nil {
o.nullFields = append(o.nullFields, "RespectPdb")
}
return o
}
// endregion
// region ShutdownHours
func (o ShutdownHours) MarshalJSON() ([]byte, error) {
@ -1517,6 +1684,13 @@ func (o *LaunchSpecification) SetResourceTagSpecification(v *ResourceTagSpecific
return o
}
func (o *LaunchSpecification) SetHealthCheckUnhealthyDurationBeforeReplacement(v *int) *LaunchSpecification {
if o.HealthCheckUnhealthyDurationBeforeReplacement = v; o.HealthCheckUnhealthyDurationBeforeReplacement == nil {
o.nullFields = append(o.nullFields, "HealthCheckUnhealthyDurationBeforeReplacement")
}
return o
}
// endregion
// region LoadBalancer
@ -1725,8 +1899,28 @@ func (o *AutoScalerDown) SetMaxScaleDownPercentage(v *float64) *AutoScalerDown {
return o
}
func (o *AutoScalerDown) SetAggressiveScaleDown(v *AggressiveScaleDown) *AutoScalerDown {
if o.AggressiveScaleDown = v; o.AggressiveScaleDown == nil {
o.nullFields = append(o.nullFields, "AggressiveScaleDown")
}
return o
}
// endregion
func (o AggressiveScaleDown) MarshalJSON() ([]byte, error) {
type noMethod AggressiveScaleDown
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *AggressiveScaleDown) SetIsEnabled(v *bool) *AggressiveScaleDown {
if o.IsEnabled = v; o.IsEnabled == nil {
o.nullFields = append(o.nullFields, "IsEnabled")
}
return o
}
// region Roll
func (o Roll) MarshalJSON() ([]byte, error) {
@ -2078,6 +2272,7 @@ type ClusterEBS struct {
VolumeSize *int `json:"volumeSize,omitempty"`
Throughput *int `json:"throughput,omitempty"`
DynamicVolumeSize *ClusterDynamicVolumeSize `json:"dynamicVolumeSize,omitempty"`
DynamicIops *ClusterDynamicIops `json:"dynamicIops,omitempty"`
forceSendFields []string
nullFields []string
@ -2091,6 +2286,15 @@ type ClusterDynamicVolumeSize struct {
nullFields []string
}
type ClusterDynamicIops struct {
BaseSize *int `json:"baseSize,omitempty"`
SizePerResourceUnit *int `json:"sizePerResourceUnit,omitempty"`
Resource *string `json:"resource,omitempty"`
forceSendFields []string
nullFields []string
}
// region BlockDeviceMapping
func (o ClusterBlockDeviceMappings) MarshalJSON() ([]byte, error) {
@ -2186,6 +2390,13 @@ func (o *ClusterEBS) SetThroughput(v *int) *ClusterEBS {
return o
}
func (o *ClusterEBS) SetDynamicIops(v *ClusterDynamicIops) *ClusterEBS {
if o.DynamicIops = v; o.DynamicIops == nil {
o.nullFields = append(o.nullFields, "DynamicIops")
}
return o
}
// endregion
// region DynamicVolumeSize
@ -2219,6 +2430,37 @@ func (o *ClusterDynamicVolumeSize) SetSizePerResourceUnit(v *int) *ClusterDynami
// endregion
// region DynamicIops
func (o ClusterDynamicIops) MarshalJSON() ([]byte, error) {
type noMethod ClusterDynamicIops
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *ClusterDynamicIops) SetBaseSize(v *int) *ClusterDynamicIops {
if o.BaseSize = v; o.BaseSize == nil {
o.nullFields = append(o.nullFields, "BaseSize")
}
return o
}
func (o *ClusterDynamicIops) SetResource(v *string) *ClusterDynamicIops {
if o.Resource = v; o.Resource == nil {
o.nullFields = append(o.nullFields, "Resource")
}
return o
}
func (o *ClusterDynamicIops) SetSizePerResourceUnit(v *int) *ClusterDynamicIops {
if o.SizePerResourceUnit = v; o.SizePerResourceUnit == nil {
o.nullFields = append(o.nullFields, "SizePerResourceUnit")
}
return o
}
// endregion
// region ResourceTagSpecification
func (o ResourceTagSpecification) MarshalJSON() ([]byte, error) {

View File

@ -0,0 +1,123 @@
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/uritemplates"
"io/ioutil"
"net/http"
"time"
)
type ClusterNodes struct {
InstanceId *string `json:"instanceId,omitempty"`
InstanceType *string `json:"instanceType,omitempty"`
AvailabilityZone *string `json:"availabilityZone,omitempty"`
LaunchSpecId *string `json:"launchSpecId,omitempty"`
LaunchSpecName *string `json:"launchSpecName,omitempty"`
LifeCycle *string `json:"lifeCycle,omitempty"`
PublicIp *string `json:"publicIp,omitempty"`
NodeName *string `json:"nodeName,omitempty"`
RegistrationStatus *string `json:"registrationStatus,omitempty"`
WorkloadRequestedMilliCpu *int `json:"workloadRequestedMilliCpu,omitempty"`
WorkloadRequestedMemoryInMiB *int `json:"workloadRequestedMemoryInMiB,omitempty"`
WorkloadRequestedGpu *int `json:"workloadRequestedGpu,omitempty"`
HeadroomRequestedMilliCpu *int `json:"headroomRequestedMilliCpu,omitempty"`
HeadroomRequestedMemoryInMiB *int `json:"headroomRequestedMemoryInMiB,omitempty"`
HeadroomRequestedGpu *int `json:"headroomRequestedGpu,omitempty"`
AllocatableMilliCpu *int `json:"allocatableMilliCpu,omitempty"`
AllocatableMemoryInMiB *float64 `json:"allocatableMemoryInMiB,omitempty"`
AllocatableGpu *int `json:"allocatableGpu,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
}
type ReadClusterNodeInput struct {
ClusterID *string `json:"clusterId,omitempty"`
LaunchSpecId *string `json:"launchSpecId,omitempty"`
InstanceId *string `json:"instanceId,omitempty"`
}
type ReadClusterNodeOutput struct {
ClusterNode []*ClusterNodes `json:"clusterNode,omitempty"`
}
func (s *ServiceOp) ReadClusterNodes(ctx context.Context, input *ReadClusterNodeInput) (*ReadClusterNodeOutput, error) {
path, err := uritemplates.Expand("/ocean/aws/k8s/cluster/{oceanClusterId}/nodes", uritemplates.Values{
"oceanClusterId": spotinst.StringValue(input.ClusterID),
})
if err != nil {
return nil, err
}
r := client.NewRequest(http.MethodGet, path)
if input.LaunchSpecId != nil {
r.Params["launchSpecId"] = []string{spotinst.StringValue(input.LaunchSpecId)}
}
if input.InstanceId != nil {
r.Params["instanceId"] = []string{spotinst.StringValue(input.InstanceId)}
}
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
gs, err := nodesFromHttpResponse(resp)
if err != nil {
return nil, err
}
return &ReadClusterNodeOutput{ClusterNode: gs}, nil
}
func nodesFromHttpResponse(resp *http.Response) ([]*ClusterNodes, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return nodesFromJSON(body)
}
func nodesFromJSON(in []byte) ([]*ClusterNodes, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*ClusterNodes, len(rw.Response.Items))
if len(out) == 0 {
return out, nil
}
for i, rb := range rw.Response.Items {
b, err := nodeFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}
return out, nil
}
func nodeFromJSON(in []byte) (*ClusterNodes, error) {
b := new(ClusterNodes)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}

View File

@ -31,6 +31,7 @@ type LaunchSpec struct {
AutoScale *AutoScale `json:"autoScale,omitempty"`
ElasticIPPool *ElasticIPPool `json:"elasticIpPool,omitempty"`
BlockDeviceMappings []*BlockDeviceMapping `json:"blockDeviceMappings,omitempty"`
EphemeralStorage *EphemeralStorage `json:"ephemeralStorage,omitempty"`
Labels []*Label `json:"labels,omitempty"`
Taints []*Taint `json:"taints,omitempty"`
Tags []*Tag `json:"tags,omitempty"`
@ -39,6 +40,8 @@ type LaunchSpec struct {
LaunchSpecScheduling *LaunchSpecScheduling `json:"scheduling,omitempty"`
InstanceMetadataOptions *LaunchspecInstanceMetadataOptions `json:"instanceMetadataOptions,omitempty"`
Images []*Images `json:"images,omitempty"`
InstanceTypesFilters *InstanceTypesFilters `json:"instanceTypesFilters,omitempty"`
PreferredOnDemandTypes []string `json:"preferredOnDemandTypes,omitempty"`
// Read-only fields.
CreatedAt *time.Time `json:"createdAt,omitempty"`
@ -219,6 +222,9 @@ type TagSelector struct {
type LaunchSpecStrategy struct {
SpotPercentage *int `json:"spotPercentage,omitempty"`
DrainingTimeout *int `json:"drainingTimeout,omitempty"`
UtilizeCommitments *bool `json:"utilizeCommitments,omitempty"`
UtilizeReservedInstances *bool `json:"utilizeReservedInstances,omitempty"`
forceSendFields []string
nullFields []string
@ -274,6 +280,37 @@ type Images struct {
nullFields []string
}
type InstanceTypesFilters struct {
Categories []string `json:"categories,omitempty"`
DiskTypes []string `json:"diskTypes,omitempty"`
ExcludeFamilies []string `json:"excludeFamilies,omitempty"`
ExcludeMetal *bool `json:"excludeMetal,omitempty"`
Hypervisor []string `json:"hypervisor,omitempty"`
IncludeFamilies []string `json:"includeFamilies,omitempty"`
IsEnaSupported *bool `json:"isEnaSupported,omitempty"`
MaxGpu *int `json:"maxGpu,omitempty"`
MaxMemoryGiB *float64 `json:"maxMemoryGiB,omitempty"`
MaxNetworkPerformance *int `json:"maxNetworkPerformance,omitempty"`
MaxVcpu *int `json:"maxVcpu,omitempty"`
MinEnis *int `json:"minEnis,omitempty"`
MinGpu *int `json:"minGpu,omitempty"`
MinMemoryGiB *float64 `json:"minMemoryGiB,omitempty"`
MinNetworkPerformance *int `json:"minNetworkPerformance,omitempty"`
MinVcpu *int `json:"minVcpu,omitempty"`
RootDeviceTypes []string `json:"rootDeviceTypes,omitempty"`
VirtualizationTypes []string `json:"virtualizationTypes,omitempty"`
forceSendFields []string
nullFields []string
}
type EphemeralStorage struct {
DeviceName *string `json:"deviceName,omitempty"`
forceSendFields []string
nullFields []string
}
type ListLaunchSpecsInput struct {
OceanID *string `json:"oceanId,omitempty"`
}
@ -558,6 +595,13 @@ func (o *LaunchSpec) SetPreferredSpotTypes(v []string) *LaunchSpec {
return o
}
func (o *LaunchSpec) SetPreferredOnDemandTypes(v []string) *LaunchSpec {
if o.PreferredOnDemandTypes = v; o.PreferredOnDemandTypes == nil {
o.nullFields = append(o.nullFields, "PreferredOnDemandTypes")
}
return o
}
func (o *LaunchSpec) SetRootVolumeSize(v *int) *LaunchSpec {
if o.RootVolumeSize = v; o.RootVolumeSize == nil {
o.nullFields = append(o.nullFields, "RootVolumeSize")
@ -648,6 +692,18 @@ func (o *LaunchSpec) SetScheduling(v *LaunchSpecScheduling) *LaunchSpec {
}
return o
}
func (o *LaunchSpec) SetInstanceTypesFilters(v *InstanceTypesFilters) *LaunchSpec {
if o.InstanceTypesFilters = v; o.InstanceTypesFilters == nil {
o.nullFields = append(o.nullFields, "InstanceTypesFilters")
}
return o
}
func (o *LaunchSpec) SetEphemeralStorage(v *EphemeralStorage) *LaunchSpec {
if o.EphemeralStorage = v; o.EphemeralStorage == nil {
o.nullFields = append(o.nullFields, "EphemeralStorage")
}
return o
}
// endregion
@ -990,6 +1046,27 @@ func (o *LaunchSpecStrategy) SetSpotPercentage(v *int) *LaunchSpecStrategy {
return o
}
func (o *LaunchSpecStrategy) SetDrainingTimeout(v *int) *LaunchSpecStrategy {
if o.DrainingTimeout = v; o.DrainingTimeout == nil {
o.nullFields = append(o.nullFields, "DrainingTimeout")
}
return o
}
func (o *LaunchSpecStrategy) SetUtilizeCommitments(v *bool) *LaunchSpecStrategy {
if o.UtilizeCommitments = v; o.UtilizeCommitments == nil {
o.nullFields = append(o.nullFields, "UtilizeCommitments")
}
return o
}
func (o *LaunchSpecStrategy) SetUtilizeReservedInstances(v *bool) *LaunchSpecStrategy {
if o.UtilizeReservedInstances = v; o.UtilizeReservedInstances == nil {
o.nullFields = append(o.nullFields, "UtilizeReservedInstances")
}
return o
}
// endregion
//region Scheduling
@ -1150,3 +1227,156 @@ func (o *Images) SetImageId(v *string) *Images {
}
// endregion
// region InstanceTypesFilters
func (o InstanceTypesFilters) MarshalJSON() ([]byte, error) {
type noMethod InstanceTypesFilters
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *InstanceTypesFilters) SetCategories(v []string) *InstanceTypesFilters {
if o.Categories = v; o.Categories == nil {
o.nullFields = append(o.nullFields, "Categories")
}
return o
}
func (o *InstanceTypesFilters) SetDiskTypes(v []string) *InstanceTypesFilters {
if o.DiskTypes = v; o.DiskTypes == nil {
o.nullFields = append(o.nullFields, "DiskTypes")
}
return o
}
func (o *InstanceTypesFilters) SetExcludeFamilies(v []string) *InstanceTypesFilters {
if o.ExcludeFamilies = v; o.ExcludeFamilies == nil {
o.nullFields = append(o.nullFields, "ExcludeFamilies")
}
return o
}
func (o *InstanceTypesFilters) SetExcludeMetal(v *bool) *InstanceTypesFilters {
if o.ExcludeMetal = v; o.ExcludeMetal == nil {
o.nullFields = append(o.nullFields, "ExcludeMetal")
}
return o
}
func (o *InstanceTypesFilters) SetHypervisor(v []string) *InstanceTypesFilters {
if o.Hypervisor = v; o.Hypervisor == nil {
o.nullFields = append(o.nullFields, "Hypervisor")
}
return o
}
func (o *InstanceTypesFilters) SetIncludeFamilies(v []string) *InstanceTypesFilters {
if o.IncludeFamilies = v; o.IncludeFamilies == nil {
o.nullFields = append(o.nullFields, "IncludeFamilies")
}
return o
}
func (o *InstanceTypesFilters) SetIsEnaSupported(v *bool) *InstanceTypesFilters {
if o.IsEnaSupported = v; o.IsEnaSupported == nil {
o.nullFields = append(o.nullFields, "IsEnaSupported")
}
return o
}
func (o *InstanceTypesFilters) SetMaxGpu(v *int) *InstanceTypesFilters {
if o.MaxGpu = v; o.MaxGpu == nil {
o.nullFields = append(o.nullFields, "MaxGpu")
}
return o
}
func (o *InstanceTypesFilters) SetMaxMemoryGiB(v *float64) *InstanceTypesFilters {
if o.MaxMemoryGiB = v; o.MaxMemoryGiB == nil {
o.nullFields = append(o.nullFields, "MaxMemoryGiB")
}
return o
}
func (o *InstanceTypesFilters) SetMaxNetworkPerformance(v *int) *InstanceTypesFilters {
if o.MaxNetworkPerformance = v; o.MaxNetworkPerformance == nil {
o.nullFields = append(o.nullFields, "MaxNetworkPerformance")
}
return o
}
func (o *InstanceTypesFilters) SetMaxVcpu(v *int) *InstanceTypesFilters {
if o.MaxVcpu = v; o.MaxVcpu == nil {
o.nullFields = append(o.nullFields, "MaxVcpu")
}
return o
}
func (o *InstanceTypesFilters) SetMinEnis(v *int) *InstanceTypesFilters {
if o.MinEnis = v; o.MinEnis == nil {
o.nullFields = append(o.nullFields, "MinEnis")
}
return o
}
func (o *InstanceTypesFilters) SetMinGpu(v *int) *InstanceTypesFilters {
if o.MinGpu = v; o.MinGpu == nil {
o.nullFields = append(o.nullFields, "MinGpu")
}
return o
}
func (o *InstanceTypesFilters) SetMinMemoryGiB(v *float64) *InstanceTypesFilters {
if o.MinMemoryGiB = v; o.MinMemoryGiB == nil {
o.nullFields = append(o.nullFields, "MinMemoryGiB")
}
return o
}
func (o *InstanceTypesFilters) SetMinNetworkPerformance(v *int) *InstanceTypesFilters {
if o.MinNetworkPerformance = v; o.MinNetworkPerformance == nil {
o.nullFields = append(o.nullFields, "MinNetworkPerformance")
}
return o
}
func (o *InstanceTypesFilters) SetMinVcpu(v *int) *InstanceTypesFilters {
if o.MinVcpu = v; o.MinVcpu == nil {
o.nullFields = append(o.nullFields, "MinVcpu")
}
return o
}
func (o *InstanceTypesFilters) SetRootDeviceTypes(v []string) *InstanceTypesFilters {
if o.RootDeviceTypes = v; o.RootDeviceTypes == nil {
o.nullFields = append(o.nullFields, "RootDeviceTypes")
}
return o
}
func (o *InstanceTypesFilters) SetVirtualizationTypes(v []string) *InstanceTypesFilters {
if o.VirtualizationTypes = v; o.VirtualizationTypes == nil {
o.nullFields = append(o.nullFields, "VirtualizationTypes")
}
return o
}
// endregion
// region EphemeralStorage
func (o *EphemeralStorage) SetDeviceName(v *string) *EphemeralStorage {
if o.DeviceName = v; o.DeviceName == nil {
o.nullFields = append(o.nullFields, "DeviceName")
}
return o
}
func (o EphemeralStorage) MarshalJSON() ([]byte, error) {
type noMethod EphemeralStorage
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
// endregion

View File

@ -32,6 +32,7 @@ type ECSLaunchSpec struct {
SubnetIDs []string `json:"subnetIds,omitempty"`
LaunchSpecScheduling *ECSLaunchSpecScheduling `json:"scheduling,omitempty"`
InstanceMetadataOptions *ECSLaunchspecInstanceMetadataOptions `json:"instanceMetadataOptions,omitempty"`
Images []*ECSImages `json:"images,omitempty"`
// Read-only fields.
CreatedAt *time.Time `json:"createdAt,omitempty"`
@ -226,6 +227,33 @@ type DeleteECSLaunchSpecInput struct {
LaunchSpecID *string `json:"launchSpecId,omitempty"`
}
type ECSImages struct {
ImageId *string `json:"id,omitempty"`
forceSendFields []string
nullFields []string
}
func (o *ECSLaunchSpec) SetECSImages(v []*ECSImages) *ECSLaunchSpec {
if o.Images = v; o.Images == nil {
o.nullFields = append(o.nullFields, "Images")
}
return o
}
func (o ECSImages) MarshalJSON() ([]byte, error) {
type noMethod ECSImages
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *ECSImages) SetImageId(v *string) *ECSImages {
if o.ImageId = v; o.ImageId == nil {
o.nullFields = append(o.nullFields, "ImageId")
}
return o
}
type DeleteECSLaunchSpecOutput struct{}
func ecsLaunchSpecFromJSON(in []byte) (*ECSLaunchSpec, error) {

View File

@ -0,0 +1,73 @@
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/util/uritemplates"
"net/http"
)
type LoadBalancers struct {
Arn *string `json:"arn,omitempty"`
Name *string `json:"name,omitempty"`
Type *string `json:"type,omitempty"`
}
type AttachLoadbalancerInput struct {
LoadBalancers []*LoadBalancers `json:"loadBalancers,omitempty"`
ID *string `json:"id,omitempty"`
}
type AttachLoadbalancerOutput struct{}
type DetachLoadbalancerInput struct {
LoadBalancers []*LoadBalancers `json:"loadBalancers,omitempty"`
ID *string `json:"id,omitempty"`
}
type DetachLoadbalancerOutput struct{}
func (s *ServiceOp) AttachLoadBalancer(ctx context.Context,
input *AttachLoadbalancerInput) (*AttachLoadbalancerOutput, error) {
path, err := uritemplates.Expand("/ocean/aws/k8s/cluster/{oceanClusterId}/loadBalancer/attach", uritemplates.Values{
"oceanClusterId": spotinst.StringValue(input.ID),
})
if err != nil {
return nil, err
}
input.ID = 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()
return &AttachLoadbalancerOutput{}, nil
}
func (s *ServiceOp) DetachLoadBalancer(ctx context.Context,
input *DetachLoadbalancerInput) (*DetachLoadbalancerOutput, error) {
path, err := uritemplates.Expand("/ocean/aws/k8s/cluster/{oceanClusterId}/loadBalancer/detach", uritemplates.Values{
"oceanClusterId": spotinst.StringValue(input.ID),
})
if err != nil {
return nil, err
}
input.ID = 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()
return &DetachLoadbalancerOutput{}, nil
}

View File

@ -0,0 +1,136 @@
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/uritemplates"
"io/ioutil"
"net/http"
)
type MigrationStatus struct {
ID *string `json:"Id,omitempty"`
OceanId *string `json:"oceanId,omitempty"`
Status *string `json:"status,omitempty"`
NewInstances []*InstanceDetails `json:"newInstances,omitempty"`
OldInstances []*InstanceDetails `json:"oldInstances,omitempty"`
UnscheduledPodIds *string `json:"unscheduledPodIds,omitempty"`
NewUnscheduledPodIds *string `json:"newUnscheduledPodIds,omitempty"`
MigrationConfig *MigrationConfig `json:"migrationConfig,omitempty"`
CreatedAt *string `json:"createdAt,omitempty"`
ErroredAt *string `json:"erroredAt,omitempty"`
StoppedAt *string `json:"stoppedAt,omitempty"`
CompletedAt *string `json:"completedAt,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 MigrationConfig struct {
ShouldTerminateDrainedNodes *bool `json:"shouldTerminateDrainedNodes,omitempty"`
ShouldEvictStandAlonePods *bool `json:"shouldEvictStandAlonePods,omitempty"`
forceSendFields []string
nullFields []string
}
type InstanceDetails struct {
InstanceId *string `json:"instanceId,omitempty"`
K8sNodeName *string `json:"k8sNodeName,omitempty"`
AsgName *string `json:"asgName,omitempty"`
State *string `json:"state,omitempty"`
RunningPods *int64 `json:"runningPods,omitempty"`
PodDetails []*PodDetails `json:"podDetails,omitempty"`
forceSendFields []string
nullFields []string
}
type PodDetails struct {
ID *string `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Kind *string `json:"kind,omitempty"`
forceSendFields []string
nullFields []string
}
type ReadMigrationStatusInput struct {
ClusterID *string `json:"clusterId,omitempty"`
MigrationID *string `json:"migrationId,omitempty"`
}
type ReadMigrationStatusOutput struct {
MigrationStatus []*MigrationStatus `json:"migrationStatus,omitempty"`
}
func (s *ServiceOp) MigrationStatus(ctx context.Context, input *ReadMigrationStatusInput) (*ReadMigrationStatusOutput, error) {
path, err := uritemplates.Expand("/ocean/aws/k8s/cluster/{oceanClusterId}/migration/{migrationId}", uritemplates.Values{
"oceanClusterId": spotinst.StringValue(input.ClusterID),
"migrationId": spotinst.StringValue(input.MigrationID),
})
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()
gs, err := migrationStatusFromHttpResponse(resp)
if err != nil {
return nil, err
}
return &ReadMigrationStatusOutput{MigrationStatus: gs}, nil
}
func migrationStatusFromHttpResponse(resp *http.Response) ([]*MigrationStatus, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return migrationStatusFromJSON(body)
}
func migrationStatusFromJSON(in []byte) ([]*MigrationStatus, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*MigrationStatus, len(rw.Response.Items))
if len(out) == 0 {
return out, nil
}
for i, rb := range rw.Response.Items {
b, err := statusFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}
return out, nil
}
func statusFromJSON(in []byte) (*MigrationStatus, error) {
b := new(MigrationStatus)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}

View File

@ -0,0 +1,97 @@
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/uritemplates"
"io/ioutil"
"net/http"
)
type Migration struct {
ID *string `json:"Id,omitempty"`
State *string `json:"state,omitempty"`
CreatedAt *string `json:"createdAt,omitempty"`
CompletedAt *string `json:"completedAt,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 ReadMigrationInput struct {
ClusterID *string `json:"clusterId,omitempty"`
}
type ReadMigrationOutput struct {
Migration []*Migration `json:"migration,omitempty"`
}
func (s *ServiceOp) ListMigrations(ctx context.Context, input *ReadMigrationInput) (*ReadMigrationOutput, error) {
path, err := uritemplates.Expand("/ocean/aws/k8s/cluster/{oceanClusterId}/migration", uritemplates.Values{
"oceanClusterId": spotinst.StringValue(input.ClusterID),
})
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()
gs, err := migrationsFromHttpResponse(resp)
if err != nil {
return nil, err
}
return &ReadMigrationOutput{Migration: gs}, nil
}
func migrationsFromHttpResponse(resp *http.Response) ([]*Migration, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return migrationsFromJSON(body)
}
func migrationsFromJSON(in []byte) ([]*Migration, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*Migration, len(rw.Response.Items))
if len(out) == 0 {
return out, nil
}
for i, rb := range rw.Response.Items {
b, err := migrationFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}
return out, nil
}
func migrationFromJSON(in []byte) (*Migration, error) {
b := new(Migration)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}

View File

@ -52,12 +52,6 @@ type Attribute struct {
nullFields []string
}
// Deprecated: Use ListOceanResourceSuggestionsInput instead.
type ListResourceSuggestionsInput struct {
OceanID *string `json:"oceanId,omitempty"`
Namespace *string `json:"namespace,omitempty"`
}
// Deprecated: Use ListOceanResourceSuggestionsOutput instead.
type ListResourceSuggestionsOutput struct {
Suggestions []*ResourceSuggestion `json:"suggestions,omitempty"`
@ -74,6 +68,12 @@ type ListOceanResourceSuggestionsOutput struct {
Suggestions []*ResourceSuggestion `json:"suggestions,omitempty"`
}
// Deprecated: Use ListOceanResourceSuggestionsInput instead.
type ListResourceSuggestionsInput struct {
OceanID *string `json:"oceanId,omitempty"`
Namespace *string `json:"namespace,omitempty"`
}
func resourceSuggestionFromJSON(in []byte) (*ResourceSuggestion, error) {
b := new(ResourceSuggestion)
if err := json.Unmarshal(in, b); err != nil {

View File

@ -17,7 +17,6 @@ type Service interface {
serviceCommon
serviceExtendedResourceDefinition
}
type serviceKubernetes interface {
ListClusters(context.Context, *ListClustersInput) (*ListClustersOutput, error)
CreateCluster(context.Context, *CreateClusterInput) (*CreateClusterOutput, error)
@ -46,6 +45,14 @@ type serviceKubernetes interface {
Roll(context.Context, *RollClusterInput) (*RollClusterOutput, error)
GetClusterAggregatedCosts(context.Context, *ClusterAggregatedCostInput) (*ClusterAggregatedCostOutput, error)
ReadClusterNodes(context.Context, *ReadClusterNodeInput) (*ReadClusterNodeOutput, error)
ListMigrations(context.Context, *ReadMigrationInput) (*ReadMigrationOutput, error)
MigrationStatus(context.Context, *ReadMigrationStatusInput) (*ReadMigrationStatusOutput, error)
AttachLoadBalancer(context.Context, *AttachLoadbalancerInput) (*AttachLoadbalancerOutput, error)
DetachLoadBalancer(context.Context, *DetachLoadbalancerInput) (*DetachLoadbalancerOutput, error)
}
type serviceECS interface {

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +0,0 @@
package azure
import "github.com/spotinst/spotinst-sdk-go/spotinst/util/jsonutil"
// region Tag
type Tag struct {
Key *string `json:"tagKey,omitempty"`
Value *string `json:"tagValue,omitempty"`
forceSendFields []string
nullFields []string
}
func (o Tag) MarshalJSON() ([]byte, error) {
type noMethod Tag
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Tag) SetKey(v *string) *Tag {
if o.Key = v; o.Key == nil {
o.nullFields = append(o.nullFields, "Key")
}
return o
}
func (o *Tag) SetValue(v *string) *Tag {
if o.Value = v; o.Value == nil {
o.nullFields = append(o.nullFields, "Value")
}
return o
}
// endregion
// region OSDisk
type OSDisk struct {
SizeGB *int `json:"sizeGB,omitempty"`
Type *string `json:"type,omitempty"`
UtilizeEphemeralStorage *bool `json:"utilizeEphemeralStorage,omitempty"`
forceSendFields []string
nullFields []string
}
func (o OSDisk) MarshalJSON() ([]byte, error) {
type noMethod OSDisk
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *OSDisk) SetSizeGB(v *int) *OSDisk {
if o.SizeGB = v; o.SizeGB == nil {
o.nullFields = append(o.nullFields, "SizeGB")
}
return o
}
func (o *OSDisk) SetType(v *string) *OSDisk {
if o.Type = v; o.Type == nil {
o.nullFields = append(o.nullFields, "Type")
}
return o
}
func (o *OSDisk) SetUtilizeEphemeralStorage(v *bool) *OSDisk {
if o.UtilizeEphemeralStorage = v; o.UtilizeEphemeralStorage == nil {
o.nullFields = append(o.nullFields, "UtilizeEphemeralStorage")
}
return o
}
// endregion
// region Label
type Label struct {
Key *string `json:"key,omitempty"`
Value *string `json:"value,omitempty"`
forceSendFields []string
nullFields []string
}
func (o Label) MarshalJSON() ([]byte, error) {
type noMethod Label
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Label) SetKey(v *string) *Label {
if o.Key = v; o.Key == nil {
o.nullFields = append(o.nullFields, "Key")
}
return o
}
func (o *Label) SetValue(v *string) *Label {
if o.Value = v; o.Value == nil {
o.nullFields = append(o.nullFields, "Value")
}
return o
}
// endregion
// region Taint
type Taint struct {
Key *string `json:"key,omitempty"`
Value *string `json:"value,omitempty"`
Effect *string `json:"effect,omitempty"`
forceSendFields []string
nullFields []string
}
func (o Taint) MarshalJSON() ([]byte, error) {
type noMethod Taint
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Taint) SetKey(v *string) *Taint {
if o.Key = v; o.Key == nil {
o.nullFields = append(o.nullFields, "Key")
}
return o
}
func (o *Taint) SetValue(v *string) *Taint {
if o.Value = v; o.Value == nil {
o.nullFields = append(o.nullFields, "Value")
}
return o
}
func (o *Taint) SetEffect(v *string) *Taint {
if o.Effect = v; o.Effect == nil {
o.nullFields = append(o.nullFields, "Effect")
}
return o
}
// endregion

View File

@ -1,446 +0,0 @@
package azure
import (
"context"
"encoding/json"
"io/ioutil"
"net/http"
"time"
"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 VirtualNodeGroup struct {
ID *string `json:"id,omitempty"`
OceanID *string `json:"oceanId,omitempty"`
Name *string `json:"name,omitempty"`
Labels []*Label `json:"labels,omitempty"`
Taints []*Taint `json:"taints,omitempty"`
AutoScale *VirtualNodeGroupAutoScale `json:"autoScale,omitempty"`
ResourceLimits *VirtualNodeGroupResourceLimits `json:"resourceLimits,omitempty"`
LaunchSpecification *VirtualNodeGroupLaunchSpecification `json:"launchSpecification,omitempty"`
Zones []string `json:"zones,omitempty"`
// Read-only fields.
CreatedAt *time.Time `json:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
forceSendFields []string
nullFields []string
}
type VirtualNodeGroupResourceLimits struct {
MaxInstanceCount *int `json:"maxInstanceCount,omitempty"`
forceSendFields []string
nullFields []string
}
type VirtualNodeGroupAutoScale struct {
Headrooms []*VirtualNodeGroupHeadroom `json:"headrooms,omitempty"`
AutoHeadroomPercentage *int `json:"autoHeadroomPercentage,omitempty"`
forceSendFields []string
nullFields []string
}
type VirtualNodeGroupHeadroom struct {
CPUPerUnit *int `json:"cpuPerUnit,omitempty"`
GPUPerUnit *int `json:"gpuPerUnit,omitempty"`
MemoryPerUnit *int `json:"memoryPerUnit,omitempty"`
NumOfUnits *int `json:"numOfUnits,omitempty"`
forceSendFields []string
nullFields []string
}
type VirtualNodeGroupLaunchSpecification struct {
OSDisk *OSDisk `json:"osDisk,omitempty"`
Tags []*Tag `json:"tags,omitempty"`
MaxPods *int `json:"maxPods,omitempty"`
forceSendFields []string
nullFields []string
}
type ListVirtualNodeGroupsInput struct {
OceanID *string `json:"oceanId,omitempty"`
}
type ListVirtualNodeGroupsOutput struct {
VirtualNodeGroups []*VirtualNodeGroup `json:"virtualNodeGroups,omitempty"`
}
type CreateVirtualNodeGroupInput struct {
VirtualNodeGroup *VirtualNodeGroup `json:"virtualNodeGroup,omitempty"`
}
type CreateVirtualNodeGroupOutput struct {
VirtualNodeGroup *VirtualNodeGroup `json:"virtualNodeGroup,omitempty"`
}
type ReadVirtualNodeGroupInput struct {
VirtualNodeGroupID *string `json:"virtualNodeGroupId,omitempty"`
}
type ReadVirtualNodeGroupOutput struct {
VirtualNodeGroup *VirtualNodeGroup `json:"virtualNodeGroup,omitempty"`
}
type UpdateVirtualNodeGroupInput struct {
VirtualNodeGroup *VirtualNodeGroup `json:"virtualNodeGroup,omitempty"`
}
type UpdateVirtualNodeGroupOutput struct {
VirtualNodeGroup *VirtualNodeGroup `json:"virtualNodeGroup,omitempty"`
}
type DeleteVirtualNodeGroupInput struct {
VirtualNodeGroupID *string `json:"virtualNodeGroupId,omitempty"`
}
type DeleteVirtualNodeGroupOutput struct{}
func virtualNodeGroupFromJSON(in []byte) (*VirtualNodeGroup, error) {
b := new(VirtualNodeGroup)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}
func virtualNodeGroupsFromJSON(in []byte) ([]*VirtualNodeGroup, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*VirtualNodeGroup, len(rw.Response.Items))
if len(out) == 0 {
return out, nil
}
for i, rb := range rw.Response.Items {
b, err := virtualNodeGroupFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}
return out, nil
}
func virtualNodeGroupsFromHttpResponse(resp *http.Response) ([]*VirtualNodeGroup, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return virtualNodeGroupsFromJSON(body)
}
func (s *ServiceOp) ListVirtualNodeGroups(ctx context.Context, input *ListVirtualNodeGroupsInput) (*ListVirtualNodeGroupsOutput, error) {
r := client.NewRequest(http.MethodGet, "/ocean/azure/k8s/virtualNodeGroup")
if input.OceanID != nil {
r.Params.Set("oceanId", spotinst.StringValue(input.OceanID))
}
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
vngs, err := virtualNodeGroupsFromHttpResponse(resp)
if err != nil {
return nil, err
}
return &ListVirtualNodeGroupsOutput{VirtualNodeGroups: vngs}, nil
}
func (s *ServiceOp) CreateVirtualNodeGroup(ctx context.Context, input *CreateVirtualNodeGroupInput) (*CreateVirtualNodeGroupOutput, error) {
r := client.NewRequest(http.MethodPost, "/ocean/azure/k8s/virtualNodeGroup")
r.Obj = input
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
vngs, err := virtualNodeGroupsFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(CreateVirtualNodeGroupOutput)
if len(vngs) > 0 {
output.VirtualNodeGroup = vngs[0]
}
return output, nil
}
func (s *ServiceOp) ReadVirtualNodeGroup(ctx context.Context, input *ReadVirtualNodeGroupInput) (*ReadVirtualNodeGroupOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/k8s/virtualNodeGroup/{virtualNodeGroupId}", uritemplates.Values{
"virtualNodeGroupId": spotinst.StringValue(input.VirtualNodeGroupID),
})
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()
vngs, err := virtualNodeGroupsFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(ReadVirtualNodeGroupOutput)
if len(vngs) > 0 {
output.VirtualNodeGroup = vngs[0]
}
return output, nil
}
func (s *ServiceOp) UpdateVirtualNodeGroup(ctx context.Context, input *UpdateVirtualNodeGroupInput) (*UpdateVirtualNodeGroupOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/k8s/virtualNodeGroup/{virtualNodeGroupId}", uritemplates.Values{
"virtualNodeGroupId": spotinst.StringValue(input.VirtualNodeGroup.ID),
})
if err != nil {
return nil, err
}
// We do not need the ID anymore so let's drop it.
input.VirtualNodeGroup.ID = 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()
vngs, err := virtualNodeGroupsFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(UpdateVirtualNodeGroupOutput)
if len(vngs) > 0 {
output.VirtualNodeGroup = vngs[0]
}
return output, nil
}
func (s *ServiceOp) DeleteVirtualNodeGroup(ctx context.Context, input *DeleteVirtualNodeGroupInput) (*DeleteVirtualNodeGroupOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/k8s/virtualNodeGroup/{virtualNodeGroupId}", uritemplates.Values{
"virtualNodeGroupId": spotinst.StringValue(input.VirtualNodeGroupID),
})
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 &DeleteVirtualNodeGroupOutput{}, nil
}
// region VirtualNodeGroup
func (o VirtualNodeGroup) MarshalJSON() ([]byte, error) {
type noMethod VirtualNodeGroup
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *VirtualNodeGroup) SetId(v *string) *VirtualNodeGroup {
if o.ID = v; o.ID == nil {
o.nullFields = append(o.nullFields, "ID")
}
return o
}
func (o *VirtualNodeGroup) SetOceanId(v *string) *VirtualNodeGroup {
if o.OceanID = v; o.OceanID == nil {
o.nullFields = append(o.nullFields, "OceanID")
}
return o
}
func (o *VirtualNodeGroup) SetName(v *string) *VirtualNodeGroup {
if o.Name = v; o.Name == nil {
o.nullFields = append(o.nullFields, "Name")
}
return o
}
func (o *VirtualNodeGroup) SetLabels(v []*Label) *VirtualNodeGroup {
if o.Labels = v; o.Labels == nil {
o.nullFields = append(o.nullFields, "Labels")
}
return o
}
func (o *VirtualNodeGroup) SetTaints(v []*Taint) *VirtualNodeGroup {
if o.Taints = v; o.Taints == nil {
o.nullFields = append(o.nullFields, "Taints")
}
return o
}
func (o *VirtualNodeGroup) SetResourceLimits(v *VirtualNodeGroupResourceLimits) *VirtualNodeGroup {
if o.ResourceLimits = v; o.ResourceLimits == nil {
o.nullFields = append(o.nullFields, "ResourceLimits")
}
return o
}
func (o *VirtualNodeGroup) SetLaunchSpecification(v *VirtualNodeGroupLaunchSpecification) *VirtualNodeGroup {
if o.LaunchSpecification = v; o.LaunchSpecification == nil {
o.nullFields = append(o.nullFields, "LaunchSpecification")
}
return o
}
func (o *VirtualNodeGroup) SetAutoScale(v *VirtualNodeGroupAutoScale) *VirtualNodeGroup {
if o.AutoScale = v; o.AutoScale == nil {
o.nullFields = append(o.nullFields, "AutoScale")
}
return o
}
func (o *VirtualNodeGroup) SetZones(v []string) *VirtualNodeGroup {
if o.Zones = v; o.Zones == nil {
o.nullFields = append(o.nullFields, "Zones")
}
return o
}
// endregion
// region VirtualNodeGroupAutoScale
func (o VirtualNodeGroupAutoScale) MarshalJSON() ([]byte, error) {
type noMethod VirtualNodeGroupAutoScale
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *VirtualNodeGroupAutoScale) SetHeadrooms(v []*VirtualNodeGroupHeadroom) *VirtualNodeGroupAutoScale {
if o.Headrooms = v; o.Headrooms == nil {
o.nullFields = append(o.nullFields, "Headrooms")
}
return o
}
func (o *VirtualNodeGroupAutoScale) SetAutoHeadroomPercentage(v *int) *VirtualNodeGroupAutoScale {
if o.AutoHeadroomPercentage = v; o.AutoHeadroomPercentage == nil {
o.nullFields = append(o.nullFields, "AutoHeadroomPercentage")
}
return o
}
//endregion
// region VirtualNodeGroupHeadroom
func (o VirtualNodeGroupHeadroom) MarshalJSON() ([]byte, error) {
type noMethod VirtualNodeGroupHeadroom
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *VirtualNodeGroupHeadroom) SetCPUPerUnit(v *int) *VirtualNodeGroupHeadroom {
if o.CPUPerUnit = v; o.CPUPerUnit == nil {
o.nullFields = append(o.nullFields, "CPUPerUnit")
}
return o
}
func (o *VirtualNodeGroupHeadroom) SetGPUPerUnit(v *int) *VirtualNodeGroupHeadroom {
if o.GPUPerUnit = v; o.GPUPerUnit == nil {
o.nullFields = append(o.nullFields, "GPUPerUnit")
}
return o
}
func (o *VirtualNodeGroupHeadroom) SetMemoryPerUnit(v *int) *VirtualNodeGroupHeadroom {
if o.MemoryPerUnit = v; o.MemoryPerUnit == nil {
o.nullFields = append(o.nullFields, "MemoryPerUnit")
}
return o
}
func (o *VirtualNodeGroupHeadroom) SetNumOfUnits(v *int) *VirtualNodeGroupHeadroom {
if o.NumOfUnits = v; o.NumOfUnits == nil {
o.nullFields = append(o.nullFields, "NumOfUnits")
}
return o
}
// endregion
// region VirtualNodeGroupResourceLimits
func (o VirtualNodeGroupResourceLimits) MarshalJSON() ([]byte, error) {
type noMethod VirtualNodeGroupResourceLimits
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *VirtualNodeGroupResourceLimits) SetMaxInstanceCount(v *int) *VirtualNodeGroupResourceLimits {
if o.MaxInstanceCount = v; o.MaxInstanceCount == nil {
o.nullFields = append(o.nullFields, "MaxInstanceCount")
}
return o
}
// endregion
// region VirtualNodeGroupLaunchSpecification
func (o VirtualNodeGroupLaunchSpecification) MarshalJSON() ([]byte, error) {
type noMethod VirtualNodeGroupLaunchSpecification
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *VirtualNodeGroupLaunchSpecification) SetOSDisk(v *OSDisk) *VirtualNodeGroupLaunchSpecification {
if o.OSDisk = v; o.OSDisk == nil {
o.nullFields = append(o.nullFields, "OSDisk")
}
return o
}
func (o *VirtualNodeGroupLaunchSpecification) SetTags(v []*Tag) *VirtualNodeGroupLaunchSpecification {
if o.Tags = v; o.Tags == nil {
o.nullFields = append(o.nullFields, "Tags")
}
return o
}
func (o *VirtualNodeGroupLaunchSpecification) SetMaxPods(v *int) *VirtualNodeGroupLaunchSpecification {
if o.MaxPods = v; o.MaxPods == nil {
o.nullFields = append(o.nullFields, "MaxPods")
}
return o
}
// endregion

View File

@ -1,134 +0,0 @@
package azure
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/uritemplates"
)
type Filter struct {
Attribute *Attribute `json:"attribute,omitempty"`
Namespaces []string `json:"namespaces,omitempty"`
forceSendFields []string
nullFields []string
}
type Attribute struct {
Key *string `json:"key,omitempty"`
Operator *string `json:"operator,omitempty"`
Type *string `json:"type,omitempty"`
Value *string `json:"value,omitempty"`
forceSendFields []string
nullFields []string
}
// ResourceSuggestion represents a single resource suggestion.
type ResourceSuggestion struct {
ResourceName *string `json:"resourceName,omitempty"`
ResourceType *string `json:"resourceType,omitempty"`
Namespace *string `json:"namespace,omitempty"`
SuggestedCPU *float64 `json:"suggestedCPU,omitempty"`
RequestedCPU *float64 `json:"requestedCPU,omitempty"`
SuggestedMemory *float64 `json:"suggestedMemory,omitempty"`
RequestedMemory *float64 `json:"requestedMemory,omitempty"`
Containers []*ContainerResourceSuggestion `json:"containers,omitempty"`
}
// ContainerResourceSuggestion represents a resource suggestion for a
// single container.
type ContainerResourceSuggestion struct {
Name *string `json:"name,omitempty"`
SuggestedCPU *float64 `json:"suggestedCpu,omitempty"`
RequestedCPU *float64 `json:"requestedCpu,omitempty"`
SuggestedMemory *float64 `json:"suggestedMemory,omitempty"`
RequestedMemory *float64 `json:"requestedMemory,omitempty"`
}
// ListResourceSuggestionsInput represents the input of `ListResourceSuggestions` function.
type ListResourceSuggestionsInput struct {
OceanID *string `json:"oceanId,omitempty"`
Namespace *string `json:"namespace,omitempty"`
Filter *Filter `json:"filter,omitempty"`
}
// ListResourceSuggestionsOutput represents the output of `ListResourceSuggestions` function.
type ListResourceSuggestionsOutput struct {
Suggestions []*ResourceSuggestion `json:"suggestions,omitempty"`
}
// region Unmarshallers
func resourceSuggestionFromJSON(in []byte) (*ResourceSuggestion, error) {
b := new(ResourceSuggestion)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}
func resourceSuggestionsFromJSON(in []byte) ([]*ResourceSuggestion, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*ResourceSuggestion, len(rw.Response.Items))
for i, rb := range rw.Response.Items {
b, err := resourceSuggestionFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}
return out, nil
}
func resourceSuggestionsFromHTTPResponse(resp *http.Response) ([]*ResourceSuggestion, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return resourceSuggestionsFromJSON(body)
}
// endregion
// region API request
// ListResourceSuggestions returns a list of right-sizing resource suggestions
// for an Ocean cluster.
func (s *ServiceOp) ListResourceSuggestions(ctx context.Context, input *ListResourceSuggestionsInput) (*ListResourceSuggestionsOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/k8s/cluster/{oceanId}/rightSizing/suggestion", uritemplates.Values{
"oceanId": spotinst.StringValue(input.OceanID),
})
if err != nil {
return nil, err
}
r := client.NewRequest(http.MethodPost, path)
// We do NOT need the ID anymore, so let's drop it.
input.OceanID = nil
r.Obj = input
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
rs, err := resourceSuggestionsFromHTTPResponse(resp)
if err != nil {
return nil, err
}
return &ListResourceSuggestionsOutput{Suggestions: rs}, nil
}
//endregion

View File

@ -1,44 +0,0 @@
package azure
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 {
ListClusters(context.Context) (*ListClustersOutput, error)
CreateCluster(context.Context, *CreateClusterInput) (*CreateClusterOutput, error)
ReadCluster(context.Context, *ReadClusterInput) (*ReadClusterOutput, error)
UpdateCluster(context.Context, *UpdateClusterInput) (*UpdateClusterOutput, error)
DeleteCluster(context.Context, *DeleteClusterInput) (*DeleteClusterOutput, error)
ImportCluster(context.Context, *ImportClusterInput) (*ImportClusterOutput, error)
ListVirtualNodeGroups(context.Context, *ListVirtualNodeGroupsInput) (*ListVirtualNodeGroupsOutput, error)
CreateVirtualNodeGroup(context.Context, *CreateVirtualNodeGroupInput) (*CreateVirtualNodeGroupOutput, error)
ReadVirtualNodeGroup(context.Context, *ReadVirtualNodeGroupInput) (*ReadVirtualNodeGroupOutput, error)
UpdateVirtualNodeGroup(context.Context, *UpdateVirtualNodeGroupInput) (*UpdateVirtualNodeGroupOutput, error)
DeleteVirtualNodeGroup(context.Context, *DeleteVirtualNodeGroupInput) (*DeleteVirtualNodeGroupOutput, error)
ListResourceSuggestions(context.Context, *ListResourceSuggestionsInput) (*ListResourceSuggestionsOutput, 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),
}
}

View File

@ -139,6 +139,87 @@ type DeleteClusterInput struct {
type DeleteClusterOutput struct{}
type RollSpec struct {
ID *string `json:"id,omitempty"`
ClusterID *string `json:"clusterId,omitempty"`
Comment *string `json:"comment,omitempty"`
Status *string `json:"status,omitempty"`
BatchSizePercentage *int `json:"batchSizePercentage,omitempty"`
BatchMinHealthyPercentage *int `json:"batchMinHealthyPercentage,omitempty"`
RespectPDB *bool `json:"respectPdb,omitempty"`
NodePoolNames []string `json:"nodePoolNames,omitempty"`
VngIds []string `json:"vngIds,omitempty"`
RespectRestrictScaleDown *bool `json:"respectRestrictScaleDown,omitempty"`
NodeNames []string `json:"nodeNames,omitempty"`
forceSendFields []string
nullFields []string
}
type RollStatus struct {
ID *string `json:"id,omitempty"`
ClusterID *string `json:"oceanId,omitempty"`
Scope *string `json:"scope,omitempty"`
Comment *string `json:"comment,omitempty"`
Status *string `json:"status,omitempty"`
Progress *Progress `json:"progress,omitempty"`
RespectPDB *bool `json:"respectPdb,omitempty"`
RespectRestrictScaleDown *bool `json:"respectRestrictScaleDown,omitempty"`
BatchMinHealthyPercentage *int `json:"batchMinHealthyPercentage,omitempty"`
CurrentBatch *int `json:"currentBatch,omitempty"`
NumOfBatches *int `json:"numOfBatches,omitempty"`
CreatedAt *string `json:"createdAt,omitempty"`
UpdatedAt *string `json:"updatedAt,omitempty"`
}
type Progress struct {
ProgressPercentage *float64 `json:"progressPercentage,omitempty"`
DetailedStatus *RollNodes `json:"detailedStatus,omitempty"`
}
type RollNodes struct {
RollNodes []*NodeStatus `json:"rollNodes,omitempty"`
}
type NodeStatus struct {
NodeName *string `json:"nodeName,omitempty"`
Status *string `json:"status,omitempty"`
}
type CreateRollInput struct {
Roll *RollSpec `json:"roll,omitempty"`
}
type CreateRollOutput struct {
Roll *RollStatus `json:"roll,omitempty"`
}
type ReadRollInput struct {
RollID *string `json:"rollId,omitempty"`
ClusterID *string `json:"clusterId,omitempty"`
}
type ReadRollOutput struct {
Roll *RollStatus `json:"roll,omitempty"`
}
type ListRollsInput struct {
ClusterID *string `json:"clusterId,omitempty"`
}
type ListRollsOutput struct {
Rolls []*RollStatus `json:"rolls,omitempty"`
}
type StopRollInput struct {
ClusterID *string `json:"clusterId,omitempty"`
RollID *string `json:"rollId,omitempty"`
}
type StopRollOutput struct {
Rolls []*RollStatus `json:"rolls,omitempty"`
}
// region Unmarshalls
func clusterFromJSON(in []byte) (*Cluster, error) {
@ -295,7 +376,7 @@ func (s *ServiceOp) UpdateCluster(ctx context.Context, input *UpdateClusterInput
r := client.NewRequest(http.MethodPut, path)
r.Obj = input
input.Cluster.AKS = nil
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
@ -576,12 +657,12 @@ func (o Automatic) MarshalJSON() ([]byte, error) {
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
/*func (o *Automatic) SetIsEnabled(v *bool) *Automatic {
func (o *Automatic) SetIsEnabled(v *bool) *Automatic {
if o.IsEnabled = v; o.IsEnabled == nil {
o.nullFields = append(o.nullFields, "IsEnabled")
}
return o
}*/
}
func (o *Automatic) SetPercentage(v *int) *Automatic {
if o.Percentage = v; o.Percentage == nil {
@ -700,4 +781,185 @@ type ImportClusterOutput struct {
Cluster *Cluster `json:"cluster,omitempty"`
}
type LaunchNewNodesInput struct {
Adjustment *int `json:"adjustment,omitempty"`
ApplicableVmSizes []string `json:"applicableVmSizes,omitempty"`
AvailabilityZones []string `json:"availabilityZones,omitempty"`
MinCoresPerNode *int `json:"minCoresPerNode,omitempty"`
MinMemoryGiBPerNode *float64 `json:"minMemoryGiBPerNode,omitempty"`
OceanId *string `json:"oceanId,omitempty"`
PreferredLifecycle *string `json:"preferredLifecycle,omitempty"`
VngIds []string `json:"vngIds,omitempty"`
}
type LaunchNewNodesOutput struct{}
func (s *ServiceOp) LaunchNewNodes(ctx context.Context,
input *LaunchNewNodesInput) (*LaunchNewNodesOutput, error) {
r := client.NewRequest(http.MethodPut, "/ocean/azure/np/cluster/launchNewNodes")
r.Obj = input
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
return &LaunchNewNodesOutput{}, nil
}
// endregion
func (s *ServiceOp) CreateRoll(ctx context.Context, input *CreateRollInput) (*CreateRollOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/np/cluster/{clusterId}/roll", uritemplates.Values{
"clusterId": spotinst.StringValue(input.Roll.ClusterID),
})
if err != nil {
return nil, err
}
// We do not need the ID anymore so let's drop it.
input.Roll.ClusterID = nil
r := client.NewRequest(http.MethodPost, path)
r.Obj = input.Roll
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
v, err := rollStatusesFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(CreateRollOutput)
if len(v) > 0 {
output.Roll = v[0]
}
return output, nil
}
func (s *ServiceOp) ReadRoll(ctx context.Context, input *ReadRollInput) (*ReadRollOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/np/cluster/{clusterId}/roll/{rollId}", uritemplates.Values{
"clusterId": spotinst.StringValue(input.ClusterID),
"rollId": spotinst.StringValue(input.RollID),
})
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()
v, err := rollStatusesFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(ReadRollOutput)
if len(v) > 0 {
output.Roll = v[0]
}
return output, nil
}
func (s *ServiceOp) ListRolls(ctx context.Context, input *ListRollsInput) (*ListRollsOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/np/cluster/{oceanClusterId}/roll", uritemplates.Values{
"oceanClusterId": spotinst.StringValue(input.ClusterID),
})
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()
v, err := rollStatusesFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(ListRollsOutput)
if len(v) > 0 {
output.Rolls = v
}
return output, nil
}
func (s *ServiceOp) StopRoll(ctx context.Context, input *StopRollInput) (*StopRollOutput, error) {
path, err := uritemplates.Expand("/ocean/azure/np/cluster/{oceanClusterId}/roll/{rollId}/stop", uritemplates.Values{
"oceanClusterId": spotinst.StringValue(input.ClusterID),
"rollId": spotinst.StringValue(input.RollID),
})
if err != nil {
return nil, err
}
r := client.NewRequest(http.MethodPut, path)
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
v, err := rollStatusesFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(StopRollOutput)
if len(v) > 0 {
output.Rolls = v
}
return output, nil
}
func rollStatusesFromHttpResponse(resp *http.Response) ([]*RollStatus, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return rollStatusesFromJSON(body)
}
func rollStatusesFromJSON(in []byte) ([]*RollStatus, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*RollStatus, len(rw.Response.Items))
if len(out) == 0 {
return out, nil
}
for i, rb := range rw.Response.Items {
b, err := rollStatusFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}
return out, nil
}
func rollStatusFromJSON(in []byte) (*RollStatus, error) {
b := new(RollStatus)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}

View File

@ -10,6 +10,10 @@ type NodePoolProperties struct {
OsDiskType *string `json:"osDiskType,omitempty"`
OsType *string `json:"osType,omitempty"`
OsSKU *string `json:"osSKU,omitempty"`
KubernetesVersion *string `json:"kubernetesVersion,omitempty"`
PodSubnetIDs []string `json:"podSubnetIDs,omitempty"`
VnetSubnetIDs []string `json:"vnetSubnetIDs,omitempty"`
LinuxOSConfig *LinuxOSConfig `json:"linuxOSConfig,omitempty"`
forceSendFields []string
nullFields []string
@ -21,6 +25,13 @@ func (o NodePoolProperties) MarshalJSON() ([]byte, error) {
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *NodePoolProperties) SetLinuxOSConfig(v *LinuxOSConfig) *NodePoolProperties {
if o.LinuxOSConfig = v; o.LinuxOSConfig == nil {
o.nullFields = append(o.nullFields, "LinuxOSConfig")
}
return o
}
func (o *NodePoolProperties) SetMaxPodsPerNode(v *int) *NodePoolProperties {
if o.MaxPodsPerNode = v; o.MaxPodsPerNode == nil {
o.nullFields = append(o.nullFields, "MaxPodsPerNode")
@ -63,8 +74,59 @@ func (o *NodePoolProperties) SetOsSKU(v *string) *NodePoolProperties {
return o
}
func (o *NodePoolProperties) SetKubernetesVersion(v *string) *NodePoolProperties {
if o.KubernetesVersion = v; o.KubernetesVersion == nil {
o.nullFields = append(o.nullFields, "KubernetesVersion")
}
return o
}
func (o *NodePoolProperties) SetPodSubnetIDs(v []string) *NodePoolProperties {
if o.PodSubnetIDs = v; o.PodSubnetIDs == nil {
o.nullFields = append(o.nullFields, "PodSubnetIDs")
}
return o
}
func (o *NodePoolProperties) SetVnetSubnetIDs(v []string) *NodePoolProperties {
if o.VnetSubnetIDs = v; o.VnetSubnetIDs == nil {
o.nullFields = append(o.nullFields, "VnetSubnetIDs")
}
return o
}
// endregion
// LinuxOSConfig region
type LinuxOSConfig struct {
Sysctls *Sysctls `json:"sysctls,omitempty"`
forceSendFields []string
nullFields []string
}
func (o *LinuxOSConfig) SetSysctls(v *Sysctls) *LinuxOSConfig {
if o.Sysctls = v; o.Sysctls == nil {
o.nullFields = append(o.nullFields, "Sysctls")
}
return o
}
// Sysctls region
type Sysctls struct {
VmMaxMapCount *int `json:"vmMaxMapCount,omitempty"`
forceSendFields []string
nullFields []string
}
func (o *Sysctls) SetVmMaxMapCount(v *int) *Sysctls {
if o.VmMaxMapCount = v; o.VmMaxMapCount == nil {
o.nullFields = append(o.nullFields, "VmMaxMapCount")
}
return o
}
// NodeCountLimits region
type NodeCountLimits struct {
MinCount *int `json:"minCount,omitempty"`
@ -243,6 +305,7 @@ func (o *Headrooms) SetNumOfUnits(v *int) *Headrooms {
type Scheduling struct {
ShutdownHours *ShutdownHours `json:"shutdownHours,omitempty"`
Tasks []*Tasks `json:"tasks,omitempty"`
forceSendFields []string
nullFields []string
@ -256,6 +319,35 @@ type ShutdownHours struct {
nullFields []string
}
type Tasks struct {
IsEnabled *bool `json:"isEnabled,omitempty"`
TaskType *string `json:"taskType,omitempty"`
CronExpression *string `json:"cronExpression,omitempty"`
Parameters *Parameters `json:"parameters,omitempty"`
forceSendFields []string
nullFields []string
}
type Parameters struct {
ClusterRoll *ParameterClusterRoll `json:"clusterRoll,omitempty"`
forceSendFields []string
nullFields []string
}
type ParameterClusterRoll struct {
BatchSizePercentage *int `json:"batchSizePercentage,omitempty"`
Comment *string `json:"comment,omitempty"`
RespectPdb *bool `json:"respectPdb,omitempty"`
RespectRestrictScaleDown *bool `json:"respectRestrictScaleDown,omitempty"`
BatchMinHealthyPercentage *int `json:"batchMinHealthyPercentage,omitempty"`
VngIds []string `json:"vngIds,omitempty"`
forceSendFields []string
nullFields []string
}
func (o Scheduling) MarshalJSON() ([]byte, error) {
type noMethod Scheduling
raw := noMethod(o)
@ -308,6 +400,14 @@ type Filters struct {
Series []string `json:"series,omitempty"`
Architectures []string `json:"architectures,omitempty"`
ExcludeSeries []string `json:"excludeSeries,omitempty"`
AcceleratedNetworking *string `json:"acceleratedNetworking,omitempty"`
DiskPerformance *string `json:"diskPerformance,omitempty"`
MinGpu *float64 `json:"minGpu,omitempty"`
MaxGpu *float64 `json:"maxGpu,omitempty"`
MinNICs *int `json:"minNICs,omitempty"`
VmTypes []string `json:"vmTypes,omitempty"`
MinDisk *int `json:"minDisk,omitempty"`
GpuTypes []string `json:"gpuTypes,omitempty"`
forceSendFields []string
nullFields []string
@ -385,4 +485,175 @@ func (o *Filters) SetExcludeSeries(v []string) *Filters {
return o
}
func (o *Filters) SetAcceleratedNetworking(v *string) *Filters {
if o.AcceleratedNetworking = v; o.AcceleratedNetworking == nil {
o.nullFields = append(o.nullFields, "AcceleratedNetworking")
}
return o
}
func (o *Filters) SetDiskPerformance(v *string) *Filters {
if o.DiskPerformance = v; o.DiskPerformance == nil {
o.nullFields = append(o.nullFields, "DiskPerformance")
}
return o
}
func (o *Filters) SetMinGpu(v *float64) *Filters {
if o.MinGpu = v; o.MinGpu == nil {
o.nullFields = append(o.nullFields, "MinGpu")
}
return o
}
func (o *Filters) SetMaxGpu(v *float64) *Filters {
if o.MaxGpu = v; o.MaxGpu == nil {
o.nullFields = append(o.nullFields, "MaxGpu")
}
return o
}
func (o *Filters) SetMinNICs(v *int) *Filters {
if o.MinNICs = v; o.MinNICs == nil {
o.nullFields = append(o.nullFields, "MinNICs")
}
return o
}
func (o *Filters) SetVmTypes(v []string) *Filters {
if o.VmTypes = v; o.VmTypes == nil {
o.nullFields = append(o.nullFields, "VmTypes")
}
return o
}
func (o *Filters) SetMinDisk(v *int) *Filters {
if o.MinDisk = v; o.MinDisk == nil {
o.nullFields = append(o.nullFields, "MinDisk")
}
return o
}
func (o *Filters) SetGpuTypes(v []string) *Filters {
if o.GpuTypes = v; o.GpuTypes == nil {
o.nullFields = append(o.nullFields, "GpuTypes")
}
return o
}
//end region
// region Tasks
func (o *Scheduling) SetTasks(v []*Tasks) *Scheduling {
if o.Tasks = v; o.Tasks == nil {
o.nullFields = append(o.nullFields, "Tasks")
}
return o
}
func (o Tasks) MarshalJSON() ([]byte, error) {
type noMethod Tasks
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Tasks) SetIsEnabled(v *bool) *Tasks {
if o.IsEnabled = v; o.IsEnabled == nil {
o.nullFields = append(o.nullFields, "IsEnabled")
}
return o
}
func (o *Tasks) SetTaskType(v *string) *Tasks {
if o.TaskType = v; o.TaskType == nil {
o.nullFields = append(o.nullFields, "Type")
}
return o
}
func (o *Tasks) SetCronExpression(v *string) *Tasks {
if o.CronExpression = v; o.CronExpression == nil {
o.nullFields = append(o.nullFields, "CronExpression")
}
return o
}
// endregion
// region Parameters
func (o Parameters) MarshalJSON() ([]byte, error) {
type noMethod Parameters
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Tasks) SetParameters(v *Parameters) *Tasks {
if o.Parameters = v; o.Parameters == nil {
o.nullFields = append(o.nullFields, "Parameter")
}
return o
}
// endregion
// region ClusterRoll
func (o *Parameters) SetClusterRoll(v *ParameterClusterRoll) *Parameters {
if o.ClusterRoll = v; o.ClusterRoll == nil {
o.nullFields = append(o.nullFields, "ClusterRoll")
}
return o
}
func (o ParameterClusterRoll) MarshalJSON() ([]byte, error) {
type noMethod ParameterClusterRoll
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
// endregion
// region ParameterClusterRoll
func (o *ParameterClusterRoll) SetBatchSizePercentage(v *int) *ParameterClusterRoll {
if o.BatchSizePercentage = v; o.BatchSizePercentage == nil {
o.nullFields = append(o.nullFields, "BatchSizePercentage")
}
return o
}
func (o *ParameterClusterRoll) SetComment(v *string) *ParameterClusterRoll {
if o.Comment = v; o.Comment == nil {
o.nullFields = append(o.nullFields, "Comment")
}
return o
}
func (o *ParameterClusterRoll) SetRespectPdb(v *bool) *ParameterClusterRoll {
if o.RespectPdb = v; o.RespectPdb == nil {
o.nullFields = append(o.nullFields, "RespectPdb")
}
return o
}
func (o *ParameterClusterRoll) SetRespectRestrictScaleDown(v *bool) *ParameterClusterRoll {
if o.RespectRestrictScaleDown = v; o.RespectRestrictScaleDown == nil {
o.nullFields = append(o.nullFields, "RespectRestrictScaleDown")
}
return o
}
func (o *ParameterClusterRoll) SetBatchMinHealthyPercentage(v *int) *ParameterClusterRoll {
if o.BatchMinHealthyPercentage = v; o.BatchMinHealthyPercentage == nil {
o.nullFields = append(o.nullFields, "BatchMinHealthyPercentage")
}
return o
}
func (o *ParameterClusterRoll) SetVngIds(v []string) *ParameterClusterRoll {
if o.VngIds = v; o.VngIds == nil {
o.nullFields = append(o.nullFields, "VngIds")
}
return o
}
// endregion

View File

@ -17,12 +17,17 @@ type Service interface {
UpdateCluster(context.Context, *UpdateClusterInput) (*UpdateClusterOutput, error)
DeleteCluster(context.Context, *DeleteClusterInput) (*DeleteClusterOutput, error)
ImportCluster(context.Context, *ImportClusterInput) (*ImportClusterOutput, error)
CreateRoll(context.Context, *CreateRollInput) (*CreateRollOutput, error)
ReadRoll(ctx context.Context, input *ReadRollInput) (*ReadRollOutput, error)
ListRolls(ctx context.Context, input *ListRollsInput) (*ListRollsOutput, error)
StopRoll(ctx context.Context, input *StopRollInput) (*StopRollOutput, error)
ListVirtualNodeGroups(context.Context, *ListVirtualNodeGroupsInput) (*ListVirtualNodeGroupsOutput, error)
CreateVirtualNodeGroup(context.Context, *CreateVirtualNodeGroupInput) (*CreateVirtualNodeGroupOutput, error)
ReadVirtualNodeGroup(context.Context, *ReadVirtualNodeGroupInput) (*ReadVirtualNodeGroupOutput, error)
UpdateVirtualNodeGroup(context.Context, *UpdateVirtualNodeGroupInput) (*UpdateVirtualNodeGroupOutput, error)
DeleteVirtualNodeGroup(context.Context, *DeleteVirtualNodeGroupInput) (*DeleteVirtualNodeGroupOutput, error)
LaunchNewNodes(context.Context, *LaunchNewNodesInput) (*LaunchNewNodesOutput, error)
}
type ServiceOp struct {

View File

@ -49,6 +49,7 @@ type Strategy struct {
DrainingTimeout *int `json:"drainingTimeout,omitempty"`
ProvisioningModel *string `json:"provisioningModel,omitempty"`
PreemptiblePercentage *int `json:"preemptiblePercentage,omitempty"`
ShouldUtilizeCommitments *bool `json:"shouldUtilizeCommitments,omitempty"`
forceSendFields []string
nullFields []string
@ -877,6 +878,13 @@ func (o *Strategy) SetPreemptiblePercentage(v *int) *Strategy {
return o
}
func (o *Strategy) SetShouldUtilizeCommitments(v *bool) *Strategy {
if o.ShouldUtilizeCommitments = v; o.ShouldUtilizeCommitments == nil {
o.nullFields = append(o.nullFields, "ShouldUtilizeCommitments")
}
return o
}
// endregion
// region Compute

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"io/ioutil"
"net/http"
"strconv"
"github.com/spotinst/spotinst-sdk-go/spotinst"
"github.com/spotinst/spotinst-sdk-go/spotinst/client"
@ -185,6 +186,7 @@ type ListLaunchSpecsOutput struct {
type CreateLaunchSpecInput struct {
LaunchSpec *LaunchSpec `json:"launchSpec,omitempty"`
InitialNodes *int `json:"-"`
}
type CreateLaunchSpecOutput struct {
@ -273,6 +275,10 @@ func (s *ServiceOp) CreateLaunchSpec(ctx context.Context, input *CreateLaunchSpe
r := client.NewRequest(http.MethodPost, "/ocean/gcp/k8s/launchSpec")
r.Obj = input
if input.InitialNodes != nil {
r.Params.Set("initialNodes", strconv.Itoa(spotinst.IntValue(input.InitialNodes)))
}
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err

View File

@ -0,0 +1,675 @@
package right_sizing
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 RightsizingRule struct {
RuleName *string `json:"ruleName,omitempty"`
OceanId *string `json:"oceanId,omitempty"`
RestartReplicas *string `json:"restartReplicas,omitempty"`
ExcludePreliminaryRecommendations *bool `json:"excludePreliminaryRecommendations,omitempty"`
RecommendationApplicationIntervals []*RecommendationApplicationIntervals `json:"recommendationApplicationIntervals,omitempty"`
RecommendationApplicationMinThreshold *RecommendationApplicationMinThreshold `json:"recommendationApplicationMinThreshold,omitempty"`
RecommendationApplicationBoundaries *RecommendationApplicationBoundaries `json:"recommendationApplicationBoundaries,omitempty"`
RecommendationApplicationOverheadValues *RecommendationApplicationOverheadValues `json:"recommendationApplicationOverheadValues,omitempty"`
RecommendationApplicationHPA *RecommendationApplicationHPA `json:"recommendationApplicationHPA,omitempty"`
forceSendFields []string
nullFields []string
}
type RecommendationApplicationIntervals struct {
RepetitionBasis *string `json:"repetitionBasis,omitempty"`
WeeklyRepetitionBasis *WeeklyRepetitionBasis `json:"weeklyRepetitionBasis,omitempty"`
MonthlyRepetitionBasis *MonthlyRepetitionBasis `json:"monthlyRepetitionBasis,omitempty"`
forceSendFields []string
nullFields []string
}
type WeeklyRepetitionBasis struct {
IntervalDays []string `json:"intervalDays,omitempty"`
IntervalHours *IntervalHours `json:"intervalHours,omitempty"`
forceSendFields []string
nullFields []string
}
type MonthlyRepetitionBasis struct {
IntervalMonths []int `json:"intervalMonths,omitempty"`
WeekOfTheMonth []string `json:"weekOfTheMonth,omitempty"`
WeeklyRepetitionBasis *WeeklyRepetitionBasis `json:"weeklyRepetitionBasis,omitempty"`
forceSendFields []string
nullFields []string
}
type IntervalHours struct {
StartTime *string `json:"startTime,omitempty"`
EndTime *string `json:"endTime,omitempty"`
forceSendFields []string
nullFields []string
}
type RecommendationApplicationMinThreshold struct {
CpuPercentage *float64 `json:"cpuPercentage,omitempty"`
MemoryPercentage *float64 `json:"memoryPercentage,omitempty"`
forceSendFields []string
nullFields []string
}
type RecommendationApplicationBoundaries struct {
Cpu *Cpu `json:"cpu,omitempty"`
Memory *Memory `json:"memory,omitempty"`
forceSendFields []string
nullFields []string
}
type Cpu struct {
Min *float64 `json:"min,omitempty"`
Max *float64 `json:"max,omitempty"`
forceSendFields []string
nullFields []string
}
type Memory struct {
Min *int `json:"min,omitempty"`
Max *int `json:"max,omitempty"`
forceSendFields []string
nullFields []string
}
type Label struct {
Key *string `json:"key,omitempty"`
Value *string `json:"value,omitempty"`
forceSendFields []string
nullFields []string
}
type Namespace struct {
NamespaceName *string `json:"namespaceName,omitempty"`
Workloads []*Workload `json:"workloads,omitempty"`
Labels []*Label `json:"labels,omitempty"`
forceSendFields []string
nullFields []string
}
type Workload struct {
Name *string `json:"name,omitempty"`
WorkloadType *string `json:"workloadType,omitempty"`
RegexName *string `json:"regexName,omitempty"`
forceSendFields []string
nullFields []string
}
type RecommendationApplicationOverheadValues struct {
CpuPercentage *float64 `json:"cpuPercentage,omitempty"`
MemoryPercentage *float64 `json:"memoryPercentage,omitempty"`
forceSendFields []string
nullFields []string
}
type RecommendationApplicationHPA struct {
AllowHPARecommendations *bool `json:"allowHPARecommendations,omitempty"`
forceSendFields []string
nullFields []string
}
type ListRightsizingRulesInput struct {
OceanId *string `json:"oceanId,omitempty"`
}
type ListRightsizingRulesOutput struct {
RightsizingRules []*RightsizingRule `json:"rightsizingRule,omitempty"`
}
type RightSizingAttachDetachInput struct {
RuleName *string `json:"ruleName,omitempty"`
OceanId *string `json:"oceanId,omitempty"`
Namespaces []*Namespace `json:"namespaces,omitempty"`
}
type RightSizingAttachDetachOutput struct{}
type ReadRightsizingRuleInput struct {
RuleName *string `json:"ruleName,omitempty"`
OceanId *string `json:"oceanId,omitempty"`
}
type ReadRightsizingRuleOutput struct {
RightsizingRule *RightsizingRule `json:"rightsizingRule,omitempty"`
}
type UpdateRightsizingRuleInput struct {
RuleName *string `json:"ruleName,omitempty"`
RightsizingRule *RightsizingRule `json:"rightsizingRule,omitempty"`
}
type UpdateRightsizingRuleOutput struct {
RightsizingRule *RightsizingRule `json:"rightsizingRule,omitempty"`
}
type DeleteRightsizingRuleInput struct {
RuleNames []string `json:"ruleNames,omitempty"`
OceanId *string `json:"oceanId,omitempty"`
}
type DeleteRightsizingRuleOutput struct{}
type CreateRightsizingRuleInput struct {
RightsizingRule *RightsizingRule `json:"rightsizingRule,omitempty"`
}
type CreateRightsizingRuleOutput struct {
RightsizingRule *RightsizingRule `json:"rightsizingRule,omitempty"`
}
func rightsizingRuleFromJSON(in []byte) (*RightsizingRule, error) {
b := new(RightsizingRule)
if err := json.Unmarshal(in, b); err != nil {
return nil, err
}
return b, nil
}
func rightsizingRulesFromJSON(in []byte) ([]*RightsizingRule, error) {
var rw client.Response
if err := json.Unmarshal(in, &rw); err != nil {
return nil, err
}
out := make([]*RightsizingRule, len(rw.Response.Items))
if len(out) == 0 {
return out, nil
}
for i, rb := range rw.Response.Items {
b, err := rightsizingRuleFromJSON(rb)
if err != nil {
return nil, err
}
out[i] = b
}
return out, nil
}
func rightsizingRulesFromHttpResponse(resp *http.Response) ([]*RightsizingRule, error) {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return rightsizingRulesFromJSON(body)
}
func (s *ServiceOp) ListRightsizingRules(ctx context.Context, input *ListRightsizingRulesInput) (*ListRightsizingRulesOutput, error) {
path, err := uritemplates.Expand("/ocean/{oceanId}/rightSizing/rule", uritemplates.Values{
"oceanId": spotinst.StringValue(input.OceanId),
})
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()
gs, err := rightsizingRulesFromHttpResponse(resp)
if err != nil {
return nil, err
}
return &ListRightsizingRulesOutput{RightsizingRules: gs}, nil
}
func (s *ServiceOp) CreateRightsizingRule(ctx context.Context, input *CreateRightsizingRuleInput) (*CreateRightsizingRuleOutput, error) {
path, err := uritemplates.Expand("/ocean/{oceanId}/rightSizing/rule", uritemplates.Values{
"oceanId": spotinst.StringValue(input.RightsizingRule.OceanId),
})
if err != nil {
return nil, err
}
// We do NOT need the ID anymore, so let's drop it.
input.RightsizingRule.OceanId = nil
r := client.NewRequest(http.MethodPost, path)
r.Obj = input.RightsizingRule
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
gs, err := rightsizingRulesFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(CreateRightsizingRuleOutput)
if len(gs) > 0 {
output.RightsizingRule = gs[0]
}
return output, nil
}
func (s *ServiceOp) ReadRightsizingRule(ctx context.Context, input *ReadRightsizingRuleInput) (*ReadRightsizingRuleOutput, error) {
path, err := uritemplates.Expand("/ocean/{oceanId}/rightSizing/rule/{ruleName}", uritemplates.Values{
"oceanId": spotinst.StringValue(input.OceanId),
"ruleName": spotinst.StringValue(input.RuleName),
})
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()
gs, err := rightsizingRulesFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(ReadRightsizingRuleOutput)
if len(gs) > 0 {
output.RightsizingRule = gs[0]
}
return output, nil
}
func (s *ServiceOp) UpdateRightsizingRule(ctx context.Context, input *UpdateRightsizingRuleInput) (*UpdateRightsizingRuleOutput, error) {
path, err := uritemplates.Expand("/ocean/{oceanId}/rightSizing/rule/{ruleName}", uritemplates.Values{
"oceanId": spotinst.StringValue(input.RightsizingRule.OceanId),
"ruleName": spotinst.StringValue(input.RuleName),
})
if err != nil {
return nil, err
}
input.RightsizingRule.OceanId = nil
r := client.NewRequest(http.MethodPut, path)
r.Obj = input.RightsizingRule
input.RuleName = nil
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
gs, err := rightsizingRulesFromHttpResponse(resp)
if err != nil {
return nil, err
}
output := new(UpdateRightsizingRuleOutput)
if len(gs) > 0 {
output.RightsizingRule = gs[0]
}
return output, nil
}
func (s *ServiceOp) DeleteRightsizingRules(ctx context.Context, input *DeleteRightsizingRuleInput) (*DeleteRightsizingRuleOutput, error) {
path, err := uritemplates.Expand("/ocean/{oceanId}/rightSizing/rule", uritemplates.Values{
"oceanId": spotinst.StringValue(input.OceanId),
})
if err != nil {
return nil, err
}
// We do NOT need the ID anymore, so let's drop it.
input.OceanId = nil
r := client.NewRequest(http.MethodDelete, path)
r.Obj = input
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
return &DeleteRightsizingRuleOutput{}, nil
}
func (s *ServiceOp) AttachRightSizingRule(ctx context.Context, input *RightSizingAttachDetachInput) (*RightSizingAttachDetachOutput, error) {
path, err := uritemplates.Expand("/ocean/{oceanId}/rightSizing/rule/{ruleName}/attachment", uritemplates.Values{
"oceanId": spotinst.StringValue(input.OceanId),
"ruleName": spotinst.StringValue(input.RuleName),
})
r := client.NewRequest(http.MethodPost, path)
input.OceanId = nil
input.RuleName = nil
r.Obj = input
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
return &RightSizingAttachDetachOutput{}, nil
}
func (s *ServiceOp) DetachRightSizingRule(ctx context.Context, input *RightSizingAttachDetachInput) (*RightSizingAttachDetachOutput, error) {
path, err := uritemplates.Expand("/ocean/{oceanId}/rightSizing/rule/{ruleName}/detachment", uritemplates.Values{
"oceanId": spotinst.StringValue(input.OceanId),
"ruleName": spotinst.StringValue(input.RuleName),
})
r := client.NewRequest(http.MethodPost, path)
input.OceanId = nil
input.RuleName = nil
r.Obj = input
resp, err := client.RequireOK(s.Client.Do(ctx, r))
if err != nil {
return nil, err
}
defer resp.Body.Close()
return &RightSizingAttachDetachOutput{}, nil
}
// region RightsizingRule
func (o RightsizingRule) MarshalJSON() ([]byte, error) {
type noMethod RightsizingRule
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *RightsizingRule) SetRuleName(v *string) *RightsizingRule {
if o.RuleName = v; o.RuleName == nil {
o.nullFields = append(o.nullFields, "RuleName")
}
return o
}
func (o *RightsizingRule) SetOceanId(v *string) *RightsizingRule {
if o.OceanId = v; o.OceanId == nil {
o.nullFields = append(o.nullFields, "oceanId")
}
return o
}
func (o *RightsizingRule) SetRestartReplicas(v *string) *RightsizingRule {
if o.RestartReplicas = v; o.RestartReplicas == nil {
o.nullFields = append(o.nullFields, "RestartReplicas")
}
return o
}
func (o *RightsizingRule) SetExcludePreliminaryRecommendations(v *bool) *RightsizingRule {
if o.ExcludePreliminaryRecommendations = v; o.ExcludePreliminaryRecommendations == nil {
o.nullFields = append(o.nullFields, "ExcludePreliminaryRecommendations")
}
return o
}
func (o *RightsizingRule) SetRecommendationApplicationIntervals(v []*RecommendationApplicationIntervals) *RightsizingRule {
if o.RecommendationApplicationIntervals = v; o.RecommendationApplicationIntervals == nil {
o.nullFields = append(o.nullFields, "RecommendationApplicationIntervals")
}
return o
}
func (o *RightsizingRule) SetRecommendationApplicationBoundaries(v *RecommendationApplicationBoundaries) *RightsizingRule {
if o.RecommendationApplicationBoundaries = v; o.RecommendationApplicationBoundaries == nil {
o.nullFields = append(o.nullFields, "RecommendationApplicationBoundaries")
}
return o
}
func (o *RightsizingRule) SetRecommendationApplicationMinThreshold(v *RecommendationApplicationMinThreshold) *RightsizingRule {
if o.RecommendationApplicationMinThreshold = v; o.RecommendationApplicationMinThreshold == nil {
o.nullFields = append(o.nullFields, "RecommendationApplicationMinThreshold")
}
return o
}
func (o *RightsizingRule) SetRecommendationApplicationOverheadValues(v *RecommendationApplicationOverheadValues) *RightsizingRule {
if o.RecommendationApplicationOverheadValues = v; o.RecommendationApplicationOverheadValues == nil {
o.nullFields = append(o.nullFields, "RecommendationApplicationOverheadValues")
}
return o
}
func (o *RightsizingRule) SetRecommendationApplicationHPA(v *RecommendationApplicationHPA) *RightsizingRule {
if o.RecommendationApplicationHPA = v; o.RecommendationApplicationHPA == nil {
o.nullFields = append(o.nullFields, "RecommendationApplicationHPA")
}
return o
}
// region RecommendationApplicationInterval
func (o RecommendationApplicationIntervals) MarshalJSON() ([]byte, error) {
type noMethod RecommendationApplicationIntervals
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *RecommendationApplicationIntervals) SetRepetitionBasis(v *string) *RecommendationApplicationIntervals {
if o.RepetitionBasis = v; o.RepetitionBasis == nil {
o.nullFields = append(o.nullFields, "RepetitionBasis")
}
return o
}
func (o *RecommendationApplicationIntervals) SetWeeklyRepetitionBasis(v *WeeklyRepetitionBasis) *RecommendationApplicationIntervals {
if o.WeeklyRepetitionBasis = v; o.WeeklyRepetitionBasis == nil {
o.nullFields = append(o.nullFields, "WeeklyRepetitionBasis")
}
return o
}
func (o *RecommendationApplicationIntervals) SetMonthlyRepetitionBasis(v *MonthlyRepetitionBasis) *RecommendationApplicationIntervals {
if o.MonthlyRepetitionBasis = v; o.MonthlyRepetitionBasis == nil {
o.nullFields = append(o.nullFields, "MonthlyRepetitionBasis")
}
return o
}
// region WeeklyRepetitionBasis
func (o *WeeklyRepetitionBasis) SetIntervalDays(v []string) *WeeklyRepetitionBasis {
if o.IntervalDays = v; o.IntervalDays == nil {
o.nullFields = append(o.nullFields, "IntervalDays")
}
return o
}
func (o *WeeklyRepetitionBasis) SetIntervalHours(v *IntervalHours) *WeeklyRepetitionBasis {
if o.IntervalHours = v; o.IntervalHours == nil {
o.nullFields = append(o.nullFields, "IntervalHours")
}
return o
}
// region IntervalHours
func (o *IntervalHours) SetStartTime(v *string) *IntervalHours {
if o.StartTime = v; o.StartTime == nil {
o.nullFields = append(o.nullFields, "StartTime")
}
return o
}
func (o *IntervalHours) SetEndTime(v *string) *IntervalHours {
if o.EndTime = v; o.EndTime == nil {
o.nullFields = append(o.nullFields, "EndTime")
}
return o
}
// region MonthlyRepetitionBasis
func (o *MonthlyRepetitionBasis) SetIntervalMonths(v []int) *MonthlyRepetitionBasis {
if o.IntervalMonths = v; o.IntervalMonths == nil {
o.nullFields = append(o.nullFields, "IntervalMonths")
}
return o
}
func (o *MonthlyRepetitionBasis) SetWeekOfTheMonth(v []string) *MonthlyRepetitionBasis {
if o.WeekOfTheMonth = v; o.WeekOfTheMonth == nil {
o.nullFields = append(o.nullFields, "WeekOfTheMonth")
}
return o
}
func (o *MonthlyRepetitionBasis) SetMonthlyWeeklyRepetitionBasis(v *WeeklyRepetitionBasis) *MonthlyRepetitionBasis {
if o.WeeklyRepetitionBasis = v; o.WeeklyRepetitionBasis == nil {
o.nullFields = append(o.nullFields, "WeeklyRepetitionBasis")
}
return o
}
// region RecommendationApplicationBoundaries
func (o RecommendationApplicationBoundaries) MarshalJSON() ([]byte, error) {
type noMethod RecommendationApplicationBoundaries
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *RecommendationApplicationBoundaries) SetCpu(v *Cpu) *RecommendationApplicationBoundaries {
if o.Cpu = v; o.Cpu == nil {
o.nullFields = append(o.nullFields, "Cpu")
}
return o
}
func (o *RecommendationApplicationBoundaries) SetMemory(v *Memory) *RecommendationApplicationBoundaries {
if o.Memory = v; o.Memory == nil {
o.nullFields = append(o.nullFields, "Memory")
}
return o
}
// region Cpu
func (o Cpu) MarshalJSON() ([]byte, error) {
type noMethod Cpu
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Cpu) SetMin(v *float64) *Cpu {
if o.Min = v; o.Min == nil {
o.nullFields = append(o.nullFields, "Cpu")
}
return o
}
func (o *Cpu) SetMax(v *float64) *Cpu {
if o.Max = v; o.Min == nil {
o.nullFields = append(o.nullFields, "Cpu")
}
return o
}
// region Memory
func (o Memory) MarshalJSON() ([]byte, error) {
type noMethod Memory
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *Memory) SetMin(v *int) *Memory {
if o.Min = v; o.Min == nil {
o.nullFields = append(o.nullFields, "Memory")
}
return o
}
func (o *Memory) SetMax(v *int) *Memory {
if o.Max = v; o.Max == nil {
o.nullFields = append(o.nullFields, "Memory")
}
return o
}
// region RecommendationApplicationMinThreshold
func (o RecommendationApplicationMinThreshold) MarshalJSON() ([]byte, error) {
type noMethod RecommendationApplicationMinThreshold
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *RecommendationApplicationMinThreshold) SetCpuPercentage(v *float64) *RecommendationApplicationMinThreshold {
if o.CpuPercentage = v; o.CpuPercentage == nil {
o.nullFields = append(o.nullFields, "CpuPercentage")
}
return o
}
func (o *RecommendationApplicationMinThreshold) SetMemoryPercentage(v *float64) *RecommendationApplicationMinThreshold {
if o.MemoryPercentage = v; o.MemoryPercentage == nil {
o.nullFields = append(o.nullFields, "MemoryPercentage")
}
return o
}
// region RecommendationApplicationOverheadValues
func (o RecommendationApplicationOverheadValues) MarshalJSON() ([]byte, error) {
type noMethod RecommendationApplicationOverheadValues
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *RecommendationApplicationOverheadValues) SetOverheadCpuPercentage(v *float64) *RecommendationApplicationOverheadValues {
if o.CpuPercentage = v; o.CpuPercentage == nil {
o.nullFields = append(o.nullFields, "CpuPercentage")
}
return o
}
func (o *RecommendationApplicationOverheadValues) SetOverheadMemoryPercentage(v *float64) *RecommendationApplicationOverheadValues {
if o.MemoryPercentage = v; o.MemoryPercentage == nil {
o.nullFields = append(o.nullFields, "MemoryPercentage")
}
return o
}
// region RecommendationApplicationHPA
func (o RecommendationApplicationHPA) MarshalJSON() ([]byte, error) {
type noMethod RecommendationApplicationHPA
raw := noMethod(o)
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
}
func (o *RecommendationApplicationHPA) SetAllowHPARecommendations(v *bool) *RecommendationApplicationHPA {
if o.AllowHPARecommendations = v; o.AllowHPARecommendations == nil {
o.nullFields = append(o.nullFields, "AllowHPARecommendations")
}
return o
}

View File

@ -0,0 +1,38 @@
package right_sizing
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 {
CreateRightsizingRule(context.Context, *CreateRightsizingRuleInput) (*CreateRightsizingRuleOutput, error)
ReadRightsizingRule(context.Context, *ReadRightsizingRuleInput) (*ReadRightsizingRuleOutput, error)
ListRightsizingRules(context.Context, *ListRightsizingRulesInput) (*ListRightsizingRulesOutput, error)
UpdateRightsizingRule(context.Context, *UpdateRightsizingRuleInput) (*UpdateRightsizingRuleOutput, error)
DeleteRightsizingRules(context.Context, *DeleteRightsizingRuleInput) (*DeleteRightsizingRuleOutput, error)
AttachRightSizingRule(context.Context, *RightSizingAttachDetachInput) (*RightSizingAttachDetachOutput, error)
DetachRightSizingRule(context.Context, *RightSizingAttachDetachInput) (*RightSizingAttachDetachOutput, 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),
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -1,7 +1,7 @@
package spotinst
// SDKVersion is the current version of the SDK.
const SDKVersion = "1.171.0"
const SDKVersion = "1.372.0"
// SDKName is the name of the SDK.
const SDKName = "spotinst-sdk-go"

7
vendor/modules.txt generated vendored
View File

@ -1112,18 +1112,17 @@ github.com/spf13/viper/internal/encoding/json
github.com/spf13/viper/internal/encoding/toml
github.com/spf13/viper/internal/encoding/yaml
github.com/spf13/viper/internal/features
# github.com/spotinst/spotinst-sdk-go v1.171.0
## explicit; go 1.16
# github.com/spotinst/spotinst-sdk-go v1.372.0
## explicit; go 1.20
github.com/spotinst/spotinst-sdk-go/service/elastigroup
github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/aws
github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure
github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3
github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/gcp
github.com/spotinst/spotinst-sdk-go/service/ocean
github.com/spotinst/spotinst-sdk-go/service/ocean/providers/aws
github.com/spotinst/spotinst-sdk-go/service/ocean/providers/azure
github.com/spotinst/spotinst-sdk-go/service/ocean/providers/azure_np
github.com/spotinst/spotinst-sdk-go/service/ocean/providers/gcp
github.com/spotinst/spotinst-sdk-go/service/ocean/right_sizing
github.com/spotinst/spotinst-sdk-go/service/ocean/spark
github.com/spotinst/spotinst-sdk-go/spotinst
github.com/spotinst/spotinst-sdk-go/spotinst/client