github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/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 // Hostname returns a name suitable to be used for a machine hostname. 23 // This function returns an error if the machine tags is invalid. 24 Hostname(machineID string) (string, error) 25 26 // MachineTag does the reverse of the Hostname method, and extracts the 27 // Tag from the hostname. 28 MachineTag(hostname string) (names.MachineTag, error) 29 } 30 31 type namespace struct { 32 name string 33 } 34 35 // NewNamespace returns a Namespace identified by the last six hex digits of the 36 // model UUID. NewNamespace returns an error if the model tag is invalid. 37 func NewNamespace(modelUUID string) (Namespace, error) { 38 if !names.IsValidModel(modelUUID) { 39 return nil, errors.Errorf("model ID %q is not a valid model", modelUUID) 40 } 41 // The suffix is the last six hex digits of the model uuid. 42 suffix := modelUUID[len(modelUUID)-uuidSuffixDigits:] 43 44 return &namespace{name: suffix}, nil 45 } 46 47 // Hostname implements Namespace. 48 func (n *namespace) Hostname(machineID string) (string, error) { 49 if !names.IsValidMachine(machineID) { 50 return "", errors.Errorf("machine ID %q is not a valid machine", machineID) 51 } 52 machineID = strings.Replace(machineID, "/", "-", -1) 53 return n.Prefix() + machineID, nil 54 } 55 56 // Hostname implements Namespace. 57 func (n *namespace) MachineTag(hostname string) (names.MachineTag, error) { 58 prefix := n.Prefix() 59 if !strings.HasPrefix(hostname, prefix) { 60 return names.MachineTag{}, errors.Errorf("hostname %q not from namespace %q", hostname, prefix) 61 } 62 id := hostname[len(prefix):] 63 id = strings.Replace(id, "-", "/", -1) 64 if !names.IsValidMachine(id) { 65 return names.MachineTag{}, errors.Errorf("unexpected machine id %q", id) 66 } 67 return names.NewMachineTag(id), nil 68 } 69 70 // Prefix implements Namespace. 71 func (n *namespace) Prefix() string { 72 return "juju-" + n.name + "-" 73 }