/
helpers.go
127 lines (106 loc) · 3.1 KB
/
helpers.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package helpers
import (
"context"
"github.com/Netflix/p2plab"
"github.com/Netflix/p2plab/labd/controlapi"
"github.com/Netflix/p2plab/metadata"
"github.com/Netflix/p2plab/nodes"
"github.com/Netflix/p2plab/pkg/httputil"
"github.com/pkg/errors"
"github.com/rs/zerolog"
bolt "go.etcd.io/bbolt"
)
// Helper abstracts commonly used functions to be shared by any router
type Helper struct {
db metadata.DB
provider p2plab.NodeProvider
client *httputil.Client
}
// New instantiates our helper type
func New(db metadata.DB, provider p2plab.NodeProvider, client *httputil.Client) *Helper {
return &Helper{db, provider, client}
}
// CreateCluster enables creating the nodes in a cluster, waiting for them to be healthy before returning
func (h *Helper) CreateCluster(ctx context.Context, cdef metadata.ClusterDefinition, name string) (metadata.Cluster, error) {
var (
cluster = metadata.Cluster{
ID: name,
Status: metadata.ClusterCreating,
Definition: cdef,
Labels: append([]string{
name,
}, cdef.GenerateLabels()...),
}
err error
)
cluster, err = h.db.CreateCluster(ctx, cluster)
if err != nil {
return cluster, err
}
zerolog.Ctx(ctx).Info().Str("cid", name).Msg("Creating node group")
ng, err := h.provider.CreateNodeGroup(ctx, name, cdef)
if err != nil {
return cluster, err
}
var mns []metadata.Node
cluster.Status = metadata.ClusterConnecting
if err := h.db.Update(ctx, func(tx *bolt.Tx) error {
var err error
tctx := metadata.WithTransactionContext(ctx, tx)
cluster, err = h.db.UpdateCluster(tctx, cluster)
if err != nil {
return err
}
mns, err = h.db.CreateNodes(tctx, cluster.ID, ng.Nodes)
if err != nil {
return err
}
return nil
}); err != nil {
return cluster, err
}
var ns = make([]p2plab.Node, len(mns))
for i, n := range mns {
ns[i] = controlapi.NewNode(h.client, n)
}
if err := nodes.WaitHealthy(ctx, ns); err != nil {
return cluster, err
}
cluster.Status = metadata.ClusterCreated
return h.db.UpdateCluster(ctx, cluster)
}
func (h *Helper) DeleteCluster(ctx context.Context, name string) error {
logger := zerolog.Ctx(ctx).With().Str("name", name).Logger()
ctx = logger.WithContext(ctx)
cluster, err := h.db.GetCluster(ctx, name)
if err != nil {
return errors.Wrapf(err, "failed to get cluster %q", name)
}
if cluster.Status != metadata.ClusterDestroying {
cluster.Status = metadata.ClusterDestroying
cluster, err = h.db.UpdateCluster(ctx, cluster)
if err != nil {
return errors.Wrap(err, "failed to update cluster status to destroying")
}
}
ns, err := h.db.ListNodes(ctx, cluster.ID)
if err != nil {
return errors.Wrap(err, "failed to list nodes")
}
ng := &p2plab.NodeGroup{
ID: cluster.ID,
Nodes: ns,
}
logger.Info().Msg("Destroying node group")
err = h.provider.DestroyNodeGroup(ctx, ng)
if err != nil {
return errors.Wrap(err, "failed to destroy node group")
}
logger.Info().Msg("Deleting cluster metadata")
err = h.db.DeleteCluster(ctx, cluster.ID)
if err != nil {
return errors.Wrap(err, "failed to delete cluster metadata")
}
logger.Info().Msg("Destroyed cluster")
return nil
}