github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/instance/namespace.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package instance 5 6 import ( 7 "strings" 8 9 "github.com/juju/errors" 10 "gopkg.in/juju/names.v2" 11 ) 12 13 // uuidSuffixDigits defines how many of the uuid digits to use. 14 // Since the NewNamespace function asserts that the modelUUID is valid, we know 15 // it follows the UUID string format that ends with eight hex digits. 16 const uuidSuffixDigits = 6 17 18 // Namespace provides a way to generate machine hostanmes with a given prefix. 19 type Namespace interface { 20 // Prefix returns the common part of the hostnames. i.e. 'juju-xxxxxx-' 21 Prefix() string 22 23 // Hostname returns a name suitable to be used for a machine hostname. 24 // This function returns an error if the machine tags is invalid. 25 Hostname(machineID string) (string, error) 26 27 // MachineTag does the reverse of the Hostname method, and extracts the 28 // Tag from the hostname. 29 MachineTag(hostname string) (names.MachineTag, error) 30 31 // Value returns the input prefixed with the namespace prefix. 32 Value(string) string 33 } 34 35 type namespace struct { 36 name string 37 } 38 39 // NewNamespace returns a Namespace identified by the last six hex digits of the 40 // model UUID. NewNamespace returns an error if the model tag is invalid. 41 func NewNamespace(modelUUID string) (Namespace, error) { 42 if !names.IsValidModel(modelUUID) { 43 return nil, errors.Errorf("model ID %q is not a valid model", modelUUID) 44 } 45 // The suffix is the last six hex digits of the model uuid. 46 suffix := modelUUID[len(modelUUID)-uuidSuffixDigits:] 47 48 return &namespace{name: suffix}, nil 49 } 50 51 // Hostname implements Namespace. 52 func (n *namespace) Hostname(machineID string) (string, error) { 53 if !names.IsValidMachine(machineID) { 54 return "", errors.Errorf("machine ID %q is not a valid machine", machineID) 55 } 56 machineID = strings.Replace(machineID, "/", "-", -1) 57 return n.Value(machineID), nil 58 } 59 60 // Value returns the input prefixed with the namespace prefix. 61 func (n *namespace) Value(s string) string { 62 return n.Prefix() + s 63 } 64 65 // Hostname implements Namespace. 66 func (n *namespace) MachineTag(hostname string) (names.MachineTag, error) { 67 prefix := n.Prefix() 68 if !strings.HasPrefix(hostname, prefix) { 69 return names.MachineTag{}, errors.Errorf("hostname %q not from namespace %q", hostname, prefix) 70 } 71 id := hostname[len(prefix):] 72 id = strings.Replace(id, "-", "/", -1) 73 if !names.IsValidMachine(id) { 74 return names.MachineTag{}, errors.Errorf("unexpected machine id %q", id) 75 } 76 return names.NewMachineTag(id), nil 77 } 78 79 // Prefix implements Namespace. 80 func (n *namespace) Prefix() string { 81 return "juju-" + n.name + "-" 82 }