github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/worker/uniter/jujuc/context.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc 5 6 import ( 7 "fmt" 8 "strconv" 9 "strings" 10 11 "github.com/juju/charm" 12 13 "github.com/juju/juju/state/api/params" 14 ) 15 16 // Context is the interface that all hook helper commands 17 // depend on to interact with the rest of the system. 18 type Context interface { 19 20 // Unit returns the executing unit's name. 21 UnitName() string 22 23 // PublicAddress returns the executing unit's public address. 24 PublicAddress() (string, bool) 25 26 // PrivateAddress returns the executing unit's private address. 27 PrivateAddress() (string, bool) 28 29 // OpenPort marks the supplied port for opening when the executing unit's 30 // service is exposed. 31 OpenPort(protocol string, port int) error 32 33 // ClosePort ensures the supplied port is closed even when the executing 34 // unit's service is exposed (unless it is opened separately by a co- 35 // located unit). 36 ClosePort(protocol string, port int) error 37 38 // Config returns the current service configuration of the executing unit. 39 ConfigSettings() (charm.Settings, error) 40 41 // HookRelation returns the ContextRelation associated with the executing 42 // hook if it was found, and whether it was found. 43 HookRelation() (ContextRelation, bool) 44 45 // RemoteUnitName returns the name of the remote unit the hook execution 46 // is associated with if it was found, and whether it was found. 47 RemoteUnitName() (string, bool) 48 49 // Relation returns the relation with the supplied id if it was found, and 50 // whether it was found. 51 Relation(id int) (ContextRelation, bool) 52 53 // RelationIds returns the ids of all relations the executing unit is 54 // currently participating in. 55 RelationIds() []int 56 57 // OwnerTag returns the owner of the service the executing units belongs to 58 OwnerTag() string 59 } 60 61 // ContextRelation expresses the capabilities of a hook with respect to a relation. 62 type ContextRelation interface { 63 64 // Id returns an integer which uniquely identifies the relation. 65 Id() int 66 67 // Name returns the name the locally executing charm assigned to this relation. 68 Name() string 69 70 // FakeId returns a string of the form "relation-name:123", which uniquely 71 // identifies the relation to the hook. In reality, the identification 72 // of the relation is the integer following the colon, but the composed 73 // name is useful to humans observing it. 74 FakeId() string 75 76 // Settings allows read/write access to the local unit's settings in 77 // this relation. 78 Settings() (Settings, error) 79 80 // UnitNames returns a list of the remote units in the relation. 81 UnitNames() []string 82 83 // ReadSettings returns the settings of any remote unit in the relation. 84 ReadSettings(unit string) (params.RelationSettings, error) 85 } 86 87 // Settings is implemented by types that manipulate unit settings. 88 type Settings interface { 89 Map() params.RelationSettings 90 Set(string, string) 91 Delete(string) 92 } 93 94 // newRelationIdValue returns a gnuflag.Value for convenient parsing of relation 95 // ids in ctx. 96 func newRelationIdValue(ctx Context, result *int) *relationIdValue { 97 v := &relationIdValue{result: result, ctx: ctx} 98 id := -1 99 if r, found := ctx.HookRelation(); found { 100 id = r.Id() 101 v.value = r.FakeId() 102 } 103 *result = id 104 return v 105 } 106 107 // relationIdValue implements gnuflag.Value for use in relation commands. 108 type relationIdValue struct { 109 result *int 110 ctx Context 111 value string 112 } 113 114 // String returns the current value. 115 func (v *relationIdValue) String() string { 116 return v.value 117 } 118 119 // Set interprets value as a relation id, if possible, and returns an error 120 // if it is not known to the system. The parsed relation id will be written 121 // to v.result. 122 func (v *relationIdValue) Set(value string) error { 123 trim := value 124 if idx := strings.LastIndex(trim, ":"); idx != -1 { 125 trim = trim[idx+1:] 126 } 127 id, err := strconv.Atoi(trim) 128 if err != nil { 129 return fmt.Errorf("invalid relation id") 130 } 131 if _, found := v.ctx.Relation(id); !found { 132 return fmt.Errorf("unknown relation id") 133 } 134 *v.result = id 135 v.value = value 136 return nil 137 }