diff --git a/cli/cmd/enterprise.go b/cli/cmd/enterprise.go deleted file mode 100644 index 92c80c907..000000000 --- a/cli/cmd/enterprise.go +++ /dev/null @@ -1,63 +0,0 @@ -package cmd - -import ( - "io/ioutil" - "os" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/pkg/enterpriseclient" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseCommand(parent *cobra.Command) *cobra.Command { - enterpriseCommand := &cobra.Command{ - Use: "enterprise", - Short: "Manage enterprise channels, policies and installers", - SilenceUsage: true, - Long: `The enterprise command allows approved enterprise to create custom installers, release channels and policies for vendors`, - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - if cmd.Use == "init" { - r.enterpriseClient = enterpriseclient.NewHTTPClient(enterpriseOrigin, nil) - return nil - } - - if enterprisePrivateKeyPath == "" { - enterprisePrivateKeyPath = os.Getenv("REPLICATED_PRIVATEKEY") - if enterprisePrivateKeyPath == "" { - return errors.New("missing private key") - } - } - - if _, err := os.Stat(enterprisePrivateKeyPath); err != nil { - if os.IsNotExist(err) { - return errors.Errorf("file %s does not exist", enterprisePrivateKeyPath) - } - - return err - } - - privateKeyContents, err := ioutil.ReadFile(enterprisePrivateKeyPath) - if err != nil { - return err - } - - r.enterpriseClient = enterpriseclient.NewHTTPClient(enterpriseOrigin, privateKeyContents) - - return nil - }, - } - parent.AddCommand(enterpriseCommand) - - // TODO remove the app and token persistent flags - - enterpriseCommand.PersistentFlags().StringVar(&enterprisePrivateKeyPath, "private-key", enterprisePrivateKeyPath, "Path to the private key used to sign requests") - - return enterpriseCommand -} - -func homeDir() string { - if h := os.Getenv("HOME"); h != "" { - return h - } - return os.Getenv("USERPROFILE") -} diff --git a/cli/cmd/enterprise_auth.go b/cli/cmd/enterprise_auth.go deleted file mode 100644 index d716a7127..000000000 --- a/cli/cmd/enterprise_auth.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseAuth(parent *cobra.Command) *cobra.Command { - enterpriseAuthCommand := &cobra.Command{ - Use: "auth", - Short: "Manage enterprise authentication", - Long: `The auth command manages authentication`, - } - parent.AddCommand(enterpriseAuthCommand) - - return enterpriseAuthCommand -} diff --git a/cli/cmd/enterprise_auth_approve.go b/cli/cmd/enterprise_auth_approve.go deleted file mode 100644 index 15da4ad89..000000000 --- a/cli/cmd/enterprise_auth_approve.go +++ /dev/null @@ -1,31 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseAuthApprove(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "approve", - SilenceUsage: true, - Short: "approve an auth key request", - Long: `approve an auth key request given a fingerprint - - Example: - replicated enteprise auth approve --fingerprint `, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseAuthApproveFingerprint, "fingerprint", "", "The fingerprint provided on auth init") - - cmd.RunE = r.enterpriseAuthApprove -} - -func (r *runners) enterpriseAuthApprove(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.AuthApprove(r.args.enterpriseAuthApproveFingerprint) - if err != nil { - return err - } - - return nil -} diff --git a/cli/cmd/enterprise_auth_init.go b/cli/cmd/enterprise_auth_init.go deleted file mode 100644 index 3ea31eb9a..000000000 --- a/cli/cmd/enterprise_auth_init.go +++ /dev/null @@ -1,27 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseAuthInit(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "init", - Short: "initialize authentication", - Long: `Create a keypair to begin authentication`, - SilenceUsage: true, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseAuthInitCreateOrg, "create-org", "", "If this flag is provided, a new organization will be created with the specified name. If not, the auth request will have to be approved by Replicated or your already authenticated organization") - - cmd.RunE = r.enterpriseAuthInit -} - -func (r *runners) enterpriseAuthInit(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.AuthInit(r.args.enterpriseAuthInitCreateOrg) - if err != nil { - return err - } - return nil -} diff --git a/cli/cmd/enterprise_channel.go b/cli/cmd/enterprise_channel.go deleted file mode 100644 index 63f776b93..000000000 --- a/cli/cmd/enterprise_channel.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseChannel(parent *cobra.Command) *cobra.Command { - enterpriseChannelCommand := &cobra.Command{ - Use: "channel", - Short: "Manage enterprise channels", - Long: `The channel command allows approved enterprise to create custom release channels`, - } - parent.AddCommand(enterpriseChannelCommand) - - return enterpriseChannelCommand -} diff --git a/cli/cmd/enterprise_channel_assign.go b/cli/cmd/enterprise_channel_assign.go deleted file mode 100644 index db559b52b..000000000 --- a/cli/cmd/enterprise_channel_assign.go +++ /dev/null @@ -1,37 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseChannelAssign(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "assign", - SilenceUsage: true, - Short: "assign a channel to a team", - Long: `Assign a channel to a team. - - Example: - replicated enteprise channel assign --channel-id ChannelID --team-id TeamID`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseChannelAssignChannelID, "channel-id", "", "The id of the channel to be assigned") - cmd.Flags().StringVar(&r.args.enterpriseChannelAssignTeamID, "team-id", "", "The id of the team to assign the channel to") - - cmd.RunE = r.enterpriseChannelAssign -} - -func (r *runners) enterpriseChannelAssign(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.AssignChannel(r.args.enterpriseChannelAssignChannelID, r.args.enterpriseChannelAssignTeamID) - if err != nil { - return err - } - - fmt.Fprintf(r.w, "Channel successfully assigned\n") - r.w.Flush() - - return nil -} diff --git a/cli/cmd/enterprise_channel_create.go b/cli/cmd/enterprise_channel_create.go deleted file mode 100644 index 10f3d39be..000000000 --- a/cli/cmd/enterprise_channel_create.go +++ /dev/null @@ -1,35 +0,0 @@ -package cmd - -import ( - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseChannelCreate(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "create", - SilenceUsage: true, - Short: "Create a new shared release channel", - Long: `Create a new shared release channel for vendors. - - Example: - replicated enteprise channel create --name SomeBigBank --description 'The release channel for SomeBigBank'`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseChannelCreateName, "name", "", "The name of this channel") - cmd.Flags().StringVar(&r.args.enterpriseChannelCreateDescription, "description", "", "A longer description of this channel") - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - cmd.RunE = r.enterpriseChannelCreate -} - -func (r *runners) enterpriseChannelCreate(cmd *cobra.Command, args []string) error { - channel, err := r.enterpriseClient.CreateChannel(r.args.enterpriseChannelCreateName, r.args.enterpriseChannelCreateDescription) - if err != nil { - return err - } - - print.EnterpriseChannel(r.outputFormat, r.w, channel) - return nil -} diff --git a/cli/cmd/enterprise_channel_ls.go b/cli/cmd/enterprise_channel_ls.go deleted file mode 100644 index 3a0f8628b..000000000 --- a/cli/cmd/enterprise_channel_ls.go +++ /dev/null @@ -1,30 +0,0 @@ -package cmd - -import ( - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseChannelLS(parent *cobra.Command) *cobra.Command { - cmd := &cobra.Command{ - Use: "ls", - Short: "lists enterprise channels", - Long: `lists all channels that have been created`, - RunE: r.enterpriseChannelList, - SilenceUsage: true, - } - parent.AddCommand(cmd) - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - return cmd -} - -func (r *runners) enterpriseChannelList(cmd *cobra.Command, args []string) error { - channels, err := r.enterpriseClient.ListChannels() - if err != nil { - return err - } - - print.EnterpriseChannels(r.outputFormat, r.w, channels) - return nil -} diff --git a/cli/cmd/enterprise_channel_rm.go b/cli/cmd/enterprise_channel_rm.go deleted file mode 100644 index e21cb3121..000000000 --- a/cli/cmd/enterprise_channel_rm.go +++ /dev/null @@ -1,36 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseChannelRM(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "rm", - SilenceUsage: true, - Short: "Remove a channel", - Long: `Remove a channel. - - Example: - replicated enteprise channel rm --id MyChannelID`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseChannelRmId, "id", "", "The id of the channel to remove") - - cmd.RunE = r.enterpriseChannelRemove -} - -func (r *runners) enterpriseChannelRemove(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.RemoveChannel(r.args.enterpriseChannelRmId) - if err != nil { - return err - } - - fmt.Fprintf(r.w, "Channel %s successfully removed\n", r.args.enterpriseChannelRmId) - r.w.Flush() - - return nil -} diff --git a/cli/cmd/enterprise_channel_update.go b/cli/cmd/enterprise_channel_update.go deleted file mode 100644 index 1f483a975..000000000 --- a/cli/cmd/enterprise_channel_update.go +++ /dev/null @@ -1,36 +0,0 @@ -package cmd - -import ( - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseChannelUpdate(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "update", - SilenceUsage: true, - Short: "update an existing release channel", - Long: `Update an existing shared release channel. - - Example: - replicated enteprise channel update --id MyChannelID --name SomeBigBank --description 'The release channel for SomeBigBank'`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseChannelUpdateID, "id", "", "The id of the channel to be updated") - cmd.Flags().StringVar(&r.args.enterpriseChannelUpdateName, "name", "", "The new name for this channel") - cmd.Flags().StringVar(&r.args.enterpriseChannelUpdateDescription, "description", "", "The new description of this channel") - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - cmd.RunE = r.enterpriseChannelUpdate -} - -func (r *runners) enterpriseChannelUpdate(cmd *cobra.Command, args []string) error { - channel, err := r.enterpriseClient.UpdateChannel(r.args.enterpriseChannelUpdateID, r.args.enterpriseChannelUpdateName, r.args.enterpriseChannelUpdateDescription) - if err != nil { - return err - } - - print.EnterpriseChannel(r.outputFormat, r.w, channel) - return nil -} diff --git a/cli/cmd/enterprise_installer.go b/cli/cmd/enterprise_installer.go deleted file mode 100644 index 5b0b30dc4..000000000 --- a/cli/cmd/enterprise_installer.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseInstaller(parent *cobra.Command) *cobra.Command { - enterpriseInstallerCommand := &cobra.Command{ - Use: "installer", - Short: "Manage enterprise installers", - Long: `The installer command allows approved enterprise to create custom installers`, - } - parent.AddCommand(enterpriseInstallerCommand) - - return enterpriseInstallerCommand -} diff --git a/cli/cmd/enterprise_installer_assign.go b/cli/cmd/enterprise_installer_assign.go deleted file mode 100644 index 524a2bd7b..000000000 --- a/cli/cmd/enterprise_installer_assign.go +++ /dev/null @@ -1,37 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseInstallerAssign(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "assign", - SilenceUsage: true, - Short: "Assigns an installer to a channel", - Long: `Assigns an installer to a channel. - - Example: - replicated enteprise installer assign --installer-id 123 --channel-id abc`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseInstallerAssignInstallerID, "installer-id", "", "The id of the installer to assign") - cmd.Flags().StringVar(&r.args.enterpriseInstallerAssignChannelID, "channel-id", "", "The id of channel") - - cmd.RunE = r.enterpriseInstallerAssign -} - -func (r *runners) enterpriseInstallerAssign(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.AssignInstaller(r.args.enterpriseInstallerAssignInstallerID, r.args.enterpriseInstallerAssignChannelID) - if err != nil { - return err - } - - fmt.Fprintf(r.w, "Installer successfully assigned\n") - r.w.Flush() - - return nil -} diff --git a/cli/cmd/enterprise_installer_create.go b/cli/cmd/enterprise_installer_create.go deleted file mode 100644 index 86f6a3125..000000000 --- a/cli/cmd/enterprise_installer_create.go +++ /dev/null @@ -1,42 +0,0 @@ -package cmd - -import ( - "io/ioutil" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseInstallerCreate(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "create", - SilenceUsage: true, - Short: "Create a new custom installer", - Long: `Create a new custom installer. - - Example: - replicated enteprise installer create --yaml-file myinstaller.yaml`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseInstallerCreateFile, "yaml-file", "", "The filename containing the installer yaml") - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - cmd.RunE = r.enterpriseInstallerCreate -} - -func (r *runners) enterpriseInstallerCreate(cmd *cobra.Command, args []string) error { - b, err := ioutil.ReadFile(r.args.enterpriseInstallerCreateFile) - if err != nil { - return errors.Wrap(err, "failed to read file") - } - - installer, err := r.enterpriseClient.CreateInstaller(string(b)) - if err != nil { - return err - } - - print.EnterpriseInstaller(r.outputFormat, r.w, installer) - return nil -} diff --git a/cli/cmd/enterprise_installer_ls.go b/cli/cmd/enterprise_installer_ls.go deleted file mode 100644 index 70653db14..000000000 --- a/cli/cmd/enterprise_installer_ls.go +++ /dev/null @@ -1,30 +0,0 @@ -package cmd - -import ( - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseInstallerLS(parent *cobra.Command) *cobra.Command { - cmd := &cobra.Command{ - Use: "ls", - Short: "lists enterprise installers", - Long: `lists all installers that have been created`, - RunE: r.enterpriseInstallerList, - SilenceUsage: true, - } - parent.AddCommand(cmd) - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - return cmd -} - -func (r *runners) enterpriseInstallerList(cmd *cobra.Command, args []string) error { - installers, err := r.enterpriseClient.ListInstallers() - if err != nil { - return err - } - - print.EnterpriseInstallers(r.outputFormat, r.w, installers) - return nil -} diff --git a/cli/cmd/enterprise_installer_rm.go b/cli/cmd/enterprise_installer_rm.go deleted file mode 100644 index c63a781dd..000000000 --- a/cli/cmd/enterprise_installer_rm.go +++ /dev/null @@ -1,36 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseInstallerRM(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "rm", - SilenceUsage: true, - Short: "Remove an installer", - Long: `Remove an installer. - - Example: - replicated enteprise installer rm --id MyInstallerID`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseInstallerRmId, "id", "", "The id of the installer to remove") - - cmd.RunE = r.enterpriseInstallerRemove -} - -func (r *runners) enterpriseInstallerRemove(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.RemoveInstaller(r.args.enterpriseInstallerRmId) - if err != nil { - return err - } - - fmt.Fprintf(r.w, "Installer %s successfully removed\n", r.args.enterpriseInstallerRmId) - r.w.Flush() - - return nil -} diff --git a/cli/cmd/enterprise_installer_update.go b/cli/cmd/enterprise_installer_update.go deleted file mode 100644 index 60c2743c9..000000000 --- a/cli/cmd/enterprise_installer_update.go +++ /dev/null @@ -1,43 +0,0 @@ -package cmd - -import ( - "io/ioutil" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterpriseInstallerUpdate(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "update", - SilenceUsage: true, - Short: "update an existing installer", - Long: `Update an existing installer. - - Example: - replicated enteprise installer update --id MyInstallerID --yaml-file myinstaller.yaml`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterpriseInstallerUpdateID, "id", "", "The id of the installer to be updated") - cmd.Flags().StringVar(&r.args.enterpriseInstallerUpdateFile, "yaml-file", "", "The filename containing the installer yaml") - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - cmd.RunE = r.enterpriseInstallerUpdate -} - -func (r *runners) enterpriseInstallerUpdate(cmd *cobra.Command, args []string) error { - b, err := ioutil.ReadFile(r.args.enterpriseInstallerUpdateFile) - if err != nil { - return errors.Wrap(err, "failed to read file") - } - - installer, err := r.enterpriseClient.UpdateInstaller(r.args.enterpriseInstallerUpdateID, string(b)) - if err != nil { - return err - } - - print.EnterpriseInstaller(r.outputFormat, r.w, installer) - return nil -} diff --git a/cli/cmd/enterprise_policy.go b/cli/cmd/enterprise_policy.go deleted file mode 100644 index 67e558700..000000000 --- a/cli/cmd/enterprise_policy.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterprisePolicy(parent *cobra.Command) *cobra.Command { - enterprisePolicyCommand := &cobra.Command{ - Use: "policy", - Short: "Manage enterprise policies", - Long: `The policy command allows approved enterprise to create and manage policies`, - } - parent.AddCommand(enterprisePolicyCommand) - - return enterprisePolicyCommand -} diff --git a/cli/cmd/enterprise_policy_assign.go b/cli/cmd/enterprise_policy_assign.go deleted file mode 100644 index 506df369d..000000000 --- a/cli/cmd/enterprise_policy_assign.go +++ /dev/null @@ -1,37 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterprisePolicyAssign(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "assign", - SilenceUsage: true, - Short: "Assigns a policy to a channel", - Long: `Assigns a policy to a channel. - - Example: - replicated enteprise policy assign --policy-id 123 --channel-id abc`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterprisePolicyAssignPolicyID, "policy-id", "", "The id of the policy to assign") - cmd.Flags().StringVar(&r.args.enterprisePolicyAssignChannelID, "channel-id", "", "The id of channel") - - cmd.RunE = r.enterprisePolicyAssign -} - -func (r *runners) enterprisePolicyAssign(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.AssignPolicy(r.args.enterprisePolicyAssignPolicyID, r.args.enterprisePolicyAssignChannelID) - if err != nil { - return err - } - - fmt.Fprintf(r.w, "Policy successfully assigned\n") - r.w.Flush() - - return nil -} diff --git a/cli/cmd/enterprise_policy_create.go b/cli/cmd/enterprise_policy_create.go deleted file mode 100644 index d11cbdeba..000000000 --- a/cli/cmd/enterprise_policy_create.go +++ /dev/null @@ -1,44 +0,0 @@ -package cmd - -import ( - "os" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterprisePolicyCreate(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "create", - SilenceUsage: true, - Short: "Create a new policy", - Long: `Create a new policy that can later be assigned to a channel. - - Example: - replicated enteprise policy create --policy-file myfile.rego --name MyPolicy --description 'A sample policy'`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterprisePolicyCreateName, "name", "", "The name of this policy") - cmd.Flags().StringVar(&r.args.enterprisePolicyCreateDescription, "description", "", "A longer description of this policy") - cmd.Flags().StringVar(&r.args.enterprisePolicyCreateFile, "policy-file", "", "The filename containing an OPA policy") - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - cmd.RunE = r.enterprisePolicyCreate -} - -func (r *runners) enterprisePolicyCreate(cmd *cobra.Command, args []string) error { - b, err := os.ReadFile(r.args.enterprisePolicyCreateFile) - if err != nil { - return errors.Wrap(err, "failed to read file") - } - - policy, err := r.enterpriseClient.CreatePolicy(r.args.enterprisePolicyCreateName, r.args.enterprisePolicyCreateDescription, string(b)) - if err != nil { - return err - } - - print.EnterprisePolicy(r.outputFormat, r.w, policy) - return nil -} diff --git a/cli/cmd/enterprise_policy_ls.go b/cli/cmd/enterprise_policy_ls.go deleted file mode 100644 index c6e334b77..000000000 --- a/cli/cmd/enterprise_policy_ls.go +++ /dev/null @@ -1,38 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterprisePolicyLS(parent *cobra.Command) *cobra.Command { - cmd := &cobra.Command{ - Use: "ls", - Short: "lists enterprise policies", - Long: `lists all policies that have been created`, - RunE: r.enterprisePolicyList, - SilenceUsage: true, - } - parent.AddCommand(cmd) - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - return cmd -} - -func (r *runners) enterprisePolicyList(cmd *cobra.Command, args []string) error { - policies, err := r.enterpriseClient.ListPolicies() - if err != nil { - return err - } - - if len(policies) == 0 { - fmt.Fprintf(r.w, "No policies found. Create one with \"replicated enterprise policy create\"\n") - r.w.Flush() - return nil - } - - print.EnterprisePolicies(r.outputFormat, r.w, policies) - return nil -} diff --git a/cli/cmd/enterprise_policy_rm.go b/cli/cmd/enterprise_policy_rm.go deleted file mode 100644 index 7fb15c502..000000000 --- a/cli/cmd/enterprise_policy_rm.go +++ /dev/null @@ -1,36 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterprisePolicyRM(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "rm", - SilenceUsage: true, - Short: "Remove a policy", - Long: `Remove a policy. - - Example: - replicated enteprise policy rm --id MyPolicyID`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterprisePolicyRmId, "id", "", "The id of the policy to remove") - - cmd.RunE = r.enterprisePolicyRemove -} - -func (r *runners) enterprisePolicyRemove(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.RemovePolicy(r.args.enterprisePolicyRmId) - if err != nil { - return err - } - - fmt.Fprintf(r.w, "Policy %s successfully removed\n", r.args.enterprisePolicyRmId) - r.w.Flush() - - return nil -} diff --git a/cli/cmd/enterprise_policy_unassign.go b/cli/cmd/enterprise_policy_unassign.go deleted file mode 100644 index be620dc9e..000000000 --- a/cli/cmd/enterprise_policy_unassign.go +++ /dev/null @@ -1,37 +0,0 @@ -package cmd - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterprisePolicyUnassign(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "unassign", - SilenceUsage: true, - Short: "Unassigns a policy from a channel", - Long: `Remove a new policy from a channel. - - Example: - replicated enteprise policy unassign --policy-id 123 --channel-id abc`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterprisePolicyUnassignPolicyID, "policy-id", "", "The id of the policy to unassign") - cmd.Flags().StringVar(&r.args.enterprisePolicyUnassignChannelID, "channel-id", "", "The id of channel") - - cmd.RunE = r.enterprisePolicyUnassign -} - -func (r *runners) enterprisePolicyUnassign(cmd *cobra.Command, args []string) error { - err := r.enterpriseClient.UnassignPolicy(r.args.enterprisePolicyUnassignPolicyID, r.args.enterprisePolicyUnassignChannelID) - if err != nil { - return err - } - - fmt.Fprintf(r.w, "Policy successfully unassigned\n") - r.w.Flush() - - return nil -} diff --git a/cli/cmd/enterprise_policy_update.go b/cli/cmd/enterprise_policy_update.go deleted file mode 100644 index be751ae15..000000000 --- a/cli/cmd/enterprise_policy_update.go +++ /dev/null @@ -1,45 +0,0 @@ -package cmd - -import ( - "os" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/cli/print" - "github.com/spf13/cobra" -) - -func (r *runners) InitEnterprisePolicyUpdate(parent *cobra.Command) { - cmd := &cobra.Command{ - Use: "update", - SilenceUsage: true, - Short: "update an existing policy", - Long: `Update an existing policy. - - Example: - replicated enteprise policy update --id MyPolicyID --policy-file myfile.rego --name MyPolicy --description 'A sample policy'`, - } - parent.AddCommand(cmd) - - cmd.Flags().StringVar(&r.args.enterprisePolicyUpdateID, "id", "", "The id of the policy to be updated") - cmd.Flags().StringVar(&r.args.enterprisePolicyUpdateName, "name", "", "The new name for this policy") - cmd.Flags().StringVar(&r.args.enterprisePolicyUpdateDescription, "description", "", "The new description of this policy") - cmd.Flags().StringVar(&r.args.enterprisePolicyUpdateFile, "policy-file", "", "The filename containing an OPA policy") - cmd.Flags().StringVar(&r.outputFormat, "output", "table", "The output format to use. One of: json|table (default: table)") - - cmd.RunE = r.enterprisePolicyUpdate -} - -func (r *runners) enterprisePolicyUpdate(cmd *cobra.Command, args []string) error { - b, err := os.ReadFile(r.args.enterprisePolicyUpdateFile) - if err != nil { - return errors.Wrap(err, "failed to read file") - } - - policy, err := r.enterpriseClient.UpdatePolicy(r.args.enterprisePolicyUpdateID, r.args.enterprisePolicyUpdateName, r.args.enterprisePolicyUpdateDescription, string(b)) - if err != nil { - return err - } - - print.EnterprisePolicy(r.outputFormat, r.w, policy) - return nil -} diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 6d693b7e7..a544a62bf 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -4,7 +4,6 @@ import ( "fmt" "io" "os" - "path/filepath" "strings" "text/tabwriter" @@ -31,21 +30,14 @@ const ( var appSlugOrID string var apiToken string -var enterprisePrivateKeyPath = filepath.Join(homeDir(), ".replicated", "enterprise", "ecdsa") var platformOrigin = "https://api.replicated.com/vendor" var kurlDotSHOrigin = "https://kurl.sh" -var enterpriseOrigin = "https://api.replicated.com/enterprise" func init() { originFromEnv := os.Getenv("REPLICATED_API_ORIGIN") if originFromEnv != "" { platformOrigin = originFromEnv } - - enterpriseOriginFromEnv := os.Getenv("REPLICATED_ENTERPRISE_ORIGIN") - if enterpriseOriginFromEnv != "" { - enterpriseOrigin = enterpriseOriginFromEnv - } } // RootCmd represents the base command when called without any subcommands @@ -171,30 +163,6 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i runCmds.InitInstallerCreate(installerCmd) runCmds.InitInstallerList(installerCmd) - enterpriseCmd := runCmds.InitEnterpriseCommand(runCmds.rootCmd) - enterpriseAuthCmd := runCmds.InitEnterpriseAuth(enterpriseCmd) - runCmds.InitEnterpriseAuthInit(enterpriseAuthCmd) - runCmds.InitEnterpriseAuthApprove(enterpriseAuthCmd) - enterpriseChannelCmd := runCmds.InitEnterpriseChannel(enterpriseCmd) - runCmds.InitEnterpriseChannelLS(enterpriseChannelCmd) - runCmds.InitEnterpriseChannelCreate(enterpriseChannelCmd) - runCmds.InitEnterpriseChannelUpdate(enterpriseChannelCmd) - runCmds.InitEnterpriseChannelRM(enterpriseChannelCmd) - runCmds.InitEnterpriseChannelAssign(enterpriseChannelCmd) - enterprisePolicyCmd := runCmds.InitEnterprisePolicy(enterpriseCmd) - runCmds.InitEnterprisePolicyLS(enterprisePolicyCmd) - runCmds.InitEnterprisePolicyCreate(enterprisePolicyCmd) - runCmds.InitEnterprisePolicyUpdate(enterprisePolicyCmd) - runCmds.InitEnterprisePolicyRM(enterprisePolicyCmd) - runCmds.InitEnterprisePolicyAssign(enterprisePolicyCmd) - runCmds.InitEnterprisePolicyUnassign(enterprisePolicyCmd) - enterpriseInstallerCmd := runCmds.InitEnterpriseInstaller(enterpriseCmd) - runCmds.InitEnterpriseInstallerLS(enterpriseInstallerCmd) - runCmds.InitEnterpriseInstallerCreate(enterpriseInstallerCmd) - runCmds.InitEnterpriseInstallerUpdate(enterpriseInstallerCmd) - runCmds.InitEnterpriseInstallerRM(enterpriseInstallerCmd) - runCmds.InitEnterpriseInstallerAssign(enterpriseInstallerCmd) - appCmd := runCmds.InitAppCommand(runCmds.rootCmd) runCmds.InitAppList(appCmd) runCmds.InitAppCreate(appCmd) @@ -401,3 +369,10 @@ func parseTags(tags []string) ([]types.Tag, error) { } return parsedTags, nil } + +func homeDir() string { + if h := os.Getenv("HOME"); h != "" { + return h + } + return os.Getenv("USERPROFILE") +} diff --git a/cli/cmd/runner.go b/cli/cmd/runner.go index fba82650d..eeafab583 100644 --- a/cli/cmd/runner.go +++ b/cli/cmd/runner.go @@ -6,7 +6,6 @@ import ( "time" "github.com/replicatedhq/replicated/client" - "github.com/replicatedhq/replicated/pkg/enterpriseclient" "github.com/replicatedhq/replicated/pkg/kotsclient" "github.com/replicatedhq/replicated/pkg/platformclient" "github.com/spf13/cobra" @@ -16,18 +15,17 @@ import ( // Runner holds the I/O dependencies and configurations used by individual // commands, which are defined as methods on this type. type runners struct { - appID string - appSlug string - appType string - isFoundationApp bool - api client.Client - enterpriseClient *enterpriseclient.HTTPClient - platformAPI *platformclient.HTTPClient - kotsAPI *kotsclient.VendorV3Client - stdin io.Reader - dir string - outputFormat string - w *tabwriter.Writer + appID string + appSlug string + appType string + isFoundationApp bool + api client.Client + platformAPI *platformclient.HTTPClient + kotsAPI *kotsclient.VendorV3Client + stdin io.Reader + dir string + outputFormat string + w *tabwriter.Writer rootCmd *cobra.Command args runnerArgs @@ -127,52 +125,10 @@ type runnerArgs struct { createInstallerPromote string createInstallerPromoteEnsureChannel bool - enterpriseAuthInitCreateOrg string - - enterpriseAuthApproveFingerprint string - - enterpriseChannelCreateName string - enterpriseChannelCreateDescription string - - enterpriseChannelUpdateID string - enterpriseChannelUpdateName string - enterpriseChannelUpdateDescription string - - enterpriseChannelRmId string - - enterpriseChannelAssignChannelID string - enterpriseChannelAssignTeamID string - - enterprisePolicyCreateName string - enterprisePolicyCreateDescription string - enterprisePolicyCreateFile string - - enterprisePolicyUpdateID string - enterprisePolicyUpdateName string - enterprisePolicyUpdateDescription string - enterprisePolicyUpdateFile string - - enterprisePolicyRmId string - - enterprisePolicyAssignPolicyID string - enterprisePolicyAssignChannelID string - - enterprisePolicyUnassignPolicyID string - enterprisePolicyUnassignChannelID string - - enterpriseInstallerCreateFile string - - enterpriseInstallerUpdateID string - enterpriseInstallerUpdateFile string - - enterpriseInstallerRmId string - - enterpriseInstallerAssignInstallerID string - enterpriseInstallerAssignChannelID string - customerLicenseInspectCustomer string - customerLicenseInspectOutput string - createReleaseAutoDefaults bool - createReleaseAutoDefaultsAccept bool + customerLicenseInspectCustomer string + customerLicenseInspectOutput string + createReleaseAutoDefaults bool + createReleaseAutoDefaultsAccept bool releaseDownloadDest string createInstallerAutoDefaults bool diff --git a/cli/print/enterprise_channel.go b/cli/print/enterprise_channel.go deleted file mode 100644 index e6b472f64..000000000 --- a/cli/print/enterprise_channel.go +++ /dev/null @@ -1,30 +0,0 @@ -package print - -import ( - "encoding/json" - "fmt" - "text/tabwriter" - "text/template" - - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -var enterpriseChannelTmplSrc = `ID NAME -{{ .ID }} {{ .Name }} -` - -var enterpriseChannelTmpl = template.Must(template.New("enterprisechannel").Parse(enterpriseChannelTmplSrc)) - -func EnterpriseChannel(outputFormat string, w *tabwriter.Writer, channel *enterprisetypes.Channel) error { - if outputFormat == "table" { - if err := enterpriseChannelTmpl.Execute(w, channel); err != nil { - return err - } - } else if outputFormat == "json" { - cAsByte, _ := json.MarshalIndent(channel, "", " ") - if _, err := fmt.Fprintln(w, string(cAsByte)); err != nil { - return err - } - } - return w.Flush() -} diff --git a/cli/print/enterprise_channels.go b/cli/print/enterprise_channels.go deleted file mode 100644 index 1f572cb88..000000000 --- a/cli/print/enterprise_channels.go +++ /dev/null @@ -1,31 +0,0 @@ -package print - -import ( - "encoding/json" - "fmt" - "text/tabwriter" - "text/template" - - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -var enterpriseChannelsTmplSrc = `ID NAME -{{ range . -}} -{{ .ID }} {{ .Name }} -{{ end }}` - -var enterpriseChannelsTmpl = template.Must(template.New("enterprisechannels").Parse(enterpriseChannelsTmplSrc)) - -func EnterpriseChannels(outputFormat string, w *tabwriter.Writer, channels []*enterprisetypes.Channel) error { - if outputFormat == "table" { - if err := enterpriseChannelsTmpl.Execute(w, channels); err != nil { - return err - } - } else if outputFormat == "json" { - cAsByte, _ := json.MarshalIndent(channels, "", " ") - if _, err := fmt.Fprintln(w, string(cAsByte)); err != nil { - return err - } - } - return w.Flush() -} diff --git a/cli/print/enterprise_installer.go b/cli/print/enterprise_installer.go deleted file mode 100644 index 404c6620e..000000000 --- a/cli/print/enterprise_installer.go +++ /dev/null @@ -1,31 +0,0 @@ -package print - -import ( - "encoding/json" - "fmt" - "text/tabwriter" - "text/template" - - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -var enterpriseInstallerTmplSrc = `ID -{{ .ID }} -` - -var enterpriseInstallerTmpl = template.Must(template.New("enterpriseinstaller").Parse(enterpriseInstallerTmplSrc)) - -func EnterpriseInstaller(outputFormat string, w *tabwriter.Writer, installer *enterprisetypes.Installer) error { - if outputFormat == "table" { - if err := enterpriseInstallerTmpl.Execute(w, installer); err != nil { - return err - } - } else if outputFormat == "json" { - cAsByte, _ := json.MarshalIndent(installer, "", " ") - if _, err := fmt.Fprintln(w, string(cAsByte)); err != nil { - return err - } - } - - return w.Flush() -} diff --git a/cli/print/enterprise_installers.go b/cli/print/enterprise_installers.go deleted file mode 100644 index 24900f48a..000000000 --- a/cli/print/enterprise_installers.go +++ /dev/null @@ -1,32 +0,0 @@ -package print - -import ( - "encoding/json" - "fmt" - "text/tabwriter" - "text/template" - - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -var enterpriseInstallersTmplSrc = `ID -{{ range . -}} -{{ .ID }} -{{ end }}` - -var enterpriseInstallersTmpl = template.Must(template.New("enterpriseinstallers").Parse(enterpriseInstallersTmplSrc)) - -func EnterpriseInstallers(outputFormat string, w *tabwriter.Writer, installers []*enterprisetypes.Installer) error { - if outputFormat == "table" { - if err := enterpriseInstallersTmpl.Execute(w, installers); err != nil { - return err - } - } else if outputFormat == "json" { - cAsByte, _ := json.MarshalIndent(installers, "", " ") - if _, err := fmt.Fprintln(w, string(cAsByte)); err != nil { - return err - } - } - - return w.Flush() -} diff --git a/cli/print/enterprise_policies.go b/cli/print/enterprise_policies.go deleted file mode 100644 index 4c3c2ca28..000000000 --- a/cli/print/enterprise_policies.go +++ /dev/null @@ -1,31 +0,0 @@ -package print - -import ( - "encoding/json" - "fmt" - "text/tabwriter" - "text/template" - - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -var enterprisePoliciesTmplSrc = `ID NAME -{{ range . -}} -{{ .ID }} {{ .Name }} -{{ end }}` - -var enterprisePoliciesTmpl = template.Must(template.New("enterprisepolicies").Parse(enterprisePoliciesTmplSrc)) - -func EnterprisePolicies(outputFormat string, w *tabwriter.Writer, policies []*enterprisetypes.Policy) error { - if outputFormat == "table" { - if err := enterprisePoliciesTmpl.Execute(w, policies); err != nil { - return err - } - } else if outputFormat == "json" { - cAsByte, _ := json.MarshalIndent(policies, "", " ") - if _, err := fmt.Fprintln(w, string(cAsByte)); err != nil { - return err - } - } - return w.Flush() -} diff --git a/cli/print/enterprise_policy.go b/cli/print/enterprise_policy.go deleted file mode 100644 index 5568c984e..000000000 --- a/cli/print/enterprise_policy.go +++ /dev/null @@ -1,30 +0,0 @@ -package print - -import ( - "encoding/json" - "fmt" - "text/tabwriter" - "text/template" - - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -var enterprisePolicyTmplSrc = `ID NAME -{{ .ID }} {{ .Name }} -` - -var enterprisePolicyTmpl = template.Must(template.New("entrerprisepolicy").Parse(enterprisePolicyTmplSrc)) - -func EnterprisePolicy(outputFormat string, w *tabwriter.Writer, policy *enterprisetypes.Policy) error { - if outputFormat == "table" { - if err := enterprisePolicyTmpl.Execute(w, policy); err != nil { - return err - } - } else if outputFormat == "json" { - cAsByte, _ := json.MarshalIndent(policy, "", " ") - if _, err := fmt.Fprintln(w, string(cAsByte)); err != nil { - return err - } - } - return w.Flush() -} diff --git a/pkg/enterpriseclient/auth.go b/pkg/enterpriseclient/auth.go deleted file mode 100644 index 8cbd9aeff..000000000 --- a/pkg/enterpriseclient/auth.go +++ /dev/null @@ -1,317 +0,0 @@ -package enterpriseclient - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/sha512" - "crypto/x509" - "encoding/base64" - "encoding/json" - "encoding/pem" - "fmt" - "io/ioutil" - "math/big" - "os" - "path/filepath" - "strings" - "time" - - "github.com/pkg/errors" - "golang.org/x/crypto/ssh" -) - -func (c HTTPClient) AuthInit(organizationName string) error { - // by default, we store the key in ~/.replicated/enterprise - _, err := os.Stat(filepath.Join(homeDir(), ".replicated", "enterprise")) - if err != nil && !os.IsNotExist(err) { - return errors.Wrap(err, "failed to check for directory") - } - if os.IsNotExist(err) { - if err := os.MkdirAll(filepath.Join(homeDir(), ".replicated", "enterprise"), 0755); err != nil { - return errors.Wrap(err, "failed to mkdir") - } - } - pubKeyPath := filepath.Join(homeDir(), ".replicated", "enterprise", "ecdsa.pub") - privKeyPath := filepath.Join(homeDir(), ".replicated", "enterprise", "ecdsa") - - _, pubKeyErr := os.Stat(pubKeyPath) - _, privKeyErr := os.Stat(privKeyPath) - - if pubKeyErr != nil && !os.IsNotExist(pubKeyErr) { - return errors.Wrap(pubKeyErr, "failed to read public key") - } - if privKeyErr != nil && !os.IsNotExist(privKeyErr) { - return errors.Wrap(privKeyErr, "failed to read private key") - } - - missingPublicKey := os.IsNotExist(pubKeyErr) - missingPrivateKey := os.IsNotExist(privKeyErr) - - if !missingPrivateKey && !missingPublicKey { - return errors.New("already authenticated") - } - - privateKey, err := generatePrivateKey() - if err != nil { - return errors.Wrap(err, "failed to generate private key") - } - if err := ioutil.WriteFile(privKeyPath, encodePrivateKeyToPEM(privateKey), 0600); err != nil { - return errors.Wrap(err, "failed to write private key to file") - } - - if err := ioutil.WriteFile(pubKeyPath, encodePublicKey(&privateKey.PublicKey), 0600); err != nil { - return errors.Wrap(err, "failed to write public key to file") - } - - if organizationName != "" { - // --create-org flag is provided, create the organization - // send the PUBLIC key and the organization name to the replicated server and return the organization id - type CreateOrgRequest struct { - PublicKeyBytes []byte `json:"publicKey"` - OrganizationName string `json:"organizationName"` - } - createOrgRequest := CreateOrgRequest{ - PublicKeyBytes: encodePublicKey(&privateKey.PublicKey), - OrganizationName: organizationName, - } - - type CreateOrgResponse struct { - OrganizationID string `json:"organizationId"` - } - createOrgResponse := CreateOrgResponse{} - - err = c.doJSON("POST", "/v1/organization", 201, createOrgRequest, &createOrgResponse) - if err != nil { - return errors.Wrap(err, "failed to create organization") - } - - fmt.Printf("\nOrganization has been created successfully with the following ID: %s\n\n", createOrgResponse.OrganizationID) - } else { - // --create-org flag is NOT provided, begin authentication process - // send the PUBLIC key to the replicated server and return the key id - type AuthRequest struct { - PublicKeyBytes []byte `json:"publicKey"` - } - authRequest := AuthRequest{ - PublicKeyBytes: encodePublicKey(&privateKey.PublicKey), - } - - type AuthInitResponse struct { - Code string `json:"code"` - } - authInitResponse := AuthInitResponse{} - - err = c.doJSON("POST", "/v1/auth", 201, authRequest, &authInitResponse) - if err != nil { - return errors.Wrap(err, "failed to init auth with server") - } - - fmt.Printf("\nYour authentication request has been submitted. Please contact your organization or Replicated at support@replicated.com to complete this request with the following code: %s\n\n", authInitResponse.Code) - } - - return nil -} - -func (c HTTPClient) AuthApprove(fingerprint string) error { - type AuthApproveRequest struct { - Fingerprint string `json:"fingerprint"` - } - authApproveRequest := AuthApproveRequest{ - Fingerprint: fingerprint, - } - - err := c.doJSON("PUT", "/v1/auth/approve", 204, authApproveRequest, nil) - if err != nil { - return errors.Wrap(err, "failed to approve auth request") - } - - fmt.Print("\nAuthentication request approved successfully\n\n") - return nil -} - -func generatePrivateKey() (*ecdsa.PrivateKey, error) { - privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) - if err != nil { - return nil, errors.Wrap(err, "failed to generate key") - } - - return privateKey, nil -} - -func encodePrivateKeyToPEM(privateKey *ecdsa.PrivateKey) []byte { - privDER, err := x509.MarshalECPrivateKey(privateKey) - if err != nil { - panic(err) // this should never happen - if it does, that means things are rather broken - } - - privBlock := pem.Block{ - Type: "EC PRIVATE KEY", - Headers: nil, - Bytes: privDER, - } - - privatePEM := pem.EncodeToMemory(&privBlock) - - return privatePEM -} - -func decodePrivateKeyPEM(privateBytes []byte) (*ecdsa.PrivateKey, error) { - privBlock, _ := pem.Decode(privateBytes) - - if privBlock.Type != "EC PRIVATE KEY" { - return nil, fmt.Errorf("private key type is %s, not 'EC PRIVATE KEY'", privBlock.Type) - } - - key, err := x509.ParseECPrivateKey(privBlock.Bytes) - if err != nil { - return nil, errors.Wrap(err, "decode ec private key") - } - return key, nil -} - -func encodePublicKey(publicKey *ecdsa.PublicKey) []byte { - pubKey, err := ssh.NewPublicKey(publicKey) - if err != nil { - panic(errors.Wrap(err, "create ssh pubkey")) // this should never happen - if it does, that means things are rather broken - } - - return pubKey.Marshal() -} - -func getFingerprint(publicKey *ecdsa.PublicKey) (string, error) { - pubKey, err := ssh.NewPublicKey(publicKey) - if err != nil { - return "", errors.Wrap(err, "create ssh pubkey") - } - return ssh.FingerprintSHA256(pubKey), nil -} - -func homeDir() string { - if h := os.Getenv("HOME"); h != "" { - return h - } - return os.Getenv("USERPROFILE") -} - -type SigBlock struct { - Nonce []byte - Timestamp []byte - Signature []byte -} - -// gets the (base64 encoded) signature and fingerprint for a given key and data -// returns the signature with a nonce and timestamp, the signature of the data alone, the fingerprint, and error -func sigAndFingerprint(privateKey *ecdsa.PrivateKey, data []byte) (string, string, string, error) { - // generate a timestamp and nonce - nonce := make([]byte, 512/8) // 512 bits - _, _ = rand.Read(nonce) // returns len, nil - neither of which we need - ts, err := time.Now().MarshalText() // marshals to RFC3339Nano - if err != nil { - return "", "", "", errors.Wrap(err, "failed to get timestamp") - } - - // hash the body and sign the hash - // store the signature in an ecSig struct and marshal it with the ssh wire format - contentSha := sha512.Sum512(data) - var ecSig struct { - R *big.Int - S *big.Int - } - ecSig.R, ecSig.S, err = ecdsa.Sign(rand.Reader, privateKey, contentSha[:]) - if err != nil { - return "", "", "", errors.Wrap(err, "failed to sign content sha") - } - signatureString := base64.StdEncoding.EncodeToString(ssh.Marshal(ecSig)) - - // do the same for the data combined with the timestamp and nonce - contentSha = sha512.Sum512(combineTsNonceData(ts, nonce, data)) - ecSig.R, ecSig.S, err = ecdsa.Sign(rand.Reader, privateKey, contentSha[:]) - if err != nil { - return "", "", "", errors.Wrap(err, "failed to sign content sha") - } - tsSig := ssh.Marshal(ecSig) - - // include the public key fingerprint as a hint to the server - fingerprint, err := getFingerprint(&privateKey.PublicKey) - if err != nil { - return "", "", "", errors.Wrap(err, "failed to get public key fingerprint") - } - - sigBlock := SigBlock{ - Timestamp: ts, - Nonce: nonce, - Signature: tsSig, - } - sigBlockBytes, err := json.Marshal(sigBlock) - if err != nil { - return "", "", "", errors.Wrap(err, "failed to marshal signature block") - } - sigBlockString := base64.StdEncoding.EncodeToString(sigBlockBytes) - - return sigBlockString, signatureString, fingerprint, nil -} - -func combineTsNonceData(ts, nonce, data []byte) []byte { - tsBytes := []byte{} - tsBytes = append(tsBytes, nonce...) - tsBytes = append(tsBytes, ts...) - tsBytes = append(tsBytes, data...) - return tsBytes -} - -// ValidatePayload checks that the payload was signed by the private key associated with the provided public key -// if fingerprintSigString is not empty, sigString is ignored and it is used instead, and the nonce will be returned if the signature was valid -func ValidatePayload(pubkey ssh.PublicKey, sigString, fingerprintSigString string, data []byte) (bool, []byte, error) { - if !strings.HasPrefix(pubkey.Type(), "ecdsa-sha2-") { - return false, nil, fmt.Errorf("%q is not an accepted public key type", pubkey.Type()) - } - - if fingerprintSigString != "" { - sigBlockBytes, err := base64.StdEncoding.DecodeString(fingerprintSigString) - if err != nil { - return false, nil, errors.Wrap(err, "invalid signature string") - } - - decodedSig := SigBlock{} - err = json.Unmarshal(sigBlockBytes, &decodedSig) - if err != nil { - return false, nil, errors.Wrap(err, "invalid signature object") - } - - err = pubkey.Verify(combineTsNonceData(decodedSig.Timestamp, decodedSig.Nonce, data), &ssh.Signature{ - Format: pubkey.Type(), - Blob: decodedSig.Signature, - }) - if err != nil { - return false, nil, errors.Wrap(err, "invalid signature") - } - - sentTime, err := time.Parse(time.RFC3339Nano, string(decodedSig.Timestamp)) - if err != nil { - return false, nil, errors.Wrap(err, "invalid timestamp") - } - if !sentTime.Before(time.Now().Add(time.Hour)) { - return false, nil, fmt.Errorf("date %s is more than an hour after the current time %s", string(decodedSig.Timestamp), time.Now().Format(time.RFC3339Nano)) - } - if !sentTime.After(time.Now().Add(-time.Hour)) { - return false, nil, fmt.Errorf("date %s is more than an hour before the current time %s", string(decodedSig.Timestamp), time.Now().Format(time.RFC3339Nano)) - } - return true, decodedSig.Nonce, nil - } - - sigBytes, err := base64.StdEncoding.DecodeString(sigString) - if err != nil { - return false, nil, errors.Wrap(err, "invalid signature string") - } - - err = pubkey.Verify(data, &ssh.Signature{ - Format: pubkey.Type(), - Blob: sigBytes, - }) - if err != nil { - return false, nil, errors.Wrap(err, "invalid signature") - } - - return true, nil, nil -} diff --git a/pkg/enterpriseclient/auth_test.go b/pkg/enterpriseclient/auth_test.go deleted file mode 100644 index 0e91cd883..000000000 --- a/pkg/enterpriseclient/auth_test.go +++ /dev/null @@ -1,114 +0,0 @@ -package enterpriseclient - -import ( - "encoding/base64" - "encoding/json" - "testing" - "time" - - "github.com/stretchr/testify/require" - "golang.org/x/crypto/ssh" -) - -func Test_sigAndFingerprint(t *testing.T) { - req := require.New(t) - - var testData string // just needs to be of sufficient length - for i := 0; i < 100; i++ { - testData = testData + "abcdefghijklmnopqurstuvwxyz123456789" - } - - // make a new private key - privateKey, err := generatePrivateKey() - req.NoError(err) - - // encode that private key to bytes - privateKeyBytes := encodePrivateKeyToPEM(privateKey) - // decode private key bytes - privateKey, err = decodePrivateKeyPEM(privateKeyBytes) - req.NoError(err) - - _, sig, fingerprint, err := sigAndFingerprint(privateKey, []byte(testData)) - req.NoError(err) - - pubKey := encodePublicKey(&privateKey.PublicKey) - - // everything past this depends only on testData, sig, fingerprint, pubKey and req - // NOT privateKey - - parsedPubKey, err := ssh.ParsePublicKey(pubKey) - req.NoError(err) - - validated, _, err := ValidatePayload(parsedPubKey, sig, "", []byte(testData)) - req.NoError(err) - req.True(validated) - - req.Equal(fingerprint, ssh.FingerprintSHA256(parsedPubKey)) - - // test bad signatures/data - - fakeSig, _, err := ValidatePayload(parsedPubKey, base64.StdEncoding.EncodeToString([]byte("fakesig")), "", []byte(testData)) - req.Error(err) - req.False(fakeSig) - - editData, _, err := ValidatePayload(parsedPubKey, sig, "", append([]byte(testData), []byte("malicious")...)) - req.Error(err) - req.False(editData) -} - -func Test_sigblockAndFingerprint(t *testing.T) { - req := require.New(t) - - var testData string // just needs to be of sufficient length - for i := 0; i < 100; i++ { - testData = testData + "abcdefghijklmnopqurstuvwxyz123456789" - } - - // make a new private key - privateKey, err := generatePrivateKey() - req.NoError(err) - - // encode that private key to bytes - privateKeyBytes := encodePrivateKeyToPEM(privateKey) - // decode private key bytes - privateKey, err = decodePrivateKeyPEM(privateKeyBytes) - req.NoError(err) - - sigBlock, _, fingerprint, err := sigAndFingerprint(privateKey, []byte(testData)) - req.NoError(err) - - pubKey := encodePublicKey(&privateKey.PublicKey) - - // everything past this depends only on testData, sig, fingerprint, pubKey and req - // NOT privateKey - - parsedPubKey, err := ssh.ParsePublicKey(pubKey) - req.NoError(err) - - validated, nonce, err := ValidatePayload(parsedPubKey, "", sigBlock, []byte(testData)) - req.NoError(err) - req.True(validated) - req.NotNil(nonce) - - req.Equal(fingerprint, ssh.FingerprintSHA256(parsedPubKey)) - - // test bad signatures/data - - badSig := SigBlock{ - Timestamp: []byte(time.Now().Format(time.RFC3339Nano)), - Nonce: nonce, - Signature: []byte("abcdefg"), - } - badSigBytes, err := json.Marshal(badSig) - req.NoError(err) - - fakeSig, nonce, err := ValidatePayload(parsedPubKey, "", base64.StdEncoding.EncodeToString(badSigBytes), []byte(testData)) - req.Error(err) - req.False(fakeSig) - req.Nil(nonce) - - editData, nonce, err := ValidatePayload(parsedPubKey, "", sigBlock, append([]byte(testData), []byte("malicious")...)) - req.Error(err) - req.False(editData) - req.Nil(nonce) -} diff --git a/pkg/enterpriseclient/channel.go b/pkg/enterpriseclient/channel.go deleted file mode 100644 index a88fa690c..000000000 --- a/pkg/enterpriseclient/channel.go +++ /dev/null @@ -1,75 +0,0 @@ -package enterpriseclient - -import ( - "fmt" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -func (c HTTPClient) ListChannels() ([]*enterprisetypes.Channel, error) { - enterpriseChannels := []*enterprisetypes.Channel{} - err := c.doJSON("GET", "/v1/channels", 200, nil, &enterpriseChannels) - if err != nil { - return nil, errors.Wrap(err, "failed to get channels") - } - - return enterpriseChannels, nil -} - -func (c HTTPClient) CreateChannel(name string, description string) (*enterprisetypes.Channel, error) { - type CreateChannelRequest struct { - Name string `json:"name"` - Description string `json:"description"` - } - createChannelRequest := CreateChannelRequest{ - Name: name, - Description: description, - } - - enterpriseChannel := enterprisetypes.Channel{} - err := c.doJSON("POST", "/v1/channel", 201, createChannelRequest, &enterpriseChannel) - if err != nil { - return nil, errors.Wrap(err, "failed to create channel") - } - - return &enterpriseChannel, nil -} - -func (c HTTPClient) UpdateChannel(id string, name string, description string) (*enterprisetypes.Channel, error) { - type UpdateChannelRequest struct { - Name string `json:"name"` - Description string `json:"description"` - } - updateChannelRequest := UpdateChannelRequest{ - Name: name, - Description: description, - } - - enterpriseChannel := enterprisetypes.Channel{} - - err := c.doJSON("PUT", fmt.Sprintf("/v1/channel/%s", id), 200, updateChannelRequest, &enterpriseChannel) - if err != nil { - return nil, errors.Wrap(err, "failed to update channel") - } - - return &enterpriseChannel, nil -} - -func (c HTTPClient) RemoveChannel(id string) error { - err := c.doJSON("DELETE", fmt.Sprintf("/v1/channel/%s", id), 204, nil, nil) - if err != nil { - return errors.Wrap(err, "failed to delete channel") - } - - return nil -} - -func (c HTTPClient) AssignChannel(channelID string, teamID string) error { - err := c.doJSON("POST", fmt.Sprintf("/v1/teamchannel/%s/%s", channelID, teamID), 204, nil, nil) - if err != nil { - return errors.Wrap(err, "failed to assign channel") - } - - return nil -} diff --git a/pkg/enterpriseclient/client.go b/pkg/enterpriseclient/client.go deleted file mode 100644 index ca1762653..000000000 --- a/pkg/enterpriseclient/client.go +++ /dev/null @@ -1,89 +0,0 @@ -package enterpriseclient - -import ( - "bytes" - "crypto/ecdsa" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - - "github.com/pkg/errors" -) - -const apiOrigin = "https://api.replicated.com/enterprise" - -// An HTTPClient communicates with the Replicated Enterprise HTTP API. -type HTTPClient struct { - privateKey *ecdsa.PrivateKey - apiOrigin string -} - -// New returns a new HTTP client. -func New(privateKeyContents []byte) *HTTPClient { - return NewHTTPClient(apiOrigin, privateKeyContents) -} - -func NewHTTPClient(origin string, privateKeyContents []byte) *HTTPClient { - c := &HTTPClient{ - apiOrigin: origin, - } - if privateKeyContents != nil { - privateKey, err := decodePrivateKeyPEM(privateKeyContents) - if err != nil { - privateKey = nil - } - c.privateKey = privateKey - } - - return c -} - -func (c *HTTPClient) doJSON(method, path string, successStatus int, reqBody interface{}, respBody interface{}) error { - endpoint := fmt.Sprintf("%s%s", c.apiOrigin, path) - var bodyBytes []byte - if reqBody != nil { - var err error - bodyBytes, err = json.Marshal(reqBody) - if err != nil { - return err - } - } - - req, err := http.NewRequest(method, endpoint, bytes.NewBuffer(bodyBytes)) - if err != nil { - return err - } - - if c.privateKey != nil { - sigWithNonce, sig, fingerprint, err := sigAndFingerprint(c.privateKey, bodyBytes) - if err != nil { - return err - } - req.Header.Set("Signature", sig) - req.Header.Set("Authorization", fingerprint) - req.Header.Set("SignatureNonce", sigWithNonce) - } - - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Accept", "application/json") - resp, err := http.DefaultClient.Do(req) - if err != nil { - return errors.Wrap(err, "failed to do request") - } - defer resp.Body.Close() - if resp.StatusCode == http.StatusNotFound { - return errors.New("not found") - } - if resp.StatusCode != successStatus { - body, _ := ioutil.ReadAll(resp.Body) - return fmt.Errorf("%s %s %d: %s", method, endpoint, resp.StatusCode, body) - } - if respBody != nil { - if err := json.NewDecoder(resp.Body).Decode(respBody); err != nil { - return fmt.Errorf("%s %s response decoding: %w", method, endpoint, err) - } - } - - return nil -} diff --git a/pkg/enterpriseclient/client_test.go b/pkg/enterpriseclient/client_test.go deleted file mode 100644 index 70e1a20b2..000000000 --- a/pkg/enterpriseclient/client_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package enterpriseclient - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewNilHTTPClient(t *testing.T) { - req := require.New(t) - client := NewHTTPClient("origin", nil) - req.Equal(&HTTPClient{ - privateKey: nil, - apiOrigin: "origin", - }, client) -} diff --git a/pkg/enterpriseclient/installer.go b/pkg/enterpriseclient/installer.go deleted file mode 100644 index 1f1c101b6..000000000 --- a/pkg/enterpriseclient/installer.go +++ /dev/null @@ -1,73 +0,0 @@ -package enterpriseclient - -import ( - "fmt" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -func (c HTTPClient) ListInstallers() ([]*enterprisetypes.Installer, error) { - enterpriseInstallers := []*enterprisetypes.Installer{} - err := c.doJSON("GET", "/v1/installers", 200, nil, &enterpriseInstallers) - if err != nil { - return nil, errors.Wrap(err, "failed to get installers") - } - - return enterpriseInstallers, nil -} - -func (c HTTPClient) CreateInstaller(yaml string) (*enterprisetypes.Installer, error) { - type CreateInstallerRequest struct { - Yaml string `json:"yaml"` - } - createInstallerRequest := CreateInstallerRequest{ - Yaml: yaml, - } - - enterpriseInstaller := enterprisetypes.Installer{} - err := c.doJSON("POST", "/v1/installer", 201, createInstallerRequest, &enterpriseInstaller) - if err != nil { - return nil, errors.Wrap(err, "failed to create installer") - } - - return &enterpriseInstaller, nil -} - -func (c HTTPClient) UpdateInstaller(id string, yaml string) (*enterprisetypes.Installer, error) { - type UpdateInstallerRequest struct { - ID string `json:"id"` - Yaml string `json:"yaml"` - } - updateInstallerRequest := UpdateInstallerRequest{ - ID: id, - Yaml: yaml, - } - - enterpriseInstaller := enterprisetypes.Installer{} - - err := c.doJSON("PUT", fmt.Sprintf("/v1/installer/%s", id), 200, updateInstallerRequest, &enterpriseInstaller) - if err != nil { - return nil, errors.Wrap(err, "failed to update installer") - } - - return &enterpriseInstaller, nil -} - -func (c HTTPClient) RemoveInstaller(id string) error { - err := c.doJSON("DELETE", fmt.Sprintf("/v1/installer/%s", id), 204, nil, nil) - if err != nil { - return errors.Wrap(err, "failed to delete installer") - } - - return nil -} - -func (c HTTPClient) AssignInstaller(installerID string, channelID string) error { - err := c.doJSON("POST", fmt.Sprintf("/v1/channelinstaller/%s/%s", installerID, channelID), 204, nil, nil) - if err != nil { - return errors.Wrap(err, "failed to assign installer") - } - - return nil -} diff --git a/pkg/enterpriseclient/policy.go b/pkg/enterpriseclient/policy.go deleted file mode 100644 index a29c26634..000000000 --- a/pkg/enterpriseclient/policy.go +++ /dev/null @@ -1,88 +0,0 @@ -package enterpriseclient - -import ( - "fmt" - - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/pkg/enterprisetypes" -) - -func (c HTTPClient) ListPolicies() ([]*enterprisetypes.Policy, error) { - enterprisePolicies := []*enterprisetypes.Policy{} - err := c.doJSON("GET", "/v1/policies", 200, nil, &enterprisePolicies) - if err != nil { - return nil, errors.Wrap(err, "failed to get policies") - } - - return enterprisePolicies, nil -} - -func (c HTTPClient) CreatePolicy(name string, description string, policy string) (*enterprisetypes.Policy, error) { - type CreatePolicyRequest struct { - Name string `json:"name"` - Description string `json:"description"` - Policy string `json:"policy"` - } - createPolicyRequest := CreatePolicyRequest{ - Name: name, - Description: description, - Policy: policy, - } - - enterprisePolicy := enterprisetypes.Policy{} - err := c.doJSON("POST", "/v1/policy", 201, createPolicyRequest, &enterprisePolicy) - if err != nil { - return nil, errors.Wrap(err, "failed to create policy") - } - - return &enterprisePolicy, nil -} - -func (c HTTPClient) UpdatePolicy(id string, name string, description string, policy string) (*enterprisetypes.Policy, error) { - type UpdatePolicyRequest struct { - Name string `json:"name"` - Description string `json:"description"` - Policy string `json:"policy"` - } - updatePolicyRequest := UpdatePolicyRequest{ - Name: name, - Description: description, - Policy: policy, - } - - enterprisePolicy := enterprisetypes.Policy{} - - err := c.doJSON("PUT", fmt.Sprintf("/v1/policy/%s", id), 200, updatePolicyRequest, &enterprisePolicy) - if err != nil { - return nil, errors.Wrap(err, "failed to update policy") - } - - return &enterprisePolicy, nil -} - -func (c HTTPClient) RemovePolicy(id string) error { - err := c.doJSON("DELETE", fmt.Sprintf("/v1/policy/%s", id), 204, nil, nil) - if err != nil { - return errors.Wrap(err, "failed to delete policy") - } - - return nil -} - -func (c HTTPClient) AssignPolicy(policyID string, channelID string) error { - err := c.doJSON("POST", fmt.Sprintf("/v1/channelpolicy/%s/%s", policyID, channelID), 204, nil, nil) - if err != nil { - return errors.Wrap(err, "failed to assign policy") - } - - return nil -} - -func (c HTTPClient) UnassignPolicy(policyID string, channelID string) error { - err := c.doJSON("DELETE", fmt.Sprintf("/v1/channelpolicy/%s/%s", policyID, channelID), 204, nil, nil) - if err != nil { - return errors.Wrap(err, "failed to unassign policy") - } - - return nil -} diff --git a/pkg/enterprisetypes/channel.go b/pkg/enterprisetypes/channel.go deleted file mode 100644 index cc37bf895..000000000 --- a/pkg/enterprisetypes/channel.go +++ /dev/null @@ -1,7 +0,0 @@ -package enterprisetypes - -type Channel struct { - ID string - Name string - Description string -} diff --git a/pkg/enterprisetypes/installer.go b/pkg/enterprisetypes/installer.go deleted file mode 100644 index 6e417176f..000000000 --- a/pkg/enterprisetypes/installer.go +++ /dev/null @@ -1,6 +0,0 @@ -package enterprisetypes - -type Installer struct { - ID string - Yaml string -} diff --git a/pkg/enterprisetypes/policy.go b/pkg/enterprisetypes/policy.go deleted file mode 100644 index cf234ecf6..000000000 --- a/pkg/enterprisetypes/policy.go +++ /dev/null @@ -1,8 +0,0 @@ -package enterprisetypes - -type Policy struct { - ID string - Name string - Description string - Policy string -} diff --git a/pkg/types/channel.go b/pkg/types/channel.go index aaa6ff717..6a255c15a 100644 --- a/pkg/types/channel.go +++ b/pkg/types/channel.go @@ -5,24 +5,23 @@ import ( ) type KotsChannel struct { - AdoptionRate []CustomerAdoption `json:"adoptionRate,omitempty"` - AppId string `json:"appId,omitempty"` - BuildAirgapAutomatically bool `json:"buildAirgapAutomatically,omitempty"` - ChannelIcon string `json:"channelIcon,omitempty"` - ChannelSequence int32 `json:"channelSequence,omitempty"` - ChannelSlug string `json:"channelSlug,omitempty"` - Created time.Time `json:"created,omitempty"` - CurrentVersion string `json:"currentVersion,omitempty"` - Customers *TotalActiveInactiveCustomers `json:"customers,omitempty"` - Description string `json:"description,omitempty"` - EnterprisePartnerChannelID string `json:"enterprisePartnerChannelID,omitempty"` - Id string `json:"id,omitempty"` - IsArchived bool `json:"isArchived,omitempty"` - IsDefault bool `json:"isDefault,omitempty"` - Name string `json:"name,omitempty"` - NumReleases int32 `json:"numReleases,omitempty"` - IsHelmOnly bool `json:"isHelmOnly,omitempty"` - ReleaseNotes string `json:"releaseNotes,omitempty"` + AdoptionRate []CustomerAdoption `json:"adoptionRate,omitempty"` + AppId string `json:"appId,omitempty"` + BuildAirgapAutomatically bool `json:"buildAirgapAutomatically,omitempty"` + ChannelIcon string `json:"channelIcon,omitempty"` + ChannelSequence int32 `json:"channelSequence,omitempty"` + ChannelSlug string `json:"channelSlug,omitempty"` + Created time.Time `json:"created,omitempty"` + CurrentVersion string `json:"currentVersion,omitempty"` + Customers *TotalActiveInactiveCustomers `json:"customers,omitempty"` + Description string `json:"description,omitempty"` + Id string `json:"id,omitempty"` + IsArchived bool `json:"isArchived,omitempty"` + IsDefault bool `json:"isDefault,omitempty"` + Name string `json:"name,omitempty"` + NumReleases int32 `json:"numReleases,omitempty"` + IsHelmOnly bool `json:"isHelmOnly,omitempty"` + ReleaseNotes string `json:"releaseNotes,omitempty"` // TODO: set these (see kotsChannelToSchema function) ReleaseSequence int32 `json:"releaseSequence,omitempty"` Releases []ChannelRelease `json:"releases,omitempty"` @@ -81,9 +80,7 @@ type ChannelRelease struct { type CreateChannelRequest struct { // Description of the channel that is to be created. Description string `json:"description,omitempty"` - // Enterprise Partner Channel Id to be added to channel. - EnterprisePartnerChannelID string `json:"enterprisePartnerChannelID,omitempty"` - Name string `json:"name"` + Name string `json:"name"` } type PatchChannelRequest struct {