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