-
Notifications
You must be signed in to change notification settings - Fork 568
/
cmds.go
354 lines (321 loc) · 12.2 KB
/
cmds.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
package cmds
import (
"context"
"fmt"
"github.com/pachyderm/pachyderm/v2/src/admin"
"github.com/pachyderm/pachyderm/v2/src/enterprise"
"github.com/pachyderm/pachyderm/v2/src/internal/cmdutil"
"github.com/pachyderm/pachyderm/v2/src/internal/config"
"github.com/pachyderm/pachyderm/v2/src/internal/errors"
"github.com/pachyderm/pachyderm/v2/src/internal/pachctl"
"github.com/pachyderm/pachyderm/v2/src/license"
"github.com/pachyderm/pachyderm/v2/src/version"
"github.com/gogo/protobuf/types"
"github.com/spf13/cobra"
)
func getIsActiveContextEnterpriseServer() (bool, error) {
cfg, err := config.Read(false, true)
if err != nil {
return false, errors.Wrapf(err, "could not read config")
}
_, ctx, err := cfg.ActiveEnterpriseContext(true)
if err != nil {
return false, errors.Wrapf(err, "could not retrieve the enterprise context from the config")
}
return ctx.EnterpriseServer, nil
}
// DeactivateCmd returns a cobra.Command to deactivate the enterprise service.
func DeactivateCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
deactivate := &cobra.Command{
Use: "{{alias}}",
Short: "Deactivate the enterprise service",
Long: "Deactivate the enterprise service",
Run: cmdutil.RunFixedArgs(0, func(args []string) error {
c, err := pachctlCfg.NewOnUserMachine(ctx, false)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer c.Close()
// Deactivate the enterprise server
req := &enterprise.DeactivateRequest{}
if _, err := c.Enterprise.Deactivate(c.Ctx(), req); err != nil {
return errors.EnsureStack(err)
}
return nil
}),
}
return cmdutil.CreateAlias(deactivate, "enterprise deactivate")
}
// RegisterCmd returns a cobra.Command that registers this cluster with a remote Enterprise Server.
func RegisterCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
var id, pachdAddr, pachdUsrAddr, enterpriseAddr, clusterId string
register := &cobra.Command{
Use: "{{alias}}",
Short: "Register the cluster with an enterprise license server",
Long: "Register the cluster with an enterprise license server",
Run: cmdutil.RunFixedArgs(0, func(args []string) error {
c, err := pachctlCfg.NewOnUserMachine(ctx, false)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer c.Close()
ec, err := pachctlCfg.NewOnUserMachine(ctx, true)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer ec.Close()
if pachdUsrAddr == "" {
pachdUsrAddr = c.GetAddress().Qualified()
}
if pachdAddr == "" {
pachdAddr = c.GetAddress().Qualified()
}
if enterpriseAddr == "" {
enterpriseAddr = ec.GetAddress().Qualified()
}
if clusterId == "" {
clusterInfo, inspectErr := c.AdminAPIClient.InspectCluster(c.Ctx(), &admin.InspectClusterRequest{
ClientVersion: version.Version,
})
if inspectErr != nil {
return errors.Wrapf(inspectErr, "could not inspect cluster")
}
clusterId = clusterInfo.DeploymentID
}
enterpriseServer, err := getIsActiveContextEnterpriseServer()
if err != nil {
return err
}
// Register the pachd with the license server
resp, err := ec.License.AddCluster(ec.Ctx(),
&license.AddClusterRequest{
Id: id,
Address: pachdAddr,
UserAddress: pachdUsrAddr,
ClusterDeploymentId: clusterId,
EnterpriseServer: enterpriseServer,
})
if err != nil {
return errors.Wrapf(err, "could not register pachd with the license service")
}
// activate the Enterprise service
_, err = c.Enterprise.Activate(c.Ctx(),
&enterprise.ActivateRequest{
Id: id,
Secret: resp.Secret,
LicenseServer: enterpriseAddr,
})
if err != nil {
err = errors.Wrapf(err, "could not register with the license server.")
_, deleteErr := ec.License.DeleteCluster(ec.Ctx(), &license.DeleteClusterRequest{Id: id})
if deleteErr != nil {
deleteErr := errors.Wrapf(deleteErr, "also failed to rollback creation of cluster with ID, %v."+
"To retry enterprise registration, first delete this cluster with 'pachctl license delete-cluster --id %v'.: %v",
id, id, deleteErr.Error())
return errors.Wrap(err, deleteErr.Error())
}
return err
}
return nil
}),
}
register.PersistentFlags().StringVar(&id, "id", "", "the id for this cluster")
register.PersistentFlags().StringVar(&pachdAddr, "pachd-address", "", "the address for the enterprise server to reach this pachd")
register.PersistentFlags().StringVar(&pachdUsrAddr, "pachd-user-address", "", "the address for a user to reach this pachd")
register.PersistentFlags().StringVar(&enterpriseAddr, "enterprise-server-address", "", "the address for the pachd to reach the enterprise server")
register.PersistentFlags().StringVar(&clusterId, "cluster-deployment-id", "", "the deployment id of the cluster being registered")
return cmdutil.CreateAlias(register, "enterprise register")
}
// GetStateCmd returns a cobra.Command to activate the enterprise features of
// Pachyderm within a Pachyderm cluster. All repos will go from
// publicly-accessible to accessible only by the owner, who can subsequently add
// users
func GetStateCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
var isEnterprise bool
getState := &cobra.Command{
Short: "Check whether the Pachyderm cluster has enterprise features " +
"activated",
Long: "Check whether the Pachyderm cluster has enterprise features " +
"activated",
Run: cmdutil.Run(func(args []string) error {
c, err := pachctlCfg.NewOnUserMachine(ctx, isEnterprise)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer c.Close()
resp, err := c.Enterprise.GetState(c.Ctx(), &enterprise.GetStateRequest{})
if err != nil {
return errors.EnsureStack(err)
}
if resp.State == enterprise.State_NONE {
fmt.Println("No Pachyderm Enterprise token was found")
return nil
}
ts, err := types.TimestampFromProto(resp.Info.Expires)
if err != nil {
return errors.Wrapf(err, "activation request succeeded, but could not "+
"convert token expiration time to a timestamp")
}
fmt.Printf("Pachyderm Enterprise token state: %s\nExpiration: %s\n",
resp.State.String(), ts.String())
return nil
}),
}
getState.PersistentFlags().BoolVar(&isEnterprise, "enterprise", false, "Activate auth on the active enterprise context")
return cmdutil.CreateAlias(getState, "enterprise get-state")
}
func SyncContextsCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
syncContexts := &cobra.Command{
Short: "Pull all available Pachyderm Cluster contexts into your pachctl config",
Long: "Pull all available Pachyderm Cluster contexts into your pachctl config",
Run: cmdutil.Run(func(args []string) error {
cfg, err := config.Read(false, false)
if err != nil {
return err
}
ec, err := pachctlCfg.NewOnUserMachine(ctx, true)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer ec.Close()
resp, err := ec.License.ListUserClusters(ec.Ctx(), &license.ListUserClustersRequest{})
if err != nil {
return errors.EnsureStack(err)
}
// update the pach_address of all existing contexts, and add the rest as well.
for _, cluster := range resp.Clusters {
if context, ok := cfg.V2.Contexts[cluster.Id]; ok {
// reset the session token if the context is pointing to a new cluster deployment
if cluster.ClusterDeploymentId != context.ClusterDeploymentID {
context.ClusterDeploymentID = cluster.ClusterDeploymentId
context.SessionToken = ""
}
context.PachdAddress = cluster.Address
context.EnterpriseServer = cluster.EnterpriseServer
} else {
cfg.V2.Contexts[cluster.Id] = &config.Context{
ClusterDeploymentID: cluster.ClusterDeploymentId,
PachdAddress: cluster.Address,
Source: config.ContextSource_IMPORTED,
EnterpriseServer: cluster.EnterpriseServer,
}
}
}
err = cfg.Write()
if err != nil {
return err
}
return nil
}),
}
return cmdutil.CreateAlias(syncContexts, "enterprise sync-contexts")
}
// HeartbeatCmd triggers an explicit heartbeat to the license server
func HeartbeatCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
var isEnterprise bool
heartbeat := &cobra.Command{
Short: "Sync the enterprise state with the license server immediately.",
Long: "Sync the enterprise state with the license server immediately.",
Run: cmdutil.Run(func(args []string) error {
c, err := pachctlCfg.NewOnUserMachine(ctx, isEnterprise)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer c.Close()
_, err = c.Enterprise.Heartbeat(c.Ctx(), &enterprise.HeartbeatRequest{})
if err != nil {
return errors.Wrapf(err, "could not sync with license server")
}
return nil
}),
}
heartbeat.PersistentFlags().BoolVar(&isEnterprise, "enterprise", false, "Make the enterprise server refresh its state")
return cmdutil.CreateAlias(heartbeat, "enterprise heartbeat")
}
// PauseCmd pauses the cluster.
func PauseCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
pause := &cobra.Command{
Short: "Pause the cluster.",
Long: "Pause the cluster.",
Run: cmdutil.Run(func(args []string) error {
c, err := pachctlCfg.NewOnUserMachine(ctx, true)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer c.Close()
_, err = c.Enterprise.Pause(c.Ctx(), &enterprise.PauseRequest{})
if err != nil {
return errors.Wrapf(err, "could not pause cluster")
}
return nil
}),
}
return cmdutil.CreateAlias(pause, "enterprise pause")
}
// UnpauseCmd pauses the cluster.
func UnpauseCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
unpause := &cobra.Command{
Short: "Unpause the cluster.",
Long: "Unpause the cluster.",
Run: cmdutil.Run(func(args []string) error {
c, err := pachctlCfg.NewOnUserMachine(ctx, true)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer c.Close()
_, err = c.Enterprise.Unpause(c.Ctx(), &enterprise.UnpauseRequest{})
if err != nil {
return errors.Wrapf(err, "could not unpause cluster")
}
return nil
}),
}
return cmdutil.CreateAlias(unpause, "enterprise unpause")
}
// PauseStatusCmd returns the pause status of the cluster: unpaused; partially
// paused; or completely paused.
func PauseStatusCmd(ctx context.Context, pachctlCfg *pachctl.Config) *cobra.Command {
pauseStatus := &cobra.Command{
Short: "Get the pause status of the cluster.",
Long: "Get the pause the cluster: normal, partially-paused or paused.",
Run: cmdutil.Run(func(args []string) error {
c, err := pachctlCfg.NewOnUserMachine(ctx, true)
if err != nil {
return errors.Wrapf(err, "could not connect")
}
defer c.Close()
resp, err := c.Enterprise.PauseStatus(c.Ctx(), &enterprise.PauseStatusRequest{})
if err != nil {
return errors.Wrapf(err, "could not get pause status")
}
switch resp.Status {
case enterprise.PauseStatusResponse_UNPAUSED:
fmt.Println("unpaused")
case enterprise.PauseStatusResponse_PARTIALLY_PAUSED:
fmt.Println("partially-paused")
case enterprise.PauseStatusResponse_PAUSED:
fmt.Println("paused")
}
return nil
}),
}
return cmdutil.CreateAlias(pauseStatus, "enterprise pause-status")
}
// Cmds returns pachctl commands related to Pachyderm Enterprise
func Cmds(mainCtx context.Context, pachctlCfg *pachctl.Config) []*cobra.Command {
var commands []*cobra.Command
enterprise := &cobra.Command{
Short: "Enterprise commands enable Pachyderm Enterprise features",
Long: "Enterprise commands enable Pachyderm Enterprise features",
}
commands = append(commands, cmdutil.CreateAlias(enterprise, "enterprise"))
commands = append(commands, RegisterCmd(mainCtx, pachctlCfg))
commands = append(commands, DeactivateCmd(mainCtx, pachctlCfg))
commands = append(commands, GetStateCmd(mainCtx, pachctlCfg))
commands = append(commands, SyncContextsCmd(mainCtx, pachctlCfg))
commands = append(commands, HeartbeatCmd(mainCtx, pachctlCfg))
commands = append(commands, PauseCmd(mainCtx, pachctlCfg))
commands = append(commands, UnpauseCmd(mainCtx, pachctlCfg))
commands = append(commands, PauseStatusCmd(mainCtx, pachctlCfg))
return commands
}