diff --git a/core/machine/doc.go b/core/machine/doc.go new file mode 100644 index 00000000000..4555da72516 --- /dev/null +++ b/core/machine/doc.go @@ -0,0 +1,6 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +// Package machine provide core common types that all of Juju can use to reason +// about machines in a model. +package machine diff --git a/core/machine/machine.go b/core/machine/machine.go new file mode 100644 index 00000000000..ebc261e9caf --- /dev/null +++ b/core/machine/machine.go @@ -0,0 +1,42 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package machine + +import ( + "fmt" + + "github.com/juju/errors" + + "github.com/juju/juju/internal/uuid" +) + +// ID is a unique identifier for a machine. +type ID string + +// NewId makes and returns a new machine [ID]. +func NewId() (ID, error) { + uuid, err := uuid.NewUUID() + if err != nil { + return "", fmt.Errorf("generating new machine id: %w", err) + } + + return ID(uuid.String()), nil +} + +// Validate returns an error if the [ID] is invalid. The error returned +// satisfies [errors.NotValid]. +func (i ID) Validate() error { + if i == "" { + return fmt.Errorf("empty machine id%w", errors.Hide(errors.NotValid)) + } + if !uuid.IsValidUUIDString(string(i)) { + return fmt.Errorf("invalid machine id: %q%w", i, errors.Hide(errors.NotValid)) + } + return nil +} + +// String returns the [ID] as a string. +func (i ID) String() string { + return string(i) +} diff --git a/core/machine/machine_test.go b/core/machine/machine_test.go new file mode 100644 index 00000000000..b3f3cd82945 --- /dev/null +++ b/core/machine/machine_test.go @@ -0,0 +1,50 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package machine + +import ( + "github.com/juju/errors" + jc "github.com/juju/testing/checkers" + gc "gopkg.in/check.v1" + + "github.com/juju/juju/internal/uuid" +) + +type machineSuite struct { +} + +var _ = gc.Suite(&machineSuite{}) + +// TestIdValidate is testing several good and not so good machine id's to check +// that the validate method produces the correct result. +func (*machineSuite) TestIdValidate(c *gc.C) { + tests := []struct { + id string + err error + }{ + { + id: "", + err: errors.NotValid, + }, + { + id: "invalid", + err: errors.NotValid, + }, + { + id: uuid.MustNewUUID().String(), + }, + } + + for i, test := range tests { + c.Logf("test %d: %q", i, test.id) + err := ID(test.id).Validate() + + if test.err == nil { + c.Check(err, gc.IsNil) + continue + } + + c.Check(err, jc.ErrorIs, test.err) + } +} diff --git a/core/machine/package_test.go b/core/machine/package_test.go new file mode 100644 index 00000000000..e976071cf43 --- /dev/null +++ b/core/machine/package_test.go @@ -0,0 +1,14 @@ +// Copyright 2024 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package machine + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +func TestPackage(t *testing.T) { + gc.TestingT(t) +}