/
relation.go
93 lines (79 loc) · 2.34 KB
/
relation.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
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package uniter
import (
"fmt"
"github.com/juju/names"
"github.com/juju/juju/apiserver/params"
)
// This module implements a subset of the interface provided by
// state.Relation, as needed by the uniter API.
// Relation represents a relation between one or two service
// endpoints.
type Relation struct {
st *State
tag names.RelationTag
id int
life params.Life
}
// Tag returns the relation tag.
func (r *Relation) Tag() names.RelationTag {
return r.tag
}
// String returns the relation as a string.
func (r *Relation) String() string {
return r.tag.Id()
}
// Id returns the integer internal relation key. This is exposed
// because the unit agent needs to expose a value derived from this
// (as JUJU_RELATION_ID) to allow relation hooks to differentiate
// between relations with different services.
func (r *Relation) Id() int {
return r.id
}
// Life returns the relation's current life state.
func (r *Relation) Life() params.Life {
return r.life
}
// Refresh refreshes the contents of the relation from the underlying
// state. It returns an error that satisfies errors.IsNotFound if the
// relation has been removed.
func (r *Relation) Refresh() error {
result, err := r.st.relation(r.tag, r.st.unitTag)
if err != nil {
return err
}
// NOTE: The life cycle information is the only
// thing that can change - id, tag and endpoint
// information are static.
r.life = result.Life
return nil
}
// Endpoint returns the endpoint of the relation for the service the
// uniter's managed unit belongs to.
func (r *Relation) Endpoint() (*Endpoint, error) {
// NOTE: This differs from state.Relation.Endpoint(), because when
// talking to the API, there's already an authenticated entity - the
// unit, and we can find out its service name.
result, err := r.st.relation(r.tag, r.st.unitTag)
if err != nil {
return nil, err
}
return &Endpoint{result.Endpoint.Relation}, nil
}
// Unit returns a RelationUnit for the supplied unit.
func (r *Relation) Unit(u *Unit) (*RelationUnit, error) {
if u == nil {
return nil, fmt.Errorf("unit is nil")
}
result, err := r.st.relation(r.tag, u.tag)
if err != nil {
return nil, err
}
return &RelationUnit{
relation: r,
unit: u,
endpoint: Endpoint{result.Endpoint.Relation},
st: r.st,
}, nil
}