github.com/pachyderm/pachyderm@v1.13.4/src/server/enterprise/cmds/cmds.go (about) 1 package cmds 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/pachyderm/pachyderm/src/client" 8 "github.com/pachyderm/pachyderm/src/client/enterprise" 9 "github.com/pachyderm/pachyderm/src/client/pkg/errors" 10 "github.com/pachyderm/pachyderm/src/server/pkg/cmdutil" 11 12 "github.com/gogo/protobuf/types" 13 "github.com/spf13/cobra" 14 ) 15 16 // Unfortunately, Go's pre-defined format strings for parsing RFC-3339-compliant 17 // timestamps aren't exhaustive. This method attempts to parse a larger set of 18 // of ISO-8601-compatible timestamps (which are themselves a subset of RFC-3339 19 // timestamps) 20 func parseISO8601(s string) (time.Time, error) { 21 t, err := time.Parse(time.RFC3339, s) 22 if err == nil { 23 return t, nil 24 } 25 t, err = time.Parse("2006-01-02T15:04:05Z0700", s) 26 if err == nil { 27 return t, nil 28 } 29 return time.Time{}, errors.Errorf("could not parse \"%s\" as any of %v", s, []string{time.RFC3339, "2006-01-02T15:04:05Z0700"}) 30 } 31 32 // ActivateCmd returns a cobra.Command to activate the enterprise features of 33 // Pachyderm within a Pachyderm cluster. All repos will go from 34 // publicly-accessible to accessible only by the owner, who can subsequently add 35 // users 36 func ActivateCmd() *cobra.Command { 37 var expires string 38 activate := &cobra.Command{ 39 Use: "{{alias}}", 40 Short: "Activate the enterprise features of Pachyderm with an activation " + 41 "code", 42 Long: "Activate the enterprise features of Pachyderm with an activation " + 43 "code", 44 Run: cmdutil.RunFixedArgs(0, func(args []string) error { 45 // request the enterprise key 46 key, err := cmdutil.ReadPassword("Enterprise key: ") 47 if err != nil { 48 return errors.Wrapf(err, "could not read enterprise key") 49 } 50 51 c, err := client.NewOnUserMachine("user") 52 if err != nil { 53 return errors.Wrapf(err, "could not connect") 54 } 55 defer c.Close() 56 req := &enterprise.ActivateRequest{} 57 req.ActivationCode = key 58 if expires != "" { 59 t, err := parseISO8601(expires) 60 if err != nil { 61 return errors.Wrapf(err, "could not parse the timestamp \"%s\"", expires) 62 } 63 req.Expires, err = types.TimestampProto(t) 64 if err != nil { 65 return errors.Wrapf(err, "error converting expiration time \"%s\"", t.String()) 66 } 67 } 68 resp, err := c.Enterprise.Activate(c.Ctx(), req) 69 if err != nil { 70 return err 71 } 72 ts, err := types.TimestampFromProto(resp.Info.Expires) 73 if err != nil { 74 return errors.Wrapf(err, "activation request succeeded, but could not "+ 75 "convert token expiration time to a timestamp", err) 76 } 77 fmt.Printf("Activation succeeded. Your Pachyderm Enterprise token "+ 78 "expires %s\n", ts.String()) 79 return nil 80 }), 81 } 82 activate.PersistentFlags().StringVar(&expires, "expires", "", "A timestamp "+ 83 "indicating when the token provided above should expire (formatted as an "+ 84 "RFC 3339/ISO 8601 datetime). This is only applied if it's earlier than "+ 85 "the signed expiration time encoded in 'activation-code', and therefore "+ 86 "is only useful for testing.") 87 88 return cmdutil.CreateAlias(activate, "enterprise activate") 89 } 90 91 // GetStateCmd returns a cobra.Command to activate the enterprise features of 92 // Pachyderm within a Pachyderm cluster. All repos will go from 93 // publicly-accessible to accessible only by the owner, who can subsequently add 94 // users 95 func GetStateCmd() *cobra.Command { 96 getState := &cobra.Command{ 97 Short: "Check whether the Pachyderm cluster has enterprise features " + 98 "activated", 99 Long: "Check whether the Pachyderm cluster has enterprise features " + 100 "activated", 101 Run: cmdutil.Run(func(args []string) error { 102 c, err := client.NewOnUserMachine("user") 103 if err != nil { 104 return errors.Wrapf(err, "could not connect") 105 } 106 defer c.Close() 107 resp, err := c.Enterprise.GetState(c.Ctx(), &enterprise.GetStateRequest{}) 108 if err != nil { 109 return err 110 } 111 if resp.State == enterprise.State_NONE { 112 fmt.Println("No Pachyderm Enterprise token was found") 113 return nil 114 } 115 ts, err := types.TimestampFromProto(resp.Info.Expires) 116 if err != nil { 117 return errors.Wrapf(err, "activation request succeeded, but could not "+ 118 "convert token expiration time to a timestamp") 119 } 120 fmt.Printf("Pachyderm Enterprise token state: %s\nExpiration: %s\n", 121 resp.State.String(), ts.String()) 122 return nil 123 }), 124 } 125 return cmdutil.CreateAlias(getState, "enterprise get-state") 126 } 127 128 // Cmds returns pachctl commands related to Pachyderm Enterprise 129 func Cmds() []*cobra.Command { 130 var commands []*cobra.Command 131 132 enterprise := &cobra.Command{ 133 Short: "Enterprise commands enable Pachyderm Enterprise features", 134 Long: "Enterprise commands enable Pachyderm Enterprise features", 135 } 136 commands = append(commands, cmdutil.CreateAlias(enterprise, "enterprise")) 137 138 commands = append(commands, ActivateCmd()) 139 commands = append(commands, GetStateCmd()) 140 141 return commands 142 }