From e0be2d06de459c7aa434ef341c0f7f1b284576fb Mon Sep 17 00:00:00 2001 From: Nicolas Vinuesa Date: Wed, 15 Mar 2023 10:33:57 +0100 Subject: [PATCH] Add image-id constraint The new image-id constraint that has been added to juju core is also needed in description for deserialization. The constraints version has been bumped to 5. --- constraints.go | 23 ++++++++++++++++++++- constraints_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/constraints.go b/constraints.go index 5784d0c..21cb59e 100644 --- a/constraints.go +++ b/constraints.go @@ -23,6 +23,7 @@ type Constraints interface { Container() string CpuCores() uint64 CpuPower() uint64 + ImageID() string InstanceType() string Memory() uint64 RootDisk() uint64 @@ -42,6 +43,7 @@ type ConstraintsArgs struct { Container string CpuCores uint64 CpuPower uint64 + ImageID string InstanceType string Memory uint64 RootDisk uint64 @@ -69,12 +71,13 @@ func newConstraints(args ConstraintsArgs) *constraints { copy(zones, args.Zones) return &constraints{ - Version: 4, + Version: 5, AllocatePublicIP_: args.AllocatePublicIP, Architecture_: args.Architecture, Container_: args.Container, CpuCores_: args.CpuCores, CpuPower_: args.CpuPower, + ImageID_: args.ImageID, InstanceType_: args.InstanceType, Memory_: args.Memory, RootDisk_: args.RootDisk, @@ -94,6 +97,7 @@ type constraints struct { Container_ string `yaml:"container,omitempty"` CpuCores_ uint64 `yaml:"cores,omitempty"` CpuPower_ uint64 `yaml:"cpu-power,omitempty"` + ImageID_ string `yaml:"image-id,omitempty"` InstanceType_ string `yaml:"instance-type,omitempty"` Memory_ uint64 `yaml:"memory,omitempty"` RootDisk_ uint64 `yaml:"root-disk,omitempty"` @@ -131,6 +135,11 @@ func (c *constraints) CpuPower() uint64 { return c.CpuPower_ } +// ImageID implements Constraints. +func (c *constraints) ImageID() string { + return c.ImageID_ +} + // InstanceType implements Constraints. func (c *constraints) InstanceType() string { return c.InstanceType_ @@ -216,6 +225,7 @@ var constraintsFieldsFuncs = map[int]fieldsFunc{ 2: constraintsV2Fields, 3: constraintsV3Fields, 4: constraintsV4Fields, + 5: constraintsV5Fields, } func constraintsV1Fields() (schema.Fields, schema.Defaults) { @@ -273,6 +283,13 @@ func constraintsV4Fields() (schema.Fields, schema.Defaults) { return fields, defaults } +func constraintsV5Fields() (schema.Fields, schema.Defaults) { + fields, defaults := constraintsV4Fields() + fields["image-id"] = schema.String() + defaults["image-id"] = "" + return fields, defaults +} + // constraintsValidCPUCores returns an error if both aliases for CPU core count // are present in the list of fields. // If correctly specified, the cores value is returned. @@ -324,6 +341,9 @@ func validatedConstraints(version int, valid map[string]interface{}, cores uint6 cons.AllocatePublicIP_ = value.(bool) } } + if version > 4 { + cons.ImageID_ = valid["image-id"].(string) + } return cons } @@ -338,6 +358,7 @@ func (c ConstraintsArgs) empty() bool { c.Container == "" && c.CpuCores == 0 && c.CpuPower == 0 && + c.ImageID == "" && c.InstanceType == "" && c.Memory == 0 && c.RootDisk == 0 && diff --git a/constraints_test.go b/constraints_test.go index 79d69d2..79e1b6d 100644 --- a/constraints_test.go +++ b/constraints_test.go @@ -30,6 +30,7 @@ func (s *ConstraintsSerializationSuite) allArgs() ConstraintsArgs { Container: "lxd", CpuCores: 8, CpuPower: 4000, + ImageID: "ubuntu-bf2", InstanceType: "magic", Memory: 16 * gig, RootDisk: 200 * gig, @@ -49,6 +50,7 @@ func (s *ConstraintsSerializationSuite) TestNewConstraints(c *gc.C) { c.Assert(instance.Container(), gc.Equals, args.Container) c.Assert(instance.CpuCores(), gc.Equals, args.CpuCores) c.Assert(instance.CpuPower(), gc.Equals, args.CpuPower) + c.Assert(instance.ImageID(), gc.Equals, args.ImageID) c.Assert(instance.InstanceType(), gc.Equals, args.InstanceType) c.Assert(instance.Memory(), gc.Equals, args.Memory) c.Assert(instance.RootDisk(), gc.Equals, args.RootDisk) @@ -159,6 +161,7 @@ func (s *ConstraintsSerializationSuite) TestParsingV1Full(c *gc.C) { expected.Zones_ = nil expected.RootDiskSource_ = "" expected.AllocatePublicIP_ = false + expected.ImageID_ = "" expected.Version = 1 c.Assert(imported, gc.DeepEquals, expected) } @@ -202,6 +205,7 @@ func (s *ConstraintsSerializationSuite) TestParsingV2Full(c *gc.C) { expected := s.testConstraints() expected.RootDiskSource_ = "" expected.AllocatePublicIP_ = false + expected.ImageID_ = "" expected.Version = 2 c.Assert(imported, gc.DeepEquals, expected) } @@ -245,6 +249,7 @@ func (s *ConstraintsSerializationSuite) TestParsingV3Full(c *gc.C) { imported := s.importConstraints(c, original) expected := s.testConstraints() expected.AllocatePublicIP_ = false + expected.ImageID_ = "" expected.Version = 3 c.Assert(imported, gc.DeepEquals, expected) } @@ -281,6 +286,8 @@ func (s *ConstraintsSerializationSuite) TestParsingV4Full(c *gc.C) { original := s.allV4Map() imported := s.importConstraints(c, original) expected := s.testConstraints() + expected.ImageID_ = "" + expected.Version = 4 c.Assert(imported, gc.DeepEquals, expected) } @@ -292,3 +299,46 @@ func (s *ConstraintsSerializationSuite) TestParsingV4Minimal(c *gc.C) { expected := &constraints{Version: 4} c.Assert(imported, gc.DeepEquals, expected) } + +func (s *ConstraintsSerializationSuite) TestParsingV4IgnoresNewFields(c *gc.C) { + original := s.allV4Map() + original["image"] = "ubuntu-bf2" + imported := s.importConstraints(c, original) + c.Assert(imported.ImageID_, gc.Equals, "") +} + +func (s *ConstraintsSerializationSuite) allV5Map() map[string]interface{} { + return map[string]interface{}{ + "version": 5, + "allocate-public-ip": true, + "architecture": "amd64", + "container": "lxd", + "cores": 8, + "cpu-power": 4000, + "image-id": "ubuntu-bf2", + "instance-type": "magic", + "memory": 16 * gig, + "root-disk": 200 * gig, + "root-disk-source": "somewhere-good", + "spaces": []interface{}{"my", "own"}, + "tags": []interface{}{"much", "strong"}, + "zones": []interface{}{"az1", "az2"}, + "virt-type": "something", + } +} + +func (s *ConstraintsSerializationSuite) TestParsingV5Full(c *gc.C) { + original := s.allV5Map() + imported := s.importConstraints(c, original) + expected := s.testConstraints() + c.Assert(imported, gc.DeepEquals, expected) +} + +func (s *ConstraintsSerializationSuite) TestParsingV5Minimal(c *gc.C) { + original := map[string]interface{}{ + "version": 5, + } + imported := s.importConstraints(c, original) + expected := &constraints{Version: 5} + c.Assert(imported, gc.DeepEquals, expected) +}