mirror of https://github.com/kubernetes/kops.git
feat(spot/ocean): support for block device mappings in launchspec
This commit is contained in:
parent
de22989eda
commit
dc1ee9402a
4
go.mod
4
go.mod
|
@ -76,8 +76,8 @@ require (
|
|||
github.com/spf13/cobra v1.1.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.7.0
|
||||
github.com/spotinst/spotinst-sdk-go v1.76.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/spotinst/spotinst-sdk-go v1.80.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/weaveworks/mesh v0.0.0-20170419100114-1f158d31de55
|
||||
github.com/zclconf/go-cty v1.3.1
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
|
|
10
go.sum
10
go.sum
|
@ -1006,8 +1006,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
|
|||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spotinst/spotinst-sdk-go v1.76.0 h1:tlFKrUAu7h3FgZM3Xy7436XR5lYo5Q/uePEy0AX5Ydw=
|
||||
github.com/spotinst/spotinst-sdk-go v1.76.0/go.mod h1:sSRVZTSdUAPxeELD/urZkxcfU/DcxO1/UIdOxagqFBc=
|
||||
github.com/spotinst/spotinst-sdk-go v1.80.0 h1:ygqAYGTA2Z/1nlIue1YtXsDGQCv6Lgx3fwO34EIi36E=
|
||||
github.com/spotinst/spotinst-sdk-go v1.80.0/go.mod h1:tJtl0XQCi8YaZnCQfC/y3qHB9OpaxADH/N7EPa0hkt8=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
|
@ -1021,8 +1021,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
|
@ -1561,8 +1562,9 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
|||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
|
|
|
@ -503,9 +503,7 @@ func (b *SpotInstanceGroupModelBuilder) buildOcean(c *fi.ModelBuilderContext, ig
|
|||
}
|
||||
|
||||
func (b *SpotInstanceGroupModelBuilder) buildLaunchSpec(c *fi.ModelBuilderContext,
|
||||
|
||||
ig, igOcean *kops.InstanceGroup, ocean *spotinsttasks.Ocean) (err error) {
|
||||
|
||||
klog.V(4).Infof("Building instance group as LaunchSpec: %q", b.AutoscalingGroupName(ig))
|
||||
launchSpec := &spotinsttasks.LaunchSpec{
|
||||
Name: fi.String(b.AutoscalingGroupName(ig)),
|
||||
|
@ -564,8 +562,6 @@ func (b *SpotInstanceGroupModelBuilder) buildLaunchSpec(c *fi.ModelBuilderContex
|
|||
}
|
||||
if rootVolumeOpts != nil { // remove unsupported options
|
||||
launchSpec.RootVolumeOpts = rootVolumeOpts
|
||||
launchSpec.RootVolumeOpts.Type = nil
|
||||
launchSpec.RootVolumeOpts.IOPS = nil
|
||||
launchSpec.RootVolumeOpts.Optimization = nil
|
||||
}
|
||||
|
||||
|
@ -613,7 +609,6 @@ func (b *SpotInstanceGroupModelBuilder) buildLaunchSpec(c *fi.ModelBuilderContex
|
|||
|
||||
func (b *SpotInstanceGroupModelBuilder) buildSecurityGroups(c *fi.ModelBuilderContext,
|
||||
ig *kops.InstanceGroup) ([]*awstasks.SecurityGroup, error) {
|
||||
|
||||
securityGroups := []*awstasks.SecurityGroup{
|
||||
b.LinkToSecurityGroup(ig.Spec.Role),
|
||||
}
|
||||
|
@ -692,9 +687,7 @@ func (b *SpotInstanceGroupModelBuilder) buildPublicIpOpts(ig *kops.InstanceGroup
|
|||
}
|
||||
|
||||
func (b *SpotInstanceGroupModelBuilder) buildRootVolumeOpts(ig *kops.InstanceGroup) (*spotinsttasks.RootVolumeOpts, error) {
|
||||
opts := &spotinsttasks.RootVolumeOpts{
|
||||
IOPS: ig.Spec.RootVolumeIops,
|
||||
}
|
||||
opts := new(spotinsttasks.RootVolumeOpts)
|
||||
|
||||
// Optimization.
|
||||
{
|
||||
|
@ -713,7 +706,7 @@ func (b *SpotInstanceGroupModelBuilder) buildRootVolumeOpts(ig *kops.InstanceGro
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
opts.Size = fi.Int32(size)
|
||||
opts.Size = fi.Int64(int64(size))
|
||||
}
|
||||
|
||||
// Type.
|
||||
|
@ -725,6 +718,22 @@ func (b *SpotInstanceGroupModelBuilder) buildRootVolumeOpts(ig *kops.InstanceGro
|
|||
opts.Type = fi.String(typ)
|
||||
}
|
||||
|
||||
// IOPS.
|
||||
{
|
||||
iops := fi.Int32Value(ig.Spec.RootVolumeIops)
|
||||
if iops > 0 {
|
||||
opts.IOPS = fi.Int64(int64(iops))
|
||||
}
|
||||
}
|
||||
|
||||
// Throughput.
|
||||
{
|
||||
throughput := fi.Int32Value(ig.Spec.RootVolumeThroughput)
|
||||
if throughput > 0 {
|
||||
opts.Throughput = fi.Int64(int64(throughput))
|
||||
}
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ go_library(
|
|||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/client:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -31,7 +31,6 @@ import (
|
|||
"github.com/spotinst/spotinst-sdk-go/spotinst/client"
|
||||
"github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kops/pkg/resources/spotinst"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
|
@ -76,8 +75,9 @@ type Elastigroup struct {
|
|||
|
||||
type RootVolumeOpts struct {
|
||||
Type *string
|
||||
Size *int32
|
||||
IOPS *int32
|
||||
Size *int64
|
||||
IOPS *int64
|
||||
Throughput *int64
|
||||
Optimization *bool
|
||||
}
|
||||
|
||||
|
@ -284,12 +284,18 @@ func (e *Elastigroup) Find(c *fi.Context) (*Elastigroup, error) {
|
|||
if actual.RootVolumeOpts == nil {
|
||||
actual.RootVolumeOpts = new(RootVolumeOpts)
|
||||
}
|
||||
if b.EBS.IOPS != nil {
|
||||
actual.RootVolumeOpts.IOPS = fi.Int32(int32(fi.IntValue(b.EBS.IOPS)))
|
||||
if b.EBS.VolumeType != nil {
|
||||
actual.RootVolumeOpts.Type = fi.String(strings.ToLower(fi.StringValue(b.EBS.VolumeType)))
|
||||
}
|
||||
if b.EBS.VolumeSize != nil {
|
||||
actual.RootVolumeOpts.Size = fi.Int64(int64(fi.IntValue(b.EBS.VolumeSize)))
|
||||
}
|
||||
if b.EBS.IOPS != nil {
|
||||
actual.RootVolumeOpts.IOPS = fi.Int64(int64(fi.IntValue(b.EBS.IOPS)))
|
||||
}
|
||||
if b.EBS.Throughput != nil {
|
||||
actual.RootVolumeOpts.Throughput = fi.Int64(int64(fi.IntValue(b.EBS.Throughput)))
|
||||
}
|
||||
|
||||
actual.RootVolumeOpts.Type = fi.String(strings.ToLower(fi.StringValue(b.EBS.VolumeType)))
|
||||
actual.RootVolumeOpts.Size = fi.Int32(int32(fi.IntValue(b.EBS.VolumeSize)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -548,28 +554,25 @@ func (_ *Elastigroup) create(cloud awsup.AWSCloud, a, e, changes *Elastigroup) e
|
|||
|
||||
// Block device mappings.
|
||||
{
|
||||
rootDevices, err := e.buildRootDevice(cloud)
|
||||
rootDevice, err := buildRootDevice(cloud, e.RootVolumeOpts, e.ImageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ephemeralDevices, err := e.buildEphemeralDevices(cloud, e.OnDemandInstanceType)
|
||||
mappings := []*aws.BlockDeviceMapping{
|
||||
e.convertBlockDeviceMapping(rootDevice),
|
||||
}
|
||||
|
||||
ephemeralDevices, err := buildEphemeralDevices(cloud, e.OnDemandInstanceType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(rootDevices) != 0 || len(ephemeralDevices) != 0 {
|
||||
var mappings []*aws.BlockDeviceMapping
|
||||
for device, bdm := range rootDevices {
|
||||
mappings = append(mappings, e.buildBlockDeviceMapping(device, bdm))
|
||||
}
|
||||
for device, bdm := range ephemeralDevices {
|
||||
mappings = append(mappings, e.buildBlockDeviceMapping(device, bdm))
|
||||
}
|
||||
if len(mappings) > 0 {
|
||||
group.Compute.LaunchSpecification.SetBlockDeviceMappings(mappings)
|
||||
}
|
||||
for _, bdm := range ephemeralDevices {
|
||||
mappings = append(mappings, e.convertBlockDeviceMapping(bdm))
|
||||
}
|
||||
|
||||
group.Compute.LaunchSpecification.SetBlockDeviceMappings(mappings)
|
||||
}
|
||||
|
||||
// Image.
|
||||
|
@ -1001,40 +1004,36 @@ func (_ *Elastigroup) update(cloud awsup.AWSCloud, a, e, changes *Elastigroup) e
|
|||
// Root volume options.
|
||||
{
|
||||
if opts := changes.RootVolumeOpts; opts != nil {
|
||||
|
||||
// Block device mappings.
|
||||
{
|
||||
if opts.Type != nil || opts.Size != nil || opts.IOPS != nil {
|
||||
rootDevices, err := e.buildRootDevice(cloud)
|
||||
rootDevice, err := buildRootDevice(cloud, opts, e.ImageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ephemeralDevices, err := e.buildEphemeralDevices(cloud, e.OnDemandInstanceType)
|
||||
mappings := []*aws.BlockDeviceMapping{
|
||||
e.convertBlockDeviceMapping(rootDevice),
|
||||
}
|
||||
|
||||
ephemeralDevices, err := buildEphemeralDevices(cloud, e.OnDemandInstanceType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(rootDevices) != 0 || len(ephemeralDevices) != 0 {
|
||||
var mappings []*aws.BlockDeviceMapping
|
||||
for device, bdm := range rootDevices {
|
||||
mappings = append(mappings, e.buildBlockDeviceMapping(device, bdm))
|
||||
}
|
||||
for device, bdm := range ephemeralDevices {
|
||||
mappings = append(mappings, e.buildBlockDeviceMapping(device, bdm))
|
||||
}
|
||||
if len(mappings) > 0 {
|
||||
if group.Compute == nil {
|
||||
group.Compute = new(aws.Compute)
|
||||
}
|
||||
if group.Compute.LaunchSpecification == nil {
|
||||
group.Compute.LaunchSpecification = new(aws.LaunchSpecification)
|
||||
}
|
||||
|
||||
group.Compute.LaunchSpecification.SetBlockDeviceMappings(mappings)
|
||||
changed = true
|
||||
}
|
||||
for _, bdm := range ephemeralDevices {
|
||||
mappings = append(mappings, e.convertBlockDeviceMapping(bdm))
|
||||
}
|
||||
|
||||
if group.Compute == nil {
|
||||
group.Compute = new(aws.Compute)
|
||||
}
|
||||
if group.Compute.LaunchSpecification == nil {
|
||||
group.Compute.LaunchSpecification = new(aws.LaunchSpecification)
|
||||
}
|
||||
|
||||
group.Compute.LaunchSpecification.SetBlockDeviceMappings(mappings)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1379,6 +1378,8 @@ type terraformElastigroupBlockDevice struct {
|
|||
VirtualName *string `json:"virtual_name,omitempty" cty:"virtual_name"`
|
||||
VolumeType *string `json:"volume_type,omitempty" cty:"volume_type"`
|
||||
VolumeSize *int64 `json:"volume_size,omitempty" cty:"volume_size"`
|
||||
VolumeIOPS *int64 `json:"iops,omitempty" cty:"iops"`
|
||||
VolumeThroughput *int64 `json:"throughput,omitempty" cty:"throughput"`
|
||||
DeleteOnTermination *bool `json:"delete_on_termination,omitempty" cty:"delete_on_termination"`
|
||||
}
|
||||
|
||||
|
@ -1556,42 +1557,34 @@ func (_ *Elastigroup) RenderTerraform(t *terraform.TerraformTarget, a, e, change
|
|||
// Root volume options.
|
||||
{
|
||||
if opts := e.RootVolumeOpts; opts != nil {
|
||||
|
||||
// Block device mappings.
|
||||
{
|
||||
rootDevices, err := e.buildRootDevice(t.Cloud.(awsup.AWSCloud))
|
||||
rootDevice, err := buildRootDevice(t.Cloud.(awsup.AWSCloud), e.RootVolumeOpts, e.ImageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ephemeralDevices, err := e.buildEphemeralDevices(cloud, e.OnDemandInstanceType)
|
||||
if err != nil {
|
||||
return err
|
||||
tf.RootBlockDevice = &terraformElastigroupBlockDevice{
|
||||
DeviceName: rootDevice.DeviceName,
|
||||
VolumeType: rootDevice.EbsVolumeType,
|
||||
VolumeSize: rootDevice.EbsVolumeSize,
|
||||
VolumeIOPS: rootDevice.EbsVolumeIops,
|
||||
VolumeThroughput: rootDevice.EbsVolumeThroughput,
|
||||
DeleteOnTermination: fi.Bool(true),
|
||||
}
|
||||
|
||||
if len(rootDevices) != 0 {
|
||||
if len(rootDevices) != 1 {
|
||||
return fmt.Errorf("unexpectedly found multiple root devices")
|
||||
}
|
||||
|
||||
for name, bdm := range rootDevices {
|
||||
tf.RootBlockDevice = &terraformElastigroupBlockDevice{
|
||||
DeviceName: fi.String(name),
|
||||
VolumeType: bdm.EbsVolumeType,
|
||||
VolumeSize: bdm.EbsVolumeSize,
|
||||
DeleteOnTermination: fi.Bool(true),
|
||||
}
|
||||
}
|
||||
ephemeralDevices, err := buildEphemeralDevices(cloud, e.OnDemandInstanceType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(ephemeralDevices) != 0 {
|
||||
tf.EphemeralBlockDevice = []*terraformElastigroupBlockDevice{}
|
||||
for _, deviceName := range sets.StringKeySet(ephemeralDevices).List() {
|
||||
bdm := ephemeralDevices[deviceName]
|
||||
tf.EphemeralBlockDevice = append(tf.EphemeralBlockDevice, &terraformElastigroupBlockDevice{
|
||||
tf.EphemeralBlockDevice = make([]*terraformElastigroupBlockDevice, len(ephemeralDevices))
|
||||
for i, bdm := range ephemeralDevices {
|
||||
tf.EphemeralBlockDevice[i] = &terraformElastigroupBlockDevice{
|
||||
DeviceName: bdm.DeviceName,
|
||||
VirtualName: bdm.VirtualName,
|
||||
DeviceName: fi.String(deviceName),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1696,70 +1689,76 @@ func (e *Elastigroup) buildAutoScaleLabels(labelsMap map[string]string) []*aws.A
|
|||
return labels
|
||||
}
|
||||
|
||||
func (e *Elastigroup) buildEphemeralDevices(c awsup.AWSCloud, instanceTypeName *string) (map[string]*awstasks.BlockDeviceMapping, error) {
|
||||
if instanceTypeName == nil {
|
||||
return nil, fi.RequiredField("InstanceType")
|
||||
}
|
||||
|
||||
instanceType, err := awsup.GetMachineTypeInfo(c, *instanceTypeName)
|
||||
func buildEphemeralDevices(cloud awsup.AWSCloud, machineType *string) ([]*awstasks.BlockDeviceMapping, error) {
|
||||
info, err := awsup.GetMachineTypeInfo(cloud, fi.StringValue(machineType))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
blockDeviceMappings := make(map[string]*awstasks.BlockDeviceMapping)
|
||||
for _, ed := range instanceType.EphemeralDevices() {
|
||||
m := &awstasks.BlockDeviceMapping{
|
||||
bdms := make([]*awstasks.BlockDeviceMapping, len(info.EphemeralDevices()))
|
||||
for i, ed := range info.EphemeralDevices() {
|
||||
bdms[i] = &awstasks.BlockDeviceMapping{
|
||||
DeviceName: fi.String(ed.DeviceName),
|
||||
VirtualName: fi.String(ed.VirtualName),
|
||||
}
|
||||
blockDeviceMappings[ed.DeviceName] = m
|
||||
}
|
||||
|
||||
return blockDeviceMappings, nil
|
||||
return bdms, nil
|
||||
}
|
||||
|
||||
func (e *Elastigroup) buildRootDevice(cloud awsup.AWSCloud) (map[string]*awstasks.BlockDeviceMapping, error) {
|
||||
image, err := resolveImage(cloud, fi.StringValue(e.ImageID))
|
||||
func buildRootDevice(cloud awsup.AWSCloud, volumeOpts *RootVolumeOpts,
|
||||
imageID *string) (*awstasks.BlockDeviceMapping, error) {
|
||||
|
||||
img, err := resolveImage(cloud, fi.StringValue(imageID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rootDeviceName := fi.StringValue(image.RootDeviceName)
|
||||
blockDeviceMappings := make(map[string]*awstasks.BlockDeviceMapping)
|
||||
|
||||
rootDeviceMapping := &awstasks.BlockDeviceMapping{
|
||||
bdm := &awstasks.BlockDeviceMapping{
|
||||
DeviceName: img.RootDeviceName,
|
||||
EbsVolumeSize: volumeOpts.Size,
|
||||
EbsVolumeType: volumeOpts.Type,
|
||||
EbsDeleteOnTermination: fi.Bool(true),
|
||||
EbsVolumeSize: fi.Int64(int64(fi.Int32Value(e.RootVolumeOpts.Size))),
|
||||
EbsVolumeType: e.RootVolumeOpts.Type,
|
||||
}
|
||||
|
||||
// The parameter IOPS is not supported for gp2 volumes.
|
||||
if e.RootVolumeOpts.IOPS != nil && fi.StringValue(e.RootVolumeOpts.Type) != "gp2" {
|
||||
rootDeviceMapping.EbsVolumeIops = fi.Int64(int64(fi.Int32Value(e.RootVolumeOpts.IOPS)))
|
||||
// IOPS is not supported for gp2 volumes.
|
||||
if volumeOpts.IOPS != nil && fi.StringValue(volumeOpts.Type) != "gp2" {
|
||||
bdm.EbsVolumeIops = volumeOpts.IOPS
|
||||
}
|
||||
|
||||
blockDeviceMappings[rootDeviceName] = rootDeviceMapping
|
||||
// Throughput is only supported for gp3 volumes.
|
||||
if volumeOpts.Throughput != nil && fi.StringValue(volumeOpts.Type) == "gp3" {
|
||||
bdm.EbsVolumeThroughput = volumeOpts.Throughput
|
||||
}
|
||||
|
||||
return blockDeviceMappings, nil
|
||||
return bdm, nil
|
||||
}
|
||||
|
||||
func (e *Elastigroup) buildBlockDeviceMapping(deviceName string, i *awstasks.BlockDeviceMapping) *aws.BlockDeviceMapping {
|
||||
o := &aws.BlockDeviceMapping{}
|
||||
o.DeviceName = fi.String(deviceName)
|
||||
o.VirtualName = i.VirtualName
|
||||
func (e *Elastigroup) convertBlockDeviceMapping(in *awstasks.BlockDeviceMapping) *aws.BlockDeviceMapping {
|
||||
out := &aws.BlockDeviceMapping{
|
||||
DeviceName: in.DeviceName,
|
||||
VirtualName: in.VirtualName,
|
||||
}
|
||||
|
||||
if i.EbsDeleteOnTermination != nil || i.EbsVolumeSize != nil || i.EbsVolumeType != nil {
|
||||
o.EBS = &aws.EBS{}
|
||||
o.EBS.DeleteOnTermination = i.EbsDeleteOnTermination
|
||||
o.EBS.VolumeSize = fi.Int(int(fi.Int64Value(i.EbsVolumeSize)))
|
||||
o.EBS.VolumeType = i.EbsVolumeType
|
||||
if in.EbsDeleteOnTermination != nil || in.EbsVolumeSize != nil || in.EbsVolumeType != nil {
|
||||
out.EBS = &aws.EBS{
|
||||
VolumeType: in.EbsVolumeType,
|
||||
VolumeSize: fi.Int(int(fi.Int64Value(in.EbsVolumeSize))),
|
||||
DeleteOnTermination: in.EbsDeleteOnTermination,
|
||||
}
|
||||
|
||||
// The parameter IOPS is not supported for gp2 volumes.
|
||||
if i.EbsVolumeIops != nil && fi.StringValue(i.EbsVolumeType) != "gp2" {
|
||||
o.EBS.IOPS = fi.Int(int(fi.Int64Value(i.EbsVolumeIops)))
|
||||
// IOPS is not valid for gp2 volumes.
|
||||
if in.EbsVolumeIops != nil && fi.StringValue(in.EbsVolumeType) != "gp2" {
|
||||
out.EBS.IOPS = fi.Int(int(fi.Int64Value(in.EbsVolumeIops)))
|
||||
}
|
||||
|
||||
// Throughput is only valid for gp3 volumes.
|
||||
if in.EbsVolumeThroughput != nil && fi.StringValue(in.EbsVolumeType) == "gp3" {
|
||||
out.EBS.Throughput = fi.Int(int(fi.Int64Value(in.EbsVolumeThroughput)))
|
||||
}
|
||||
}
|
||||
|
||||
return o
|
||||
return out
|
||||
}
|
||||
|
||||
func (e *Elastigroup) applyDefaults() {
|
||||
|
|
|
@ -182,9 +182,38 @@ func (o *LaunchSpec) Find(c *fi.Context) (*LaunchSpec, error) {
|
|||
|
||||
// Root volume options.
|
||||
{
|
||||
if spec.RootVolumeSize != nil {
|
||||
actual.RootVolumeOpts = new(RootVolumeOpts)
|
||||
actual.RootVolumeOpts.Size = fi.Int32(int32(*spec.RootVolumeSize))
|
||||
// Volume size.
|
||||
{
|
||||
if spec.RootVolumeSize != nil {
|
||||
actual.RootVolumeOpts = new(RootVolumeOpts)
|
||||
actual.RootVolumeOpts.Size = fi.Int64(int64(*spec.RootVolumeSize))
|
||||
}
|
||||
}
|
||||
|
||||
// Block device mappings.
|
||||
{
|
||||
if spec.BlockDeviceMappings != nil {
|
||||
for _, b := range spec.BlockDeviceMappings {
|
||||
if b.EBS == nil || b.EBS.SnapshotID != nil {
|
||||
continue // not the root
|
||||
}
|
||||
if actual.RootVolumeOpts == nil {
|
||||
actual.RootVolumeOpts = new(RootVolumeOpts)
|
||||
}
|
||||
if b.EBS.VolumeType != nil {
|
||||
actual.RootVolumeOpts.Type = fi.String(strings.ToLower(fi.StringValue(b.EBS.VolumeType)))
|
||||
}
|
||||
if b.EBS.VolumeSize != nil {
|
||||
actual.RootVolumeOpts.Size = fi.Int64(int64(fi.IntValue(b.EBS.VolumeSize)))
|
||||
}
|
||||
if b.EBS.IOPS != nil {
|
||||
actual.RootVolumeOpts.IOPS = fi.Int64(int64(fi.IntValue(b.EBS.IOPS)))
|
||||
}
|
||||
if b.EBS.Throughput != nil {
|
||||
actual.RootVolumeOpts.Throughput = fi.Int64(int64(fi.IntValue(b.EBS.Throughput)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,11 +396,15 @@ func (_ *LaunchSpec) create(cloud awsup.AWSCloud, a, e, changes *LaunchSpec) err
|
|||
// Root volume options.
|
||||
{
|
||||
if opts := e.RootVolumeOpts; opts != nil {
|
||||
|
||||
// Volume size.
|
||||
if opts.Size != nil {
|
||||
spec.SetRootVolumeSize(fi.Int(int(*opts.Size)))
|
||||
rootDevice, err := buildRootDevice(cloud, e.RootVolumeOpts, e.ImageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
spec.SetRootVolumeSize(nil) // mutually exclusive
|
||||
spec.SetBlockDeviceMappings([]*aws.BlockDeviceMapping{
|
||||
e.convertBlockDeviceMapping(rootDevice),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,14 +581,17 @@ func (_ *LaunchSpec) update(cloud awsup.AWSCloud, a, e, changes *LaunchSpec) err
|
|||
// Root volume options.
|
||||
{
|
||||
if opts := changes.RootVolumeOpts; opts != nil {
|
||||
|
||||
// Volume size.
|
||||
if opts.Size != nil {
|
||||
spec.SetRootVolumeSize(fi.Int(int(*opts.Size)))
|
||||
changed = true
|
||||
rootDevice, err := buildRootDevice(cloud, opts, e.ImageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
spec.SetRootVolumeSize(nil) // mutually exclusive
|
||||
spec.SetBlockDeviceMappings([]*aws.BlockDeviceMapping{
|
||||
e.convertBlockDeviceMapping(rootDevice),
|
||||
})
|
||||
changes.RootVolumeOpts = nil
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -743,7 +779,7 @@ type terraformLaunchSpec struct {
|
|||
ImageID *string `json:"image_id,omitempty" cty:"image_id"`
|
||||
AssociatePublicIPAddress *bool `json:"associate_public_ip_address,omitempty" cty:"associate_public_ip_address"`
|
||||
RestrictScaleDown *bool `json:"restrict_scale_down,omitempty" cty:"restrict_scale_down"`
|
||||
RootVolumeSize *int32 `json:"root_volume_size,omitempty" cty:"root_volume_size"`
|
||||
RootVolumeSize *int64 `json:"root_volume_size,omitempty" cty:"root_volume_size"`
|
||||
UserData *terraform.Literal `json:"user_data,omitempty" cty:"user_data"`
|
||||
IAMInstanceProfile *terraform.Literal `json:"iam_instance_profile,omitempty" cty:"iam_instance_profile"`
|
||||
KeyName *terraform.Literal `json:"key_name,omitempty" cty:"key_name"`
|
||||
|
@ -754,6 +790,7 @@ type terraformLaunchSpec struct {
|
|||
Labels []*terraformKV `json:"labels,omitempty" cty:"labels"`
|
||||
Tags []*terraformKV `json:"tags,omitempty" cty:"tags"`
|
||||
Headrooms []*terraformAutoScalerHeadroom `json:"autoscale_headrooms,omitempty" cty:"autoscale_headrooms"`
|
||||
BlockDeviceMappings []*terraformBlockDeviceMapping `json:"block_device_mappings,omitempty" cty:"block_device_mappings"`
|
||||
Strategy *terraformLaunchSpecStrategy `json:"strategy,omitempty" cty:"strategy"`
|
||||
}
|
||||
|
||||
|
@ -761,6 +798,20 @@ type terraformLaunchSpecStrategy struct {
|
|||
SpotPercentage *int64 `json:"spot_percentage,omitempty" cty:"spot_percentage"`
|
||||
}
|
||||
|
||||
type terraformBlockDeviceMapping struct {
|
||||
DeviceName *string `json:"device_name,omitempty" cty:"device_name"`
|
||||
EBS *terraformBlockDeviceMappingEBS `json:"ebs,omitempty" cty:"ebs"`
|
||||
}
|
||||
|
||||
type terraformBlockDeviceMappingEBS struct {
|
||||
VirtualName *string `json:"virtual_name,omitempty" cty:"virtual_name"`
|
||||
VolumeType *string `json:"volume_type,omitempty" cty:"volume_type"`
|
||||
VolumeSize *int64 `json:"volume_size,omitempty" cty:"volume_size"`
|
||||
VolumeIOPS *int64 `json:"iops,omitempty" cty:"iops"`
|
||||
VolumeThroughput *int64 `json:"throughput,omitempty" cty:"throughput"`
|
||||
DeleteOnTermination *bool `json:"delete_on_termination,omitempty" cty:"delete_on_termination"`
|
||||
}
|
||||
|
||||
func (_ *LaunchSpec) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *LaunchSpec) error {
|
||||
cloud := t.Cloud.(awsup.AWSCloud)
|
||||
|
||||
|
@ -840,11 +891,21 @@ func (_ *LaunchSpec) RenderTerraform(t *terraform.TerraformTarget, a, e, changes
|
|||
|
||||
// Root volume options.
|
||||
if opts := e.RootVolumeOpts; opts != nil {
|
||||
|
||||
// Volume size.
|
||||
if opts.Size != nil {
|
||||
tf.RootVolumeSize = opts.Size
|
||||
rootDevice, err := buildRootDevice(t.Cloud.(awsup.AWSCloud), e.RootVolumeOpts, e.ImageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tf.BlockDeviceMappings = append(tf.BlockDeviceMappings, &terraformBlockDeviceMapping{
|
||||
DeviceName: rootDevice.DeviceName,
|
||||
EBS: &terraformBlockDeviceMappingEBS{
|
||||
VolumeType: rootDevice.EbsVolumeType,
|
||||
VolumeSize: rootDevice.EbsVolumeSize,
|
||||
VolumeIOPS: rootDevice.EbsVolumeIops,
|
||||
VolumeThroughput: rootDevice.EbsVolumeThroughput,
|
||||
DeleteOnTermination: fi.Bool(true),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Tags.
|
||||
|
@ -937,3 +998,30 @@ func (o *LaunchSpec) buildTags() []*aws.Tag {
|
|||
|
||||
return tags
|
||||
}
|
||||
|
||||
func (o *LaunchSpec) convertBlockDeviceMapping(in *awstasks.BlockDeviceMapping) *aws.BlockDeviceMapping {
|
||||
out := &aws.BlockDeviceMapping{
|
||||
DeviceName: in.DeviceName,
|
||||
VirtualName: in.VirtualName,
|
||||
}
|
||||
|
||||
if in.EbsDeleteOnTermination != nil || in.EbsVolumeSize != nil || in.EbsVolumeType != nil {
|
||||
out.EBS = &aws.EBS{
|
||||
VolumeType: in.EbsVolumeType,
|
||||
VolumeSize: fi.Int(int(fi.Int64Value(in.EbsVolumeSize))),
|
||||
DeleteOnTermination: in.EbsDeleteOnTermination,
|
||||
}
|
||||
|
||||
// IOPS is not valid for gp2 volumes.
|
||||
if in.EbsVolumeIops != nil && fi.StringValue(in.EbsVolumeType) != "gp2" {
|
||||
out.EBS.IOPS = fi.Int(int(fi.Int64Value(in.EbsVolumeIops)))
|
||||
}
|
||||
|
||||
// Throughput is only valid for gp3 volumes.
|
||||
if in.EbsVolumeThroughput != nil && fi.StringValue(in.EbsVolumeType) == "gp3" {
|
||||
out.EBS.Throughput = fi.Int(int(fi.Int64Value(in.EbsVolumeThroughput)))
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ func (o *Ocean) Find(c *fi.Context) (*Ocean, error) {
|
|||
// Root volume options.
|
||||
if lc.RootVolumeSize != nil {
|
||||
actual.RootVolumeOpts = new(RootVolumeOpts)
|
||||
actual.RootVolumeOpts.Size = fi.Int32(int32(*lc.RootVolumeSize))
|
||||
actual.RootVolumeOpts.Size = fi.Int64(int64(*lc.RootVolumeSize))
|
||||
}
|
||||
|
||||
// Monitoring.
|
||||
|
@ -1034,7 +1034,7 @@ type terraformOcean struct {
|
|||
EBSOptimized *bool `json:"ebs_optimized,omitempty" cty:"ebs_optimized"`
|
||||
ImageID *string `json:"image_id,omitempty" cty:"image_id"`
|
||||
AssociatePublicIPAddress *bool `json:"associate_public_ip_address,omitempty" cty:"associate_public_ip_address"`
|
||||
RootVolumeSize *int32 `json:"root_volume_size,omitempty" cty:"root_volume_size"`
|
||||
RootVolumeSize *int64 `json:"root_volume_size,omitempty" cty:"root_volume_size"`
|
||||
UserData *terraform.Literal `json:"user_data,omitempty" cty:"user_data"`
|
||||
IAMInstanceProfile *terraform.Literal `json:"iam_instance_profile,omitempty" cty:"iam_instance_profile"`
|
||||
KeyName *terraform.Literal `json:"key_name,omitempty" cty:"key_name"`
|
||||
|
|
|
@ -9,6 +9,7 @@ go_library(
|
|||
deps = [
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/aws:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/gcp:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/client:go_default_library",
|
||||
|
|
|
@ -3,6 +3,7 @@ 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"
|
||||
"github.com/spotinst/spotinst-sdk-go/spotinst/client"
|
||||
|
@ -15,6 +16,7 @@ import (
|
|||
type Service interface {
|
||||
CloudProviderAWS() aws.Service
|
||||
CloudProviderAzure() azure.Service
|
||||
CloudProviderAzureV3() azurev3.Service
|
||||
CloudProviderGCP() gcp.Service
|
||||
}
|
||||
|
||||
|
@ -46,6 +48,12 @@ func (s *ServiceOp) CloudProviderAzure() azure.Service {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *ServiceOp) CloudProviderAzureV3() azurev3.Service {
|
||||
return &azurev3.ServiceOp{
|
||||
Client: s.Client,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ServiceOp) CloudProviderGCP() gcp.Service {
|
||||
return &gcp.ServiceOp{
|
||||
Client: s.Client,
|
||||
|
|
55
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/aws/aws.go
generated
vendored
55
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/aws/aws.go
generated
vendored
|
@ -499,6 +499,7 @@ type Strategy struct {
|
|||
RevertToSpot *RevertToSpot `json:"revertToSpot,omitempty"`
|
||||
ScalingStrategy *ScalingStrategy `json:"scalingStrategy,omitempty"`
|
||||
UtilizeCommitments *bool `json:"utilizeCommitments,omitempty"`
|
||||
MinimumInstanceLifetime *int `json:"minimumInstanceLifetime,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
|
@ -618,6 +619,22 @@ type LaunchSpecification struct {
|
|||
NetworkInterfaces []*NetworkInterface `json:"networkInterfaces,omitempty"`
|
||||
Tags []*Tag `json:"tags,omitempty"`
|
||||
MetadataOptions *MetadataOptions `json:"metadataOptions,omitempty"`
|
||||
CPUOptions *CPUOptions `json:"cpuOptions,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type MetadataOptions struct {
|
||||
HTTPTokens *string `json:"httpTokens,omitempty"`
|
||||
HTTPPutResponseHopLimit *int `json:"httpPutResponseHopLimit,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type CPUOptions struct {
|
||||
ThreadsPerCore *int `json:"threadsPerCore,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
|
@ -920,14 +937,6 @@ type StopDeploymentInput struct {
|
|||
|
||||
type StopDeploymentOutput struct{}
|
||||
|
||||
type MetadataOptions struct {
|
||||
HTTPTokens *string `json:"httpTokens,omitempty"`
|
||||
HTTPPutResponseHopLimit *int `json:"httpPutResponseHopLimit,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
func deploymentStatusFromJSON(in []byte) (*RollGroupStatus, error) {
|
||||
b := new(RollGroupStatus)
|
||||
if err := json.Unmarshal(in, b); err != nil {
|
||||
|
@ -3064,6 +3073,13 @@ func (o *Strategy) SetUtilizeCommitments(v *bool) *Strategy {
|
|||
return o
|
||||
}
|
||||
|
||||
func (o *Strategy) SetMinimumInstanceLifetime(v *int) *Strategy {
|
||||
if o.MinimumInstanceLifetime = v; o.MinimumInstanceLifetime == nil {
|
||||
o.nullFields = append(o.nullFields, "MinimumInstanceLifetime")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region ScalingStrategy
|
||||
|
@ -3547,6 +3563,13 @@ func (o *LaunchSpecification) SetMetadataOptions(v *MetadataOptions) *LaunchSpec
|
|||
return o
|
||||
}
|
||||
|
||||
func (o *LaunchSpecification) SetCPUOptions(v *CPUOptions) *LaunchSpecification {
|
||||
if o.CPUOptions = v; o.CPUOptions == nil {
|
||||
o.nullFields = append(o.nullFields, "CPUOptions")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region LoadBalancersConfig
|
||||
|
@ -4313,3 +4336,19 @@ func (o *MetadataOptions) SetHTTPPutResponseHopLimit(v *int) *MetadataOptions {
|
|||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region CPUOptions
|
||||
|
||||
func (o CPUOptions) MarshalJSON() ([]byte, error) {
|
||||
type noMethod CPUOptions
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
func (o *CPUOptions) SetThreadsPerCore(v *int) *CPUOptions {
|
||||
if o.ThreadsPerCore = v; o.ThreadsPerCore == nil {
|
||||
o.nullFields = append(o.nullFields, "ThreadsPerCore")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
|
|
@ -766,7 +766,7 @@ func (s *ServiceOp) List(ctx context.Context, input *ListGroupsInput) (*ListGrou
|
|||
}
|
||||
|
||||
func (s *ServiceOp) Create(ctx context.Context, input *CreateGroupInput) (*CreateGroupOutput, error) {
|
||||
r := client.NewRequest(http.MethodPost, "/compute/azure/group")
|
||||
r := client.NewRequest(http.MethodPost, "/azure/compute/group")
|
||||
r.Obj = input
|
||||
|
||||
resp, err := client.RequireOK(s.Client.Do(ctx, r))
|
||||
|
|
19
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3/BUILD.bazel
generated
vendored
Normal file
19
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3/BUILD.bazel
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"azure.go",
|
||||
"service.go",
|
||||
],
|
||||
importmap = "k8s.io/kops/vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3",
|
||||
importpath = "github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/client:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/session:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/util/jsonutil:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/util/uritemplates:go_default_library",
|
||||
],
|
||||
)
|
774
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3/azure.go
generated
vendored
Normal file
774
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3/azure.go
generated
vendored
Normal file
|
@ -0,0 +1,774 @@
|
|||
package v3
|
||||
|
||||
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 Group struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
ResourceGroupName *string `json:"resourceGroupName,omitempty"`
|
||||
Region *string `json:"region,omitempty"`
|
||||
Capacity *Capacity `json:"capacity,omitempty"`
|
||||
Compute *Compute `json:"compute,omitempty"`
|
||||
Strategy *Strategy `json:"strategy,omitempty"`
|
||||
|
||||
// Read-only fields.
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,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 Strategy struct {
|
||||
OnDemandCount *int `json:"onDemandCount,omitempty"`
|
||||
DrainingTimeout *int `json:"drainingTimeout,omitempty"`
|
||||
SpotPercentage *int `json:"spotPercentage,omitempty"`
|
||||
FallbackToOnDemand *bool `json:"fallbackToOd,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type Capacity struct {
|
||||
Minimum *int `json:"minimum,omitempty"`
|
||||
Maximum *int `json:"maximum,omitempty"`
|
||||
Target *int `json:"target,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type Compute struct {
|
||||
VMSizes *VMSizes `json:"vmSizes,omitempty"`
|
||||
OS *string `json:"os,omitempty"`
|
||||
LaunchSpecification *LaunchSpecification `json:"launchSpecification,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type VMSizes struct {
|
||||
OnDemandSizes []string `json:"odSizes,omitempty"`
|
||||
SpotSizes []string `json:"spotSizes,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type LaunchSpecification struct {
|
||||
Image *Image `json:"image,omitempty"`
|
||||
Network *Network `json:"network,omitempty"`
|
||||
Login *Login `json:"login,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
MarketPlace *MarketPlaceImage `json:"marketplace,omitempty"`
|
||||
Custom *CustomImage `json:"custom,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type MarketPlaceImage struct {
|
||||
Publisher *string `json:"publisher,omitempty"`
|
||||
Offer *string `json:"offer,omitempty"`
|
||||
SKU *string `json:"sku,omitempty"`
|
||||
Version *string `json:"version,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type CustomImage struct {
|
||||
ResourceGroupName *string `json:"resourceGroupName,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
VirtualNetworkName *string `json:"virtualNetworkName,omitempty"`
|
||||
ResourceGroupName *string `json:"resourceGroupName,omitempty"`
|
||||
NetworkInterfaces []*NetworkInterface `json:"networkInterfaces,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type NetworkInterface struct {
|
||||
SubnetName *string `json:"subnetName,omitempty"`
|
||||
AssignPublicIP *bool `json:"assignPublicIp,omitempty"`
|
||||
IsPrimary *bool `json:"isPrimary,omitempty"`
|
||||
AdditionalIPConfigs []*AdditionalIPConfig `json:"additionalIpConfigurations,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type AdditionalIPConfig struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
PrivateIPAddressVersion *string `json:"privateIpAddressVersion,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type Login struct {
|
||||
UserName *string `json:"userName,omitempty"`
|
||||
SSHPublicKey *string `json:"sshPublicKey,omitempty"`
|
||||
Password *string `json:"password,omitempty"`
|
||||
|
||||
forceSendFields []string
|
||||
nullFields []string
|
||||
}
|
||||
|
||||
type CreateGroupInput struct {
|
||||
Group *Group `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type CreateGroupOutput struct {
|
||||
Group *Group `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type ReadGroupInput struct {
|
||||
GroupID *string `json:"groupId,omitempty"`
|
||||
}
|
||||
|
||||
type ReadGroupOutput struct {
|
||||
Group *Group `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateGroupInput struct {
|
||||
Group *Group `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateGroupOutput struct {
|
||||
Group *Group `json:"group,omitempty"`
|
||||
}
|
||||
|
||||
type DeleteGroupInput struct {
|
||||
GroupID *string `json:"groupId,omitempty"`
|
||||
}
|
||||
|
||||
type DeleteGroupOutput struct{}
|
||||
|
||||
type ListGroupsInput struct{}
|
||||
|
||||
type ListGroupsOutput struct {
|
||||
Groups []*Group `json:"groups,omitempty"`
|
||||
}
|
||||
|
||||
// region Unmarshallers
|
||||
|
||||
func groupFromJSON(in []byte) (*Group, error) {
|
||||
b := new(Group)
|
||||
if err := json.Unmarshal(in, b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func groupsFromJSON(in []byte) ([]*Group, error) {
|
||||
var rw client.Response
|
||||
if err := json.Unmarshal(in, &rw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]*Group, len(rw.Response.Items))
|
||||
if len(out) == 0 {
|
||||
return out, nil
|
||||
}
|
||||
for i, rb := range rw.Response.Items {
|
||||
b, err := groupFromJSON(rb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i] = b
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func groupsFromHttpResponse(resp *http.Response) ([]*Group, error) {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return groupsFromJSON(body)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region API requests
|
||||
|
||||
func (s *ServiceOp) List(ctx context.Context, input *ListGroupsInput) (*ListGroupsOutput, error) {
|
||||
r := client.NewRequest(http.MethodGet, "/azure/compute/group")
|
||||
resp, err := client.RequireOK(s.Client.Do(ctx, r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
gs, err := groupsFromHttpResponse(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ListGroupsOutput{Groups: gs}, nil
|
||||
}
|
||||
|
||||
func (s *ServiceOp) Create(ctx context.Context, input *CreateGroupInput) (*CreateGroupOutput, error) {
|
||||
r := client.NewRequest(http.MethodPost, "/azure/compute/group")
|
||||
r.Obj = input
|
||||
|
||||
resp, err := client.RequireOK(s.Client.Do(ctx, r))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
gs, err := groupsFromHttpResponse(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
output := new(CreateGroupOutput)
|
||||
if len(gs) > 0 {
|
||||
output.Group = gs[0]
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s *ServiceOp) Read(ctx context.Context, input *ReadGroupInput) (*ReadGroupOutput, error) {
|
||||
path, err := uritemplates.Expand("/azure/compute/group/{groupId}", uritemplates.Values{
|
||||
"groupId": spotinst.StringValue(input.GroupID),
|
||||
})
|
||||
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 := groupsFromHttpResponse(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
output := new(ReadGroupOutput)
|
||||
if len(gs) > 0 {
|
||||
output.Group = gs[0]
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s *ServiceOp) Update(ctx context.Context, input *UpdateGroupInput) (*UpdateGroupOutput, error) {
|
||||
path, err := uritemplates.Expand("/azure/compute/group/{groupId}", uritemplates.Values{
|
||||
"groupId": spotinst.StringValue(input.Group.ID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We do NOT need the ID anymore, so let's drop it.
|
||||
input.Group.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()
|
||||
|
||||
gs, err := groupsFromHttpResponse(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
output := new(UpdateGroupOutput)
|
||||
if len(gs) > 0 {
|
||||
output.Group = gs[0]
|
||||
}
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (s *ServiceOp) Delete(ctx context.Context, input *DeleteGroupInput) (*DeleteGroupOutput, error) {
|
||||
path, err := uritemplates.Expand("/azure/compute/group/{groupId}", uritemplates.Values{
|
||||
"groupId": spotinst.StringValue(input.GroupID),
|
||||
})
|
||||
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 &DeleteGroupOutput{}, nil
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Group
|
||||
|
||||
func (o Group) MarshalJSON() ([]byte, error) {
|
||||
type noMethod Group
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *Group) SetId(v *string) *Group {
|
||||
if o.ID = v; o.ID == nil {
|
||||
o.nullFields = append(o.nullFields, "ID")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Group) SetName(v *string) *Group {
|
||||
if o.Name = v; o.Name == nil {
|
||||
o.nullFields = append(o.nullFields, "Name")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Group) SetResourceGroupName(v *string) *Group {
|
||||
if o.ResourceGroupName = v; o.ResourceGroupName == nil {
|
||||
o.nullFields = append(o.nullFields, "ResourceGroupName")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Group) SetCapacity(v *Capacity) *Group {
|
||||
if o.Capacity = v; o.Capacity == nil {
|
||||
o.nullFields = append(o.nullFields, "Capacity")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Group) SetCompute(v *Compute) *Group {
|
||||
if o.Compute = v; o.Compute == nil {
|
||||
o.nullFields = append(o.nullFields, "Compute")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Group) SetStrategy(v *Strategy) *Group {
|
||||
if o.Strategy = v; o.Strategy == nil {
|
||||
o.nullFields = append(o.nullFields, "Strategy")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Group) SetRegion(v *string) *Group {
|
||||
if o.Region = v; o.Region == nil {
|
||||
o.nullFields = append(o.nullFields, "Region")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Strategy
|
||||
|
||||
func (o Strategy) MarshalJSON() ([]byte, error) {
|
||||
type noMethod Strategy
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *Strategy) SetOnDemandCount(v *int) *Strategy {
|
||||
if o.OnDemandCount = v; o.OnDemandCount == nil {
|
||||
o.nullFields = append(o.nullFields, "OnDemandCount")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Strategy) SetDrainingTimeout(v *int) *Strategy {
|
||||
if o.DrainingTimeout = v; o.DrainingTimeout == nil {
|
||||
o.nullFields = append(o.nullFields, "DrainingTimeout")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Strategy) SetSpotPercentage(v *int) *Strategy {
|
||||
if o.SpotPercentage = v; o.SpotPercentage == nil {
|
||||
o.nullFields = append(o.nullFields, "SpotPercentage")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Strategy) SetFallbackToOnDemand(v *bool) *Strategy {
|
||||
if o.FallbackToOnDemand = v; o.FallbackToOnDemand == nil {
|
||||
o.nullFields = append(o.nullFields, "FallbackToOnDemand")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Capacity
|
||||
|
||||
func (o Capacity) MarshalJSON() ([]byte, error) {
|
||||
type noMethod Capacity
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *Capacity) SetMinimum(v *int) *Capacity {
|
||||
if o.Minimum = v; o.Minimum == nil {
|
||||
o.nullFields = append(o.nullFields, "Minimum")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Capacity) SetMaximum(v *int) *Capacity {
|
||||
if o.Maximum = v; o.Maximum == nil {
|
||||
o.nullFields = append(o.nullFields, "Maximum")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Capacity) SetTarget(v *int) *Capacity {
|
||||
if o.Target = v; o.Target == nil {
|
||||
o.nullFields = append(o.nullFields, "Target")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Compute
|
||||
|
||||
func (o Compute) MarshalJSON() ([]byte, error) {
|
||||
type noMethod Compute
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *Compute) SetVMSizes(v *VMSizes) *Compute {
|
||||
if o.VMSizes = v; o.VMSizes == nil {
|
||||
o.nullFields = append(o.nullFields, "VMSizes")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Compute) SetOS(v *string) *Compute {
|
||||
if o.OS = v; o.OS == nil {
|
||||
o.nullFields = append(o.nullFields, "OS")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Compute) SetLaunchSpecification(v *LaunchSpecification) *Compute {
|
||||
if o.LaunchSpecification = v; o.LaunchSpecification == nil {
|
||||
o.nullFields = append(o.nullFields, "LaunchSpecification")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region VMSize
|
||||
|
||||
func (o VMSizes) MarshalJSON() ([]byte, error) {
|
||||
type noMethod VMSizes
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *VMSizes) SetOnDemandSizes(v []string) *VMSizes {
|
||||
if o.OnDemandSizes = v; o.OnDemandSizes == nil {
|
||||
o.nullFields = append(o.nullFields, "OnDemandSizes")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *VMSizes) SetSpotSizes(v []string) *VMSizes {
|
||||
if o.SpotSizes = v; o.SpotSizes == nil {
|
||||
o.nullFields = append(o.nullFields, "SpotSizes")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region LaunchSpecification
|
||||
|
||||
func (o LaunchSpecification) MarshalJSON() ([]byte, error) {
|
||||
type noMethod LaunchSpecification
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *LaunchSpecification) SetImage(v *Image) *LaunchSpecification {
|
||||
if o.Image = v; o.Image == nil {
|
||||
o.nullFields = append(o.nullFields, "Image")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *LaunchSpecification) SetNetwork(v *Network) *LaunchSpecification {
|
||||
if o.Network = v; o.Network == nil {
|
||||
o.nullFields = append(o.nullFields, "Network")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *LaunchSpecification) SetLogin(v *Login) *LaunchSpecification {
|
||||
if o.Login = v; o.Login == nil {
|
||||
o.nullFields = append(o.nullFields, "Login")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Image
|
||||
|
||||
func (o Image) MarshalJSON() ([]byte, error) {
|
||||
type noMethod Image
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *Image) SetMarketPlaceImage(v *MarketPlaceImage) *Image {
|
||||
if o.MarketPlace = v; o.MarketPlace == nil {
|
||||
o.nullFields = append(o.nullFields, "MarketPlace")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Image) SetCustom(v *CustomImage) *Image {
|
||||
if o.Custom = v; o.Custom == nil {
|
||||
o.nullFields = append(o.nullFields, "Custom")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region MarketPlaceImage
|
||||
|
||||
func (o MarketPlaceImage) MarshalJSON() ([]byte, error) {
|
||||
type noMethod MarketPlaceImage
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *MarketPlaceImage) SetPublisher(v *string) *MarketPlaceImage {
|
||||
if o.Publisher = v; o.Publisher == nil {
|
||||
o.nullFields = append(o.nullFields, "Publisher")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *MarketPlaceImage) SetOffer(v *string) *MarketPlaceImage {
|
||||
if o.Offer = v; o.Offer == nil {
|
||||
o.nullFields = append(o.nullFields, "Offer")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *MarketPlaceImage) SetSKU(v *string) *MarketPlaceImage {
|
||||
if o.SKU = v; o.SKU == nil {
|
||||
o.nullFields = append(o.nullFields, "SKU")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *MarketPlaceImage) SetVersion(v *string) *MarketPlaceImage {
|
||||
if o.Version = v; o.Version == nil {
|
||||
o.nullFields = append(o.nullFields, "Version")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region CustomImage
|
||||
|
||||
func (o CustomImage) MarshalJSON() ([]byte, error) {
|
||||
type noMethod CustomImage
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *CustomImage) SetResourceGroupName(v *string) *CustomImage {
|
||||
if o.ResourceGroupName = v; o.ResourceGroupName == nil {
|
||||
o.nullFields = append(o.nullFields, "ResourceGroupName")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *CustomImage) SetName(v *string) *CustomImage {
|
||||
if o.Name = v; o.Name == nil {
|
||||
o.nullFields = append(o.nullFields, "Name")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Network
|
||||
|
||||
func (o Network) MarshalJSON() ([]byte, error) {
|
||||
type noMethod Network
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *Network) SetVirtualNetworkName(v *string) *Network {
|
||||
if o.VirtualNetworkName = v; o.VirtualNetworkName == nil {
|
||||
o.nullFields = append(o.nullFields, "VirtualNetworkName")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Network) SetResourceGroupName(v *string) *Network {
|
||||
if o.ResourceGroupName = v; o.ResourceGroupName == nil {
|
||||
o.nullFields = append(o.nullFields, "ResourceGroupName")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Network) SetNetworkInterfaces(v []*NetworkInterface) *Network {
|
||||
if o.NetworkInterfaces = v; o.NetworkInterfaces == nil {
|
||||
o.nullFields = append(o.nullFields, "NetworkInterfaces")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region NetworkInterface
|
||||
|
||||
func (o NetworkInterface) MarshalJSON() ([]byte, error) {
|
||||
type noMethod NetworkInterface
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *NetworkInterface) SetSubnetName(v *string) *NetworkInterface {
|
||||
if o.SubnetName = v; o.SubnetName == nil {
|
||||
o.nullFields = append(o.nullFields, "SubnetName")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *NetworkInterface) SetAdditionalIPConfigs(v []*AdditionalIPConfig) *NetworkInterface {
|
||||
if o.AdditionalIPConfigs = v; o.AdditionalIPConfigs == nil {
|
||||
o.nullFields = append(o.nullFields, "AdditionalIPConfigs")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *NetworkInterface) SetAssignPublicIP(v *bool) *NetworkInterface {
|
||||
if o.AssignPublicIP = v; o.AssignPublicIP == nil {
|
||||
o.nullFields = append(o.nullFields, "AssignPublicIP")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *NetworkInterface) SetIsPrimary(v *bool) *NetworkInterface {
|
||||
if o.IsPrimary = v; o.IsPrimary == nil {
|
||||
o.nullFields = append(o.nullFields, "IsPrimary")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region AdditionalIPConfig
|
||||
|
||||
func (o AdditionalIPConfig) MarshalJSON() ([]byte, error) {
|
||||
type noMethod AdditionalIPConfig
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
// SetName sets the name
|
||||
func (o *AdditionalIPConfig) SetName(v *string) *AdditionalIPConfig {
|
||||
if o.Name = v; o.Name == nil {
|
||||
o.nullFields = append(o.nullFields, "Name")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPrivateIPAddressVersion sets the ip address version
|
||||
func (o *AdditionalIPConfig) SetPrivateIPAddressVersion(v *string) *AdditionalIPConfig {
|
||||
if o.PrivateIPAddressVersion = v; o.PrivateIPAddressVersion == nil {
|
||||
o.nullFields = append(o.nullFields, "PrivateIPAddressVersion")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Login
|
||||
|
||||
func (o Login) MarshalJSON() ([]byte, error) {
|
||||
type noMethod Login
|
||||
raw := noMethod(o)
|
||||
return jsonutil.MarshalJSON(raw, o.forceSendFields, o.nullFields)
|
||||
}
|
||||
|
||||
func (o *Login) SetUserName(v *string) *Login {
|
||||
if o.UserName = v; o.UserName == nil {
|
||||
o.nullFields = append(o.nullFields, "UserName")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Login) SetSSHPublicKey(v *string) *Login {
|
||||
if o.SSHPublicKey = v; o.SSHPublicKey == nil {
|
||||
o.nullFields = append(o.nullFields, "SSHPublicKey")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *Login) SetPassword(v *string) *Login {
|
||||
if o.Password = v; o.Password == nil {
|
||||
o.nullFields = append(o.nullFields, "Password")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
36
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3/service.go
generated
vendored
Normal file
36
vendor/github.com/spotinst/spotinst-sdk-go/service/elastigroup/providers/azure/v3/service.go
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
package v3
|
||||
|
||||
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 {
|
||||
Create(context.Context, *CreateGroupInput) (*CreateGroupOutput, error)
|
||||
Read(context.Context, *ReadGroupInput) (*ReadGroupOutput, error)
|
||||
Update(context.Context, *UpdateGroupInput) (*UpdateGroupOutput, error)
|
||||
Delete(context.Context, *DeleteGroupInput) (*DeleteGroupOutput, error)
|
||||
List(context.Context, *ListGroupsInput) (*ListGroupsOutput, 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),
|
||||
}
|
||||
}
|
|
@ -26,6 +26,7 @@ type ECSLaunchSpec struct {
|
|||
BlockDeviceMappings []*ECSBlockDeviceMapping `json:"blockDeviceMappings,omitempty"`
|
||||
Tags []*Tag `json:"tags,omitempty"`
|
||||
InstanceTypes []string `json:"instanceTypes,omitempty"`
|
||||
RestrictScaleDown *bool `json:"restrictScaleDown,omitempty"`
|
||||
|
||||
// Read-only fields.
|
||||
CreatedAt *time.Time `json:"createdAt,omitempty"`
|
||||
|
@ -397,6 +398,13 @@ func (o *ECSLaunchSpec) SetInstanceTypes(v []string) *ECSLaunchSpec {
|
|||
return o
|
||||
}
|
||||
|
||||
func (o *ECSLaunchSpec) SetRestrictScaleDown(v *bool) *ECSLaunchSpec {
|
||||
if o.RestrictScaleDown = v; o.RestrictScaleDown == nil {
|
||||
o.nullFields = append(o.nullFields, "RestrictScaleDown")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Attributes
|
||||
|
|
22
vendor/github.com/spotinst/spotinst-sdk-go/service/ocean/providers/gcp/launch_spec.go
generated
vendored
22
vendor/github.com/spotinst/spotinst-sdk-go/service/ocean/providers/gcp/launch_spec.go
generated
vendored
|
@ -13,13 +13,14 @@ import (
|
|||
)
|
||||
|
||||
type LaunchSpec struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
OceanID *string `json:"oceanId,omitempty"`
|
||||
SourceImage *string `json:"sourceImage,omitempty"`
|
||||
Metadata []*Metadata `json:"metadata,omitempty"`
|
||||
Labels []*Label `json:"labels,omitempty"`
|
||||
Taints []*Taint `json:"taints,omitempty"`
|
||||
AutoScale *AutoScale `json:"autoScale,omitempty"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
OceanID *string `json:"oceanId,omitempty"`
|
||||
SourceImage *string `json:"sourceImage,omitempty"`
|
||||
Metadata []*Metadata `json:"metadata,omitempty"`
|
||||
Labels []*Label `json:"labels,omitempty"`
|
||||
Taints []*Taint `json:"taints,omitempty"`
|
||||
AutoScale *AutoScale `json:"autoScale,omitempty"`
|
||||
RestrictScaleDown *bool `json:"restrictScaleDown,omitempty"`
|
||||
|
||||
// forceSendFields is a list of field names (e.g. "Keys") to
|
||||
// unconditionally include in API requests. By default, fields with
|
||||
|
@ -356,6 +357,13 @@ func (o *LaunchSpec) SetAutoScale(v *AutoScale) *LaunchSpec {
|
|||
return o
|
||||
}
|
||||
|
||||
func (o *LaunchSpec) SetRestrictScaleDown(v *bool) *LaunchSpec {
|
||||
if o.RestrictScaleDown = v; o.RestrictScaleDown == nil {
|
||||
o.nullFields = append(o.nullFields, "RestrictScaleDown")
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Label
|
||||
|
|
|
@ -14,7 +14,7 @@ go_library(
|
|||
importpath = "github.com/spotinst/spotinst-sdk-go/spotinst/credentials",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/go-ini/ini:go_default_library",
|
||||
"//vendor/github.com/spotinst/spotinst-sdk-go/spotinst/featureflag:go_default_library",
|
||||
"//vendor/gopkg.in/ini.v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
2
vendor/github.com/spotinst/spotinst-sdk-go/spotinst/credentials/provider_file.go
generated
vendored
2
vendor/github.com/spotinst/spotinst-sdk-go/spotinst/credentials/provider_file.go
generated
vendored
|
@ -8,7 +8,7 @@ import (
|
|||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/go-ini/ini"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package spotinst
|
||||
|
||||
// SDKVersion is the current version of the SDK.
|
||||
const SDKVersion = "1.76.0"
|
||||
const SDKVersion = "1.80.0"
|
||||
|
||||
// SDKName is the name of the SDK.
|
||||
const SDKName = "spotinst-sdk-go"
|
||||
|
|
|
@ -6,6 +6,7 @@ go_library(
|
|||
"assertion_compare.go",
|
||||
"assertion_format.go",
|
||||
"assertion_forward.go",
|
||||
"assertion_order.go",
|
||||
"assertions.go",
|
||||
"doc.go",
|
||||
"errors.go",
|
||||
|
|
|
@ -13,12 +13,42 @@ const (
|
|||
compareGreater
|
||||
)
|
||||
|
||||
var (
|
||||
intType = reflect.TypeOf(int(1))
|
||||
int8Type = reflect.TypeOf(int8(1))
|
||||
int16Type = reflect.TypeOf(int16(1))
|
||||
int32Type = reflect.TypeOf(int32(1))
|
||||
int64Type = reflect.TypeOf(int64(1))
|
||||
|
||||
uintType = reflect.TypeOf(uint(1))
|
||||
uint8Type = reflect.TypeOf(uint8(1))
|
||||
uint16Type = reflect.TypeOf(uint16(1))
|
||||
uint32Type = reflect.TypeOf(uint32(1))
|
||||
uint64Type = reflect.TypeOf(uint64(1))
|
||||
|
||||
float32Type = reflect.TypeOf(float32(1))
|
||||
float64Type = reflect.TypeOf(float64(1))
|
||||
|
||||
stringType = reflect.TypeOf("")
|
||||
)
|
||||
|
||||
func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
||||
obj1Value := reflect.ValueOf(obj1)
|
||||
obj2Value := reflect.ValueOf(obj2)
|
||||
|
||||
// throughout this switch we try and avoid calling .Convert() if possible,
|
||||
// as this has a pretty big performance impact
|
||||
switch kind {
|
||||
case reflect.Int:
|
||||
{
|
||||
intobj1 := obj1.(int)
|
||||
intobj2 := obj2.(int)
|
||||
intobj1, ok := obj1.(int)
|
||||
if !ok {
|
||||
intobj1 = obj1Value.Convert(intType).Interface().(int)
|
||||
}
|
||||
intobj2, ok := obj2.(int)
|
||||
if !ok {
|
||||
intobj2 = obj2Value.Convert(intType).Interface().(int)
|
||||
}
|
||||
if intobj1 > intobj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -31,8 +61,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Int8:
|
||||
{
|
||||
int8obj1 := obj1.(int8)
|
||||
int8obj2 := obj2.(int8)
|
||||
int8obj1, ok := obj1.(int8)
|
||||
if !ok {
|
||||
int8obj1 = obj1Value.Convert(int8Type).Interface().(int8)
|
||||
}
|
||||
int8obj2, ok := obj2.(int8)
|
||||
if !ok {
|
||||
int8obj2 = obj2Value.Convert(int8Type).Interface().(int8)
|
||||
}
|
||||
if int8obj1 > int8obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -45,8 +81,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Int16:
|
||||
{
|
||||
int16obj1 := obj1.(int16)
|
||||
int16obj2 := obj2.(int16)
|
||||
int16obj1, ok := obj1.(int16)
|
||||
if !ok {
|
||||
int16obj1 = obj1Value.Convert(int16Type).Interface().(int16)
|
||||
}
|
||||
int16obj2, ok := obj2.(int16)
|
||||
if !ok {
|
||||
int16obj2 = obj2Value.Convert(int16Type).Interface().(int16)
|
||||
}
|
||||
if int16obj1 > int16obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -59,8 +101,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Int32:
|
||||
{
|
||||
int32obj1 := obj1.(int32)
|
||||
int32obj2 := obj2.(int32)
|
||||
int32obj1, ok := obj1.(int32)
|
||||
if !ok {
|
||||
int32obj1 = obj1Value.Convert(int32Type).Interface().(int32)
|
||||
}
|
||||
int32obj2, ok := obj2.(int32)
|
||||
if !ok {
|
||||
int32obj2 = obj2Value.Convert(int32Type).Interface().(int32)
|
||||
}
|
||||
if int32obj1 > int32obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -73,8 +121,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Int64:
|
||||
{
|
||||
int64obj1 := obj1.(int64)
|
||||
int64obj2 := obj2.(int64)
|
||||
int64obj1, ok := obj1.(int64)
|
||||
if !ok {
|
||||
int64obj1 = obj1Value.Convert(int64Type).Interface().(int64)
|
||||
}
|
||||
int64obj2, ok := obj2.(int64)
|
||||
if !ok {
|
||||
int64obj2 = obj2Value.Convert(int64Type).Interface().(int64)
|
||||
}
|
||||
if int64obj1 > int64obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -87,8 +141,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Uint:
|
||||
{
|
||||
uintobj1 := obj1.(uint)
|
||||
uintobj2 := obj2.(uint)
|
||||
uintobj1, ok := obj1.(uint)
|
||||
if !ok {
|
||||
uintobj1 = obj1Value.Convert(uintType).Interface().(uint)
|
||||
}
|
||||
uintobj2, ok := obj2.(uint)
|
||||
if !ok {
|
||||
uintobj2 = obj2Value.Convert(uintType).Interface().(uint)
|
||||
}
|
||||
if uintobj1 > uintobj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -101,8 +161,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Uint8:
|
||||
{
|
||||
uint8obj1 := obj1.(uint8)
|
||||
uint8obj2 := obj2.(uint8)
|
||||
uint8obj1, ok := obj1.(uint8)
|
||||
if !ok {
|
||||
uint8obj1 = obj1Value.Convert(uint8Type).Interface().(uint8)
|
||||
}
|
||||
uint8obj2, ok := obj2.(uint8)
|
||||
if !ok {
|
||||
uint8obj2 = obj2Value.Convert(uint8Type).Interface().(uint8)
|
||||
}
|
||||
if uint8obj1 > uint8obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -115,8 +181,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Uint16:
|
||||
{
|
||||
uint16obj1 := obj1.(uint16)
|
||||
uint16obj2 := obj2.(uint16)
|
||||
uint16obj1, ok := obj1.(uint16)
|
||||
if !ok {
|
||||
uint16obj1 = obj1Value.Convert(uint16Type).Interface().(uint16)
|
||||
}
|
||||
uint16obj2, ok := obj2.(uint16)
|
||||
if !ok {
|
||||
uint16obj2 = obj2Value.Convert(uint16Type).Interface().(uint16)
|
||||
}
|
||||
if uint16obj1 > uint16obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -129,8 +201,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Uint32:
|
||||
{
|
||||
uint32obj1 := obj1.(uint32)
|
||||
uint32obj2 := obj2.(uint32)
|
||||
uint32obj1, ok := obj1.(uint32)
|
||||
if !ok {
|
||||
uint32obj1 = obj1Value.Convert(uint32Type).Interface().(uint32)
|
||||
}
|
||||
uint32obj2, ok := obj2.(uint32)
|
||||
if !ok {
|
||||
uint32obj2 = obj2Value.Convert(uint32Type).Interface().(uint32)
|
||||
}
|
||||
if uint32obj1 > uint32obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -143,8 +221,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Uint64:
|
||||
{
|
||||
uint64obj1 := obj1.(uint64)
|
||||
uint64obj2 := obj2.(uint64)
|
||||
uint64obj1, ok := obj1.(uint64)
|
||||
if !ok {
|
||||
uint64obj1 = obj1Value.Convert(uint64Type).Interface().(uint64)
|
||||
}
|
||||
uint64obj2, ok := obj2.(uint64)
|
||||
if !ok {
|
||||
uint64obj2 = obj2Value.Convert(uint64Type).Interface().(uint64)
|
||||
}
|
||||
if uint64obj1 > uint64obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -157,8 +241,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Float32:
|
||||
{
|
||||
float32obj1 := obj1.(float32)
|
||||
float32obj2 := obj2.(float32)
|
||||
float32obj1, ok := obj1.(float32)
|
||||
if !ok {
|
||||
float32obj1 = obj1Value.Convert(float32Type).Interface().(float32)
|
||||
}
|
||||
float32obj2, ok := obj2.(float32)
|
||||
if !ok {
|
||||
float32obj2 = obj2Value.Convert(float32Type).Interface().(float32)
|
||||
}
|
||||
if float32obj1 > float32obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -171,8 +261,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.Float64:
|
||||
{
|
||||
float64obj1 := obj1.(float64)
|
||||
float64obj2 := obj2.(float64)
|
||||
float64obj1, ok := obj1.(float64)
|
||||
if !ok {
|
||||
float64obj1 = obj1Value.Convert(float64Type).Interface().(float64)
|
||||
}
|
||||
float64obj2, ok := obj2.(float64)
|
||||
if !ok {
|
||||
float64obj2 = obj2Value.Convert(float64Type).Interface().(float64)
|
||||
}
|
||||
if float64obj1 > float64obj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -185,8 +281,14 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
|||
}
|
||||
case reflect.String:
|
||||
{
|
||||
stringobj1 := obj1.(string)
|
||||
stringobj2 := obj2.(string)
|
||||
stringobj1, ok := obj1.(string)
|
||||
if !ok {
|
||||
stringobj1 = obj1Value.Convert(stringType).Interface().(string)
|
||||
}
|
||||
stringobj2, ok := obj2.(string)
|
||||
if !ok {
|
||||
stringobj2 = obj2Value.Convert(stringType).Interface().(string)
|
||||
}
|
||||
if stringobj1 > stringobj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
|
@ -240,6 +342,24 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter
|
|||
return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs)
|
||||
}
|
||||
|
||||
// Positive asserts that the specified element is positive
|
||||
//
|
||||
// assert.Positive(t, 1)
|
||||
// assert.Positive(t, 1.23)
|
||||
func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
zero := reflect.Zero(reflect.TypeOf(e))
|
||||
return compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, "\"%v\" is not positive", msgAndArgs)
|
||||
}
|
||||
|
||||
// Negative asserts that the specified element is negative
|
||||
//
|
||||
// assert.Negative(t, -1)
|
||||
// assert.Negative(t, -1.23)
|
||||
func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
zero := reflect.Zero(reflect.TypeOf(e))
|
||||
return compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, "\"%v\" is not negative", msgAndArgs)
|
||||
}
|
||||
|
||||
func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
|
|
|
@ -114,6 +114,24 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
|||
return Error(t, err, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return ErrorAs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// ErrorIsf asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return ErrorIs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Eventuallyf asserts that given condition will be met in waitFor time,
|
||||
// periodically checking target function each tick.
|
||||
//
|
||||
|
@ -321,6 +339,54 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil
|
|||
return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsDecreasingf asserts that the collection is decreasing
|
||||
//
|
||||
// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsDecreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsIncreasingf asserts that the collection is increasing
|
||||
//
|
||||
// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsIncreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsNonDecreasingf asserts that the collection is not decreasing
|
||||
//
|
||||
// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNonDecreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsNonIncreasingf asserts that the collection is not increasing
|
||||
//
|
||||
// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
|
@ -375,6 +441,17 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args .
|
|||
return LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Negativef asserts that the specified element is negative
|
||||
//
|
||||
// assert.Negativef(t, -1, "error message %s", "formatted")
|
||||
// assert.Negativef(t, -1.23, "error message %s", "formatted")
|
||||
func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Negative(t, e, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Neverf asserts that the given condition doesn't satisfy in waitFor time,
|
||||
// periodically checking the target function each tick.
|
||||
//
|
||||
|
@ -476,6 +553,15 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s
|
|||
return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotErrorIsf asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return NotErrorIs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotNilf asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNilf(t, err, "error message %s", "formatted")
|
||||
|
@ -572,6 +658,17 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str
|
|||
return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Positivef asserts that the specified element is positive
|
||||
//
|
||||
// assert.Positivef(t, 1, "error message %s", "formatted")
|
||||
// assert.Positivef(t, 1.23, "error message %s", "formatted")
|
||||
func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Positive(t, e, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Regexpf asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted")
|
||||
|
|
|
@ -204,6 +204,42 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
|
|||
return Error(a.t, err, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return ErrorAs(a.t, err, target, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return ErrorAsf(a.t, err, target, msg, args...)
|
||||
}
|
||||
|
||||
// ErrorIs asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return ErrorIs(a.t, err, target, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ErrorIsf asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return ErrorIsf(a.t, err, target, msg, args...)
|
||||
}
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
|
@ -631,6 +667,102 @@ func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilo
|
|||
return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
||||
}
|
||||
|
||||
// IsDecreasing asserts that the collection is decreasing
|
||||
//
|
||||
// a.IsDecreasing([]int{2, 1, 0})
|
||||
// a.IsDecreasing([]float{2, 1})
|
||||
// a.IsDecreasing([]string{"b", "a"})
|
||||
func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsDecreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsDecreasingf asserts that the collection is decreasing
|
||||
//
|
||||
// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted")
|
||||
// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted")
|
||||
// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsDecreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsIncreasing asserts that the collection is increasing
|
||||
//
|
||||
// a.IsIncreasing([]int{1, 2, 3})
|
||||
// a.IsIncreasing([]float{1, 2})
|
||||
// a.IsIncreasing([]string{"a", "b"})
|
||||
func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsIncreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsIncreasingf asserts that the collection is increasing
|
||||
//
|
||||
// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted")
|
||||
// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted")
|
||||
// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsIncreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsNonDecreasing asserts that the collection is not decreasing
|
||||
//
|
||||
// a.IsNonDecreasing([]int{1, 1, 2})
|
||||
// a.IsNonDecreasing([]float{1, 2})
|
||||
// a.IsNonDecreasing([]string{"a", "b"})
|
||||
func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNonDecreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonDecreasingf asserts that the collection is not decreasing
|
||||
//
|
||||
// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted")
|
||||
// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted")
|
||||
// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNonDecreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsNonIncreasing asserts that the collection is not increasing
|
||||
//
|
||||
// a.IsNonIncreasing([]int{2, 1, 1})
|
||||
// a.IsNonIncreasing([]float{2, 1})
|
||||
// a.IsNonIncreasing([]string{"b", "a"})
|
||||
func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNonIncreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonIncreasingf asserts that the collection is not increasing
|
||||
//
|
||||
// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted")
|
||||
// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted")
|
||||
// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNonIncreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
|
@ -739,6 +871,28 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i
|
|||
return Lessf(a.t, e1, e2, msg, args...)
|
||||
}
|
||||
|
||||
// Negative asserts that the specified element is negative
|
||||
//
|
||||
// a.Negative(-1)
|
||||
// a.Negative(-1.23)
|
||||
func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Negative(a.t, e, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Negativef asserts that the specified element is negative
|
||||
//
|
||||
// a.Negativef(-1, "error message %s", "formatted")
|
||||
// a.Negativef(-1.23, "error message %s", "formatted")
|
||||
func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Negativef(a.t, e, msg, args...)
|
||||
}
|
||||
|
||||
// Never asserts that the given condition doesn't satisfy in waitFor time,
|
||||
// periodically checking the target function each tick.
|
||||
//
|
||||
|
@ -941,6 +1095,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
|
|||
return NotEqualf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// NotErrorIs asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return NotErrorIs(a.t, err, target, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotErrorIsf asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return NotErrorIsf(a.t, err, target, msg, args...)
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// a.NotNil(err)
|
||||
|
@ -1133,6 +1305,28 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b
|
|||
return Panicsf(a.t, f, msg, args...)
|
||||
}
|
||||
|
||||
// Positive asserts that the specified element is positive
|
||||
//
|
||||
// a.Positive(1)
|
||||
// a.Positive(1.23)
|
||||
func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Positive(a.t, e, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Positivef asserts that the specified element is positive
|
||||
//
|
||||
// a.Positivef(1, "error message %s", "formatted")
|
||||
// a.Positivef(1.23, "error message %s", "formatted")
|
||||
func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return Positivef(a.t, e, msg, args...)
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package assert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// isOrdered checks that collection contains orderable elements.
|
||||
func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {
|
||||
objKind := reflect.TypeOf(object).Kind()
|
||||
if objKind != reflect.Slice && objKind != reflect.Array {
|
||||
return false
|
||||
}
|
||||
|
||||
objValue := reflect.ValueOf(object)
|
||||
objLen := objValue.Len()
|
||||
|
||||
if objLen <= 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
value := objValue.Index(0)
|
||||
valueInterface := value.Interface()
|
||||
firstValueKind := value.Kind()
|
||||
|
||||
for i := 1; i < objLen; i++ {
|
||||
prevValue := value
|
||||
prevValueInterface := valueInterface
|
||||
|
||||
value = objValue.Index(i)
|
||||
valueInterface = value.Interface()
|
||||
|
||||
compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind)
|
||||
|
||||
if !isComparable {
|
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\" and \"%s\"", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !containsValue(allowedComparesResults, compareResult) {
|
||||
return Fail(t, fmt.Sprintf(failMessage, prevValue, value), msgAndArgs...)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// IsIncreasing asserts that the collection is increasing
|
||||
//
|
||||
// assert.IsIncreasing(t, []int{1, 2, 3})
|
||||
// assert.IsIncreasing(t, []float{1, 2})
|
||||
// assert.IsIncreasing(t, []string{"a", "b"})
|
||||
func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs)
|
||||
}
|
||||
|
||||
// IsNonIncreasing asserts that the collection is not increasing
|
||||
//
|
||||
// assert.IsNonIncreasing(t, []int{2, 1, 1})
|
||||
// assert.IsNonIncreasing(t, []float{2, 1})
|
||||
// assert.IsNonIncreasing(t, []string{"b", "a"})
|
||||
func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs)
|
||||
}
|
||||
|
||||
// IsDecreasing asserts that the collection is decreasing
|
||||
//
|
||||
// assert.IsDecreasing(t, []int{2, 1, 0})
|
||||
// assert.IsDecreasing(t, []float{2, 1})
|
||||
// assert.IsDecreasing(t, []string{"b", "a"})
|
||||
func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs)
|
||||
}
|
||||
|
||||
// IsNonDecreasing asserts that the collection is not decreasing
|
||||
//
|
||||
// assert.IsNonDecreasing(t, []int{1, 1, 2})
|
||||
// assert.IsNonDecreasing(t, []float{1, 2})
|
||||
// assert.IsNonDecreasing(t, []string{"a", "b"})
|
||||
func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs)
|
||||
}
|
|
@ -172,8 +172,8 @@ func isTest(name, prefix string) bool {
|
|||
if len(name) == len(prefix) { // "Test" is ok
|
||||
return true
|
||||
}
|
||||
rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
|
||||
return !unicode.IsLower(rune)
|
||||
r, _ := utf8.DecodeRuneInString(name[len(prefix):])
|
||||
return !unicode.IsLower(r)
|
||||
}
|
||||
|
||||
func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
|
||||
|
@ -1622,6 +1622,7 @@ var spewConfig = spew.ConfigState{
|
|||
DisableCapacities: true,
|
||||
SortKeys: true,
|
||||
DisableMethods: true,
|
||||
MaxDepth: 10,
|
||||
}
|
||||
|
||||
type tHelper interface {
|
||||
|
@ -1693,3 +1694,81 @@ func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.D
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ErrorIs asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if errors.Is(err, target) {
|
||||
return true
|
||||
}
|
||||
|
||||
var expectedText string
|
||||
if target != nil {
|
||||
expectedText = target.Error()
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err)
|
||||
|
||||
return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+
|
||||
"expected: %q\n"+
|
||||
"in chain: %s", expectedText, chain,
|
||||
), msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotErrorIs asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if !errors.Is(err, target) {
|
||||
return true
|
||||
}
|
||||
|
||||
var expectedText string
|
||||
if target != nil {
|
||||
expectedText = target.Error()
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err)
|
||||
|
||||
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
|
||||
"found: %q\n"+
|
||||
"in chain: %s", expectedText, chain,
|
||||
), msgAndArgs...)
|
||||
}
|
||||
|
||||
// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if errors.As(err, target) {
|
||||
return true
|
||||
}
|
||||
|
||||
chain := buildErrorChainString(err)
|
||||
|
||||
return Fail(t, fmt.Sprintf("Should be in error chain:\n"+
|
||||
"expected: %q\n"+
|
||||
"in chain: %s", target, chain,
|
||||
), msgAndArgs...)
|
||||
}
|
||||
|
||||
func buildErrorChainString(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
e := errors.Unwrap(err)
|
||||
chain := fmt.Sprintf("%q", err.Error())
|
||||
for e != nil {
|
||||
chain += fmt.Sprintf("\n\t%q", e.Error())
|
||||
e = errors.Unwrap(e)
|
||||
}
|
||||
return chain
|
||||
}
|
||||
|
|
|
@ -256,6 +256,54 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) {
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.ErrorAs(t, err, target, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.ErrorAsf(t, err, target, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// ErrorIs asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.ErrorIs(t, err, target, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// ErrorIsf asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.ErrorIsf(t, err, target, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
|
@ -806,6 +854,126 @@ func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon fl
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsDecreasing asserts that the collection is decreasing
|
||||
//
|
||||
// assert.IsDecreasing(t, []int{2, 1, 0})
|
||||
// assert.IsDecreasing(t, []float{2, 1})
|
||||
// assert.IsDecreasing(t, []string{"b", "a"})
|
||||
func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsDecreasing(t, object, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsDecreasingf asserts that the collection is decreasing
|
||||
//
|
||||
// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsDecreasingf(t, object, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsIncreasing asserts that the collection is increasing
|
||||
//
|
||||
// assert.IsIncreasing(t, []int{1, 2, 3})
|
||||
// assert.IsIncreasing(t, []float{1, 2})
|
||||
// assert.IsIncreasing(t, []string{"a", "b"})
|
||||
func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsIncreasing(t, object, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsIncreasingf asserts that the collection is increasing
|
||||
//
|
||||
// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsIncreasingf(t, object, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsNonDecreasing asserts that the collection is not decreasing
|
||||
//
|
||||
// assert.IsNonDecreasing(t, []int{1, 1, 2})
|
||||
// assert.IsNonDecreasing(t, []float{1, 2})
|
||||
// assert.IsNonDecreasing(t, []string{"a", "b"})
|
||||
func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsNonDecreasing(t, object, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsNonDecreasingf asserts that the collection is not decreasing
|
||||
//
|
||||
// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsNonDecreasingf(t, object, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsNonIncreasing asserts that the collection is not increasing
|
||||
//
|
||||
// assert.IsNonIncreasing(t, []int{2, 1, 1})
|
||||
// assert.IsNonIncreasing(t, []float{2, 1})
|
||||
// assert.IsNonIncreasing(t, []string{"b", "a"})
|
||||
func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsNonIncreasing(t, object, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsNonIncreasingf asserts that the collection is not increasing
|
||||
//
|
||||
// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.IsNonIncreasingf(t, object, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
|
@ -944,6 +1112,34 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
// Negative asserts that the specified element is negative
|
||||
//
|
||||
// assert.Negative(t, -1)
|
||||
// assert.Negative(t, -1.23)
|
||||
func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.Negative(t, e, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Negativef asserts that the specified element is negative
|
||||
//
|
||||
// assert.Negativef(t, -1, "error message %s", "formatted")
|
||||
// assert.Negativef(t, -1.23, "error message %s", "formatted")
|
||||
func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.Negativef(t, e, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Never asserts that the given condition doesn't satisfy in waitFor time,
|
||||
// periodically checking the target function each tick.
|
||||
//
|
||||
|
@ -1200,6 +1396,30 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
// NotErrorIs asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.NotErrorIs(t, err, target, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// NotErrorIsf asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.NotErrorIsf(t, err, target, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNil(t, err)
|
||||
|
@ -1446,6 +1666,34 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}
|
|||
t.FailNow()
|
||||
}
|
||||
|
||||
// Positive asserts that the specified element is positive
|
||||
//
|
||||
// assert.Positive(t, 1)
|
||||
// assert.Positive(t, 1.23)
|
||||
func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.Positive(t, e, msgAndArgs...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Positivef asserts that the specified element is positive
|
||||
//
|
||||
// assert.Positivef(t, 1, "error message %s", "formatted")
|
||||
// assert.Positivef(t, 1.23, "error message %s", "formatted")
|
||||
func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if assert.Positivef(t, e, msg, args...) {
|
||||
return
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
|
||||
|
|
|
@ -205,6 +205,42 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) {
|
|||
Error(a.t, err, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
ErrorAs(a.t, err, target, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.
|
||||
// This is a wrapper for errors.As.
|
||||
func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
ErrorAsf(a.t, err, target, msg, args...)
|
||||
}
|
||||
|
||||
// ErrorIs asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
ErrorIs(a.t, err, target, msgAndArgs...)
|
||||
}
|
||||
|
||||
// ErrorIsf asserts that at least one of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
ErrorIsf(a.t, err, target, msg, args...)
|
||||
}
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
|
@ -632,6 +668,102 @@ func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilo
|
|||
InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
|
||||
}
|
||||
|
||||
// IsDecreasing asserts that the collection is decreasing
|
||||
//
|
||||
// a.IsDecreasing([]int{2, 1, 0})
|
||||
// a.IsDecreasing([]float{2, 1})
|
||||
// a.IsDecreasing([]string{"b", "a"})
|
||||
func (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsDecreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsDecreasingf asserts that the collection is decreasing
|
||||
//
|
||||
// a.IsDecreasingf([]int{2, 1, 0}, "error message %s", "formatted")
|
||||
// a.IsDecreasingf([]float{2, 1}, "error message %s", "formatted")
|
||||
// a.IsDecreasingf([]string{"b", "a"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsDecreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsIncreasing asserts that the collection is increasing
|
||||
//
|
||||
// a.IsIncreasing([]int{1, 2, 3})
|
||||
// a.IsIncreasing([]float{1, 2})
|
||||
// a.IsIncreasing([]string{"a", "b"})
|
||||
func (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsIncreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsIncreasingf asserts that the collection is increasing
|
||||
//
|
||||
// a.IsIncreasingf([]int{1, 2, 3}, "error message %s", "formatted")
|
||||
// a.IsIncreasingf([]float{1, 2}, "error message %s", "formatted")
|
||||
// a.IsIncreasingf([]string{"a", "b"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsIncreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsNonDecreasing asserts that the collection is not decreasing
|
||||
//
|
||||
// a.IsNonDecreasing([]int{1, 1, 2})
|
||||
// a.IsNonDecreasing([]float{1, 2})
|
||||
// a.IsNonDecreasing([]string{"a", "b"})
|
||||
func (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsNonDecreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonDecreasingf asserts that the collection is not decreasing
|
||||
//
|
||||
// a.IsNonDecreasingf([]int{1, 1, 2}, "error message %s", "formatted")
|
||||
// a.IsNonDecreasingf([]float{1, 2}, "error message %s", "formatted")
|
||||
// a.IsNonDecreasingf([]string{"a", "b"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsNonDecreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsNonIncreasing asserts that the collection is not increasing
|
||||
//
|
||||
// a.IsNonIncreasing([]int{2, 1, 1})
|
||||
// a.IsNonIncreasing([]float{2, 1})
|
||||
// a.IsNonIncreasing([]string{"b", "a"})
|
||||
func (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsNonIncreasing(a.t, object, msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonIncreasingf asserts that the collection is not increasing
|
||||
//
|
||||
// a.IsNonIncreasingf([]int{2, 1, 1}, "error message %s", "formatted")
|
||||
// a.IsNonIncreasingf([]float{2, 1}, "error message %s", "formatted")
|
||||
// a.IsNonIncreasingf([]string{"b", "a"}, "error message %s", "formatted")
|
||||
func (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
IsNonIncreasingf(a.t, object, msg, args...)
|
||||
}
|
||||
|
||||
// IsType asserts that the specified objects are of the same type.
|
||||
func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
|
@ -740,6 +872,28 @@ func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...i
|
|||
Lessf(a.t, e1, e2, msg, args...)
|
||||
}
|
||||
|
||||
// Negative asserts that the specified element is negative
|
||||
//
|
||||
// a.Negative(-1)
|
||||
// a.Negative(-1.23)
|
||||
func (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
Negative(a.t, e, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Negativef asserts that the specified element is negative
|
||||
//
|
||||
// a.Negativef(-1, "error message %s", "formatted")
|
||||
// a.Negativef(-1.23, "error message %s", "formatted")
|
||||
func (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
Negativef(a.t, e, msg, args...)
|
||||
}
|
||||
|
||||
// Never asserts that the given condition doesn't satisfy in waitFor time,
|
||||
// periodically checking the target function each tick.
|
||||
//
|
||||
|
@ -942,6 +1096,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
|
|||
NotEqualf(a.t, expected, actual, msg, args...)
|
||||
}
|
||||
|
||||
// NotErrorIs asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
NotErrorIs(a.t, err, target, msgAndArgs...)
|
||||
}
|
||||
|
||||
// NotErrorIsf asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
NotErrorIsf(a.t, err, target, msg, args...)
|
||||
}
|
||||
|
||||
// NotNil asserts that the specified object is not nil.
|
||||
//
|
||||
// a.NotNil(err)
|
||||
|
@ -1134,6 +1306,28 @@ func (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interfa
|
|||
Panicsf(a.t, f, msg, args...)
|
||||
}
|
||||
|
||||
// Positive asserts that the specified element is positive
|
||||
//
|
||||
// a.Positive(1)
|
||||
// a.Positive(1.23)
|
||||
func (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
Positive(a.t, e, msgAndArgs...)
|
||||
}
|
||||
|
||||
// Positivef asserts that the specified element is positive
|
||||
//
|
||||
// a.Positivef(1, "error message %s", "formatted")
|
||||
// a.Positivef(1.23, "error message %s", "formatted")
|
||||
func (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) {
|
||||
if h, ok := a.t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
Positivef(a.t, e, msg, args...)
|
||||
}
|
||||
|
||||
// Regexp asserts that a specified regexp matches a string.
|
||||
//
|
||||
// a.Regexp(regexp.MustCompile("start"), "it's starting")
|
||||
|
|
|
@ -55,6 +55,9 @@ func newFile(dataSources []dataSource, opts LoadOptions) *File {
|
|||
if len(opts.KeyValueDelimiterOnWrite) == 0 {
|
||||
opts.KeyValueDelimiterOnWrite = "="
|
||||
}
|
||||
if len(opts.ChildSectionDelimiter) == 0 {
|
||||
opts.ChildSectionDelimiter = "."
|
||||
}
|
||||
|
||||
return &File{
|
||||
BlockMode: true,
|
||||
|
@ -82,7 +85,7 @@ func (f *File) NewSection(name string) (*Section, error) {
|
|||
return nil, errors.New("empty section name")
|
||||
}
|
||||
|
||||
if f.options.Insensitive && name != DefaultSection {
|
||||
if (f.options.Insensitive || f.options.InsensitiveSections) && name != DefaultSection {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
|
||||
|
@ -144,7 +147,7 @@ func (f *File) SectionsByName(name string) ([]*Section, error) {
|
|||
if len(name) == 0 {
|
||||
name = DefaultSection
|
||||
}
|
||||
if f.options.Insensitive {
|
||||
if f.options.Insensitive || f.options.InsensitiveSections {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
|
||||
|
@ -236,7 +239,7 @@ func (f *File) DeleteSectionWithIndex(name string, index int) error {
|
|||
if len(name) == 0 {
|
||||
name = DefaultSection
|
||||
}
|
||||
if f.options.Insensitive {
|
||||
if f.options.Insensitive || f.options.InsensitiveSections {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
|
||||
|
@ -299,6 +302,9 @@ func (f *File) Reload() (err error) {
|
|||
}
|
||||
return err
|
||||
}
|
||||
if f.options.ShortCircuit {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -347,7 +353,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if i > 0 || DefaultHeader {
|
||||
if i > 0 || DefaultHeader || (i == 0 && strings.ToUpper(sec.name) != DefaultSection) {
|
||||
if _, err := buf.WriteString("[" + sname + "]" + LineBreak); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -451,6 +457,8 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
|
|||
val = `"""` + val + `"""`
|
||||
} else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") {
|
||||
val = "`" + val + "`"
|
||||
} else if len(strings.TrimSpace(val)) != len(val) {
|
||||
val = `"` + val + `"`
|
||||
}
|
||||
if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
|
||||
return nil, err
|
||||
|
@ -494,7 +502,7 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
// SaveToIndent writes content to file system with given value indention.
|
||||
func (f *File) SaveToIndent(filename, indent string) error {
|
||||
// Note: Because we are truncating with os.Create,
|
||||
// so it's safer to save to a temporary file location and rename afte done.
|
||||
// so it's safer to save to a temporary file location and rename after done.
|
||||
buf, err := f.writeToBuffer(indent)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -71,12 +71,18 @@ type LoadOptions struct {
|
|||
Loose bool
|
||||
// Insensitive indicates whether the parser forces all section and key names to lowercase.
|
||||
Insensitive bool
|
||||
// InsensitiveSections indicates whether the parser forces all section to lowercase.
|
||||
InsensitiveSections bool
|
||||
// InsensitiveKeys indicates whether the parser forces all key names to lowercase.
|
||||
InsensitiveKeys bool
|
||||
// IgnoreContinuation indicates whether to ignore continuation lines while parsing.
|
||||
IgnoreContinuation bool
|
||||
// IgnoreInlineComment indicates whether to ignore comments at the end of value and treat it as part of value.
|
||||
IgnoreInlineComment bool
|
||||
// SkipUnrecognizableLines indicates whether to skip unrecognizable lines that do not conform to key/value pairs.
|
||||
SkipUnrecognizableLines bool
|
||||
// ShortCircuit indicates whether to ignore other configuration sources after loaded the first available configuration source.
|
||||
ShortCircuit bool
|
||||
// AllowBooleanKeys indicates whether to allow boolean type keys or treat as value is missing.
|
||||
// This type of keys are mostly used in my.cnf.
|
||||
AllowBooleanKeys bool
|
||||
|
@ -107,8 +113,10 @@ type LoadOptions struct {
|
|||
UnparseableSections []string
|
||||
// KeyValueDelimiters is the sequence of delimiters that are used to separate key and value. By default, it is "=:".
|
||||
KeyValueDelimiters string
|
||||
// KeyValueDelimiters is the delimiter that are used to separate key and value output. By default, it is "=".
|
||||
// KeyValueDelimiterOnWrite is the delimiter that are used to separate key and value output. By default, it is "=".
|
||||
KeyValueDelimiterOnWrite string
|
||||
// ChildSectionDelimiter is the delimiter that is used to separate child sections. By default, it is ".".
|
||||
ChildSectionDelimiter string
|
||||
// PreserveSurroundedQuote indicates whether to preserve surrounded quote (single and double quotes).
|
||||
PreserveSurroundedQuote bool
|
||||
// DebugFunc is called to collect debug information (currently only useful to debug parsing Python-style multiline values).
|
||||
|
|
|
@ -377,7 +377,7 @@ func (f *File) parse(reader io.Reader) (err error) {
|
|||
|
||||
// Ignore error because default section name is never empty string.
|
||||
name := DefaultSection
|
||||
if f.options.Insensitive {
|
||||
if f.options.Insensitive || f.options.InsensitiveSections {
|
||||
name = strings.ToLower(DefaultSection)
|
||||
}
|
||||
section, _ := f.NewSection(name)
|
||||
|
@ -469,7 +469,7 @@ func (f *File) parse(reader io.Reader) (err error) {
|
|||
inUnparseableSection = false
|
||||
for i := range f.options.UnparseableSections {
|
||||
if f.options.UnparseableSections[i] == name ||
|
||||
(f.options.Insensitive && strings.EqualFold(f.options.UnparseableSections[i], name)) {
|
||||
((f.options.Insensitive || f.options.InsensitiveSections) && strings.EqualFold(f.options.UnparseableSections[i], name)) {
|
||||
inUnparseableSection = true
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ func (s *Section) SetBody(body string) {
|
|||
func (s *Section) NewKey(name, val string) (*Key, error) {
|
||||
if len(name) == 0 {
|
||||
return nil, errors.New("error creating new key: empty key name")
|
||||
} else if s.f.options.Insensitive {
|
||||
} else if s.f.options.Insensitive || s.f.options.InsensitiveKeys {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ func (s *Section) GetKey(name string) (*Key, error) {
|
|||
if s.f.BlockMode {
|
||||
s.f.lock.RLock()
|
||||
}
|
||||
if s.f.options.Insensitive {
|
||||
if s.f.options.Insensitive || s.f.options.InsensitiveKeys {
|
||||
name = strings.ToLower(name)
|
||||
}
|
||||
key := s.keys[name]
|
||||
|
@ -121,7 +121,7 @@ func (s *Section) GetKey(name string) (*Key, error) {
|
|||
// Check if it is a child-section.
|
||||
sname := s.name
|
||||
for {
|
||||
if i := strings.LastIndex(sname, "."); i > -1 {
|
||||
if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 {
|
||||
sname = sname[:i]
|
||||
sec, err := s.f.GetSection(sname)
|
||||
if err != nil {
|
||||
|
@ -188,7 +188,7 @@ func (s *Section) ParentKeys() []*Key {
|
|||
var parentKeys []*Key
|
||||
sname := s.name
|
||||
for {
|
||||
if i := strings.LastIndex(sname, "."); i > -1 {
|
||||
if i := strings.LastIndex(sname, s.f.options.ChildSectionDelimiter); i > -1 {
|
||||
sname = sname[:i]
|
||||
sec, err := s.f.GetSection(sname)
|
||||
if err != nil {
|
||||
|
@ -245,7 +245,7 @@ func (s *Section) DeleteKey(name string) {
|
|||
// For example, "[parent.child1]" and "[parent.child12]" are child sections
|
||||
// of section "[parent]".
|
||||
func (s *Section) ChildSections() []*Section {
|
||||
prefix := s.name + "."
|
||||
prefix := s.name + s.f.options.ChildSectionDelimiter
|
||||
children := make([]*Section, 0, 3)
|
||||
for _, name := range s.f.sectionList {
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
|
|
|
@ -263,24 +263,21 @@ func setWithProperType(t reflect.Type, key *Key, field reflect.Value, delim stri
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool, allowNonUnique bool) {
|
||||
opts := strings.SplitN(tag, ",", 4)
|
||||
func parseTagOptions(tag string) (rawName string, omitEmpty bool, allowShadow bool, allowNonUnique bool, extends bool) {
|
||||
opts := strings.SplitN(tag, ",", 5)
|
||||
rawName = opts[0]
|
||||
if len(opts) > 1 {
|
||||
omitEmpty = opts[1] == "omitempty"
|
||||
for _, opt := range opts[1:] {
|
||||
omitEmpty = omitEmpty || (opt == "omitempty")
|
||||
allowShadow = allowShadow || (opt == "allowshadow")
|
||||
allowNonUnique = allowNonUnique || (opt == "nonunique")
|
||||
extends = extends || (opt == "extends")
|
||||
}
|
||||
if len(opts) > 2 {
|
||||
allowShadow = opts[2] == "allowshadow"
|
||||
}
|
||||
if len(opts) > 3 {
|
||||
allowNonUnique = opts[3] == "nonunique"
|
||||
}
|
||||
return rawName, omitEmpty, allowShadow, allowNonUnique
|
||||
return rawName, omitEmpty, allowShadow, allowNonUnique, extends
|
||||
}
|
||||
|
||||
// mapToField maps the given value to the matching field of the given section.
|
||||
// The sectionIndex is the index (if non unique sections are enabled) to which the value should be added.
|
||||
func (s *Section) mapToField(val reflect.Value, isStrict bool, sectionIndex int) error {
|
||||
func (s *Section) mapToField(val reflect.Value, isStrict bool, sectionIndex int, sectionName string) error {
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val = val.Elem()
|
||||
}
|
||||
|
@ -295,7 +292,7 @@ func (s *Section) mapToField(val reflect.Value, isStrict bool, sectionIndex int)
|
|||
continue
|
||||
}
|
||||
|
||||
rawName, _, allowShadow, allowNonUnique := parseTagOptions(tag)
|
||||
rawName, _, allowShadow, allowNonUnique, extends := parseTagOptions(tag)
|
||||
fieldName := s.parseFieldName(tpField.Name, rawName)
|
||||
if len(fieldName) == 0 || !field.CanSet() {
|
||||
continue
|
||||
|
@ -303,12 +300,26 @@ func (s *Section) mapToField(val reflect.Value, isStrict bool, sectionIndex int)
|
|||
|
||||
isStruct := tpField.Type.Kind() == reflect.Struct
|
||||
isStructPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct
|
||||
isAnonymous := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
|
||||
if isAnonymous {
|
||||
isAnonymousPtr := tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous
|
||||
if isAnonymousPtr {
|
||||
field.Set(reflect.New(tpField.Type.Elem()))
|
||||
}
|
||||
|
||||
if isAnonymous || isStruct || isStructPtr {
|
||||
if extends && (isAnonymousPtr || (isStruct && tpField.Anonymous)) {
|
||||
if isStructPtr && field.IsNil() {
|
||||
field.Set(reflect.New(tpField.Type.Elem()))
|
||||
}
|
||||
fieldSection := s
|
||||
if rawName != "" {
|
||||
sectionName = s.name + s.f.options.ChildSectionDelimiter + rawName
|
||||
if secs, err := s.f.SectionsByName(sectionName); err == nil && sectionIndex < len(secs) {
|
||||
fieldSection = secs[sectionIndex]
|
||||
}
|
||||
}
|
||||
if err := fieldSection.mapToField(field, isStrict, sectionIndex, sectionName); err != nil {
|
||||
return fmt.Errorf("map to field %q: %v", fieldName, err)
|
||||
}
|
||||
} else if isAnonymousPtr || isStruct || isStructPtr {
|
||||
if secs, err := s.f.SectionsByName(fieldName); err == nil {
|
||||
if len(secs) <= sectionIndex {
|
||||
return fmt.Errorf("there are not enough sections (%d <= %d) for the field %q", len(secs), sectionIndex, fieldName)
|
||||
|
@ -318,7 +329,7 @@ func (s *Section) mapToField(val reflect.Value, isStrict bool, sectionIndex int)
|
|||
if isStructPtr && field.IsNil() {
|
||||
field.Set(reflect.New(tpField.Type.Elem()))
|
||||
}
|
||||
if err = secs[sectionIndex].mapToField(field, isStrict, sectionIndex); err != nil {
|
||||
if err = secs[sectionIndex].mapToField(field, isStrict, sectionIndex, fieldName); err != nil {
|
||||
return fmt.Errorf("map to field %q: %v", fieldName, err)
|
||||
}
|
||||
continue
|
||||
|
@ -357,7 +368,7 @@ func (s *Section) mapToSlice(secName string, val reflect.Value, isStrict bool) (
|
|||
typ := val.Type().Elem()
|
||||
for i, sec := range secs {
|
||||
elem := reflect.New(typ)
|
||||
if err = sec.mapToField(elem, isStrict, i); err != nil {
|
||||
if err = sec.mapToField(elem, isStrict, i, sec.name); err != nil {
|
||||
return reflect.Value{}, fmt.Errorf("map to field from section %q: %v", secName, err)
|
||||
}
|
||||
|
||||
|
@ -387,7 +398,7 @@ func (s *Section) mapTo(v interface{}, isStrict bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
return s.mapToField(val, isStrict, 0)
|
||||
return s.mapToField(val, isStrict, 0, s.name)
|
||||
}
|
||||
|
||||
// MapTo maps section to given struct.
|
||||
|
@ -479,7 +490,7 @@ func reflectSliceWithProperType(key *Key, field reflect.Value, delim string, all
|
|||
_ = keyWithShadows.AddShadow(val)
|
||||
}
|
||||
}
|
||||
key = keyWithShadows
|
||||
*key = *keyWithShadows
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -581,7 +592,7 @@ func (s *Section) reflectFrom(val reflect.Value) error {
|
|||
continue
|
||||
}
|
||||
|
||||
rawName, omitEmpty, allowShadow, allowNonUnique := parseTagOptions(tag)
|
||||
rawName, omitEmpty, allowShadow, allowNonUnique, extends := parseTagOptions(tag)
|
||||
if omitEmpty && isEmptyValue(field) {
|
||||
continue
|
||||
}
|
||||
|
@ -595,7 +606,14 @@ func (s *Section) reflectFrom(val reflect.Value) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if (tpField.Type.Kind() == reflect.Ptr && tpField.Anonymous) ||
|
||||
if extends && tpField.Anonymous && (tpField.Type.Kind() == reflect.Ptr || tpField.Type.Kind() == reflect.Struct) {
|
||||
if err := s.reflectFrom(field); err != nil {
|
||||
return fmt.Errorf("reflect from field %q: %v", fieldName, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if (tpField.Type.Kind() == reflect.Ptr && tpField.Type.Elem().Kind() == reflect.Struct) ||
|
||||
(tpField.Type.Kind() == reflect.Struct && tpField.Type.Name() != "Time") {
|
||||
// Note: The only error here is section doesn't exist.
|
||||
sec, err := s.f.GetSection(fieldName)
|
||||
|
|
|
@ -551,11 +551,12 @@ github.com/spf13/pflag
|
|||
# github.com/spf13/viper v1.7.0
|
||||
## explicit
|
||||
github.com/spf13/viper
|
||||
# github.com/spotinst/spotinst-sdk-go v1.76.0
|
||||
# github.com/spotinst/spotinst-sdk-go v1.80.0
|
||||
## explicit
|
||||
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
|
||||
|
@ -570,7 +571,7 @@ github.com/spotinst/spotinst-sdk-go/spotinst/util/jsonutil
|
|||
github.com/spotinst/spotinst-sdk-go/spotinst/util/stringutil
|
||||
github.com/spotinst/spotinst-sdk-go/spotinst/util/uritemplates
|
||||
github.com/spotinst/spotinst-sdk-go/spotinst/util/useragent
|
||||
# github.com/stretchr/testify v1.6.1
|
||||
# github.com/stretchr/testify v1.7.0
|
||||
## explicit
|
||||
github.com/stretchr/testify/assert
|
||||
github.com/stretchr/testify/require
|
||||
|
@ -827,7 +828,7 @@ gopkg.in/gcfg.v1/types
|
|||
# gopkg.in/inf.v0 v0.9.1
|
||||
## explicit
|
||||
gopkg.in/inf.v0
|
||||
# gopkg.in/ini.v1 v1.57.0
|
||||
# gopkg.in/ini.v1 v1.62.0
|
||||
gopkg.in/ini.v1
|
||||
# gopkg.in/square/go-jose.v2 v2.3.1
|
||||
gopkg.in/square/go-jose.v2
|
||||
|
|
Loading…
Reference in New Issue