Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 84 additions & 39 deletions cmd/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/outscale/octl/pkg/builder"
"github.com/outscale/octl/pkg/config"
"github.com/outscale/octl/pkg/debug"
"github.com/outscale/octl/pkg/flags"
"github.com/outscale/octl/pkg/messages"
"github.com/outscale/octl/pkg/preferences"
"github.com/outscale/octl/pkg/runner"
Expand All @@ -25,14 +26,15 @@ import (

// oksCmd represents the kubecommand
var oksCmd = &cobra.Command{
GroupID: "services",
Use: "kube",
Short: "OUTSCALE Kubernetes as a Service (OKS) management",
Aliases: []string{"oks"},
GroupID: "services",
Use: "kube",
Short: "OUTSCALE Kubernetes as a Service (OKS) management",
Aliases: []string{"oks"},
PersistentPreRunE: flagNamesToID,
}

var projectUseCmd = &cobra.Command{
Use: "use [project_id_or_name]",
Use: "use [id_or_name]",
Short: "Set a default project for cluster commands, reset it without args",
Run: useProject,
Args: cobra.MaximumNArgs(1),
Expand All @@ -49,14 +51,20 @@ func init() {

// Add --project flag to kube cluster commands
clusterCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "cluster" })
clusterCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "project name")
clusterCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project")
_ = flags.MarkAsNoForward(clusterCmd.PersistentFlags(), "project")
clusterCmd.PersistentPreRunE = clusterArgToID
clusterCreateCmd, _ := lo.Find(clusterCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "create" })
_ = flags.SetDefault(clusterCreateCmd.Flags(), "project", preferences.Preferences.Kube.DefaultProject)

// Remap <cluster ls --project name> to <project clusters name>
projectCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "project" })
projectCmd.PersistentPreRunE = projectArgToID
projectClustersCmd, _ := lo.Find(projectCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "clusters" })
clusterListCmd, _ := lo.Find(clusterCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "list" })
runClusterListCmd := clusterListCmd.Run
clusterListCmd.Run = func(cmd *cobra.Command, args []string) {
// remap flag to arg
project, _ := cmd.Flags().GetString("project")
if project != "" {
cmd.Flag("project").Changed = false
Expand All @@ -66,69 +74,103 @@ func init() {
}
}

// Project use
// cluster/project use
projectCmd.AddCommand(projectUseCmd)

// Add --project flag to kube api cluster commands
apiCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "api" })
lo.ForEach(apiCmd.Commands(), func(c *cobra.Command, _ int) {
if strings.HasSuffix(c.Name(), "Cluster") || c.Name() == "GetKubeconfig" {
c.Flags().String("project", preferences.Preferences.Kube.DefaultProject, "project name")
}
})
}

func kube(cmd *cobra.Command, args []string) {
debug.Println(cmd.Name() + " called")
p := loadProfile(cmd)
cl, err := oks.NewClient(p, sdkOptions(cmd)...)
if err == nil {
args = argNameToID(cmd, args, cl)
flagNameToID(cmd, cl)
err = runner.Run[*oks.Client, *oks.ErrorResponse](cmd, args, cl, config.For("kube"))
}
if err != nil {
messages.ExitErr(err)
}
}

func argNameToID(cmd *cobra.Command, args []string, cl *oks.Client) []string {
func clusterArgToID(cmd *cobra.Command, args []string) error {
debug.Println("clusterArgToID")
p := loadProfile(cmd)
cl, err := oks.NewClient(p, sdkOptions(cmd)...)
if err != nil {
return err
}

if len(args) == 0 {
debug.Println("no arg to replace")
return args
return nil
}
if _, err := uuid.Parse(args[0]); err == nil {
debug.Println("arg is an uuid")
return args
return nil
}
var err error
switch cmd.Name() {
case "GetProject", "DeleteProject", "GetProjectNets", "GetProjectQuotas", "GetProjectPublicIps", "GetProjectSnapshots":
args[0], err = projectNameToID(cmd.Context(), args[0], cl)
case "GetCluster", "UpdateCluster", "DeleteCluster", "GetKubeconfig":
project, _ := cmd.Flags().GetString("project")
args[0], err = clusterNameToID(cmd.Context(), args[0], project, cl)
project, _ := cmd.Flags().GetString("project")
args[0], err = clusterNameToID(cmd.Context(), args[0], project, cl)
return err
}

func projectArgToID(cmd *cobra.Command, args []string) error {
// project use should store the name, not the ID
if cmd.Name() == "use" {
return nil
}
debug.Println("projectArgToID")
p := loadProfile(cmd)
cl, err := oks.NewClient(p, sdkOptions(cmd)...)
if err != nil {
messages.ExitErr(err)
return err
}

if len(args) == 0 {
debug.Println("no arg to replace")
return nil
}
if _, err := uuid.Parse(args[0]); err == nil {
debug.Println("arg is an uuid")
return nil
}
return args
args[0], err = projectNameToID(cmd.Context(), args[0], cl)
return err
}

func flagNameToID(cmd *cobra.Command, cl *oks.Client) {
f := cmd.Flags().Lookup("ProjectId")
if f == nil {
debug.Println("no flag to replace")
return
func flagNamesToID(cmd *cobra.Command, args []string) error {
debug.Println("flagNamesToID")
p := loadProfile(cmd)
cl, err := oks.NewClient(p, sdkOptions(cmd)...)
if err != nil {
return err
}

pf := cmd.Flags().Lookup("project")
if pf == nil {
debug.Println("no project flag to replace")
return nil
}
id, err := projectNameToID(cmd.Context(), f.Value.String(), cl)
pid, err := projectNameToID(cmd.Context(), pf.Value.String(), cl)
if err != nil {
messages.ExitErr(err)
return err
}
_ = pf.Value.Set(pid)

cf := cmd.Flags().Lookup("cluster")
if cf == nil {
debug.Println("no cluster flag to replace")
return nil
}
_ = f.Value.Set(id)
cid, err := clusterNameToID(cmd.Context(), cf.Value.String(), pid, cl)
if err != nil {
return err
}
_ = cf.Value.Set(cid)
return nil
}

func projectNameToID(ctx context.Context, name string, cl *oks.Client) (string, error) {
if name == "" {
return "", nil
}
pjs, err := cl.ListProjects(ctx, &oks.ListProjectsParams{Name: &name})
if err != nil {
return "", err
Expand All @@ -137,12 +179,15 @@ func projectNameToID(ctx context.Context, name string, cl *oks.Client) (string,
case 0:
return "", fmt.Errorf("project %q not found", name)
default:
debug.Println("replacing", name, "by", pjs.Projects[0].Id)
messages.Info("Resolving project name %q as ID %q", name, pjs.Projects[0].Id)
return pjs.Projects[0].Id, nil
}
}

func clusterNameToID(ctx context.Context, name, project string, cl *oks.Client) (string, error) {
if name == "" {
return "", nil
}
var (
cs *oks.ClusterResponseList
err error
Expand Down Expand Up @@ -170,7 +215,7 @@ func clusterNameToID(ctx context.Context, name, project string, cl *oks.Client)
case 0:
return "", fmt.Errorf("cluster %q not found", name)
case 1:
debug.Println("replacing", name, "by", clusters[0].Id)
messages.Info("Resolving cluster name %q as ID %q", name, clusters[0].Id)
return clusters[0].Id, nil
default:
return "", fmt.Errorf("multiple clusters found with the name %q", name)
Expand Down
3 changes: 1 addition & 2 deletions cmd/kube_kubeapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ func kubeapi(provider string) func(cmd *cobra.Command, args []string) {
messages.ExitErr(err)
}
cluster, _ := cmd.Flags().GetString("cluster")
project, _ := cmd.Flags().GetString("project")
kubeconfig, err := getKubeconfig(cmd.Context(), cluster, project, cl)
kubeconfig, err := getKubeconfig(cmd.Context(), cluster, cl)
if err != nil {
messages.ExitErr(err)
}
Expand Down
17 changes: 7 additions & 10 deletions cmd/kube_kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/outscale/octl/pkg/debug"
"github.com/outscale/octl/pkg/flags"
"github.com/outscale/octl/pkg/messages"
"github.com/outscale/octl/pkg/preferences"
"github.com/outscale/osc-sdk-go/v3/pkg/oks"
Expand All @@ -34,8 +35,7 @@ func kubectl(cmd *cobra.Command, args []string) {
messages.ExitErr(err)
}
cluster, _ := cmd.Flags().GetString("cluster")
project, _ := cmd.Flags().GetString("project")
kubeconfig, err := getKubeconfig(cmd.Context(), cluster, project, cl)
kubeconfig, err := getKubeconfig(cmd.Context(), cluster, cl)
if err != nil {
messages.ExitErr(err)
}
Expand All @@ -52,19 +52,15 @@ func kubectl(cmd *cobra.Command, args []string) {
}
}

func getKubeconfig(ctx context.Context, cluster, project string, cl *oks.Client) (string, error) {
id, err := clusterNameToID(ctx, cluster, project, cl)
if err != nil {
return "", err
}
filename, err := kubeconfigPath(id)
func getKubeconfig(ctx context.Context, cluster string, cl *oks.Client) (string, error) {
filename, err := kubeconfigPath(cluster)
if err != nil {
return "", err
}
debug.Println("kubeconfig path", filename)
if _, err := os.Stat(filename); errors.Is(err, fs.ErrNotExist) {
debug.Println("no kubeconfig; refreshing")
err = refreshKubeconfig(ctx, id, filename, cl)
err = refreshKubeconfig(ctx, cluster, filename, cl)
if err != nil {
return "", err
}
Expand All @@ -86,7 +82,7 @@ func getKubeconfig(ctx context.Context, cluster, project string, cl *oks.Client)
}
if err == nil && time.Since(decoded.NotAfter) > 0 {
debug.Println("expired kubeconfig certificate; refreshing")
err = refreshKubeconfig(ctx, id, filename, cl)
err = refreshKubeconfig(ctx, cluster, filename, cl)
}
if err != nil {
return "", err
Expand Down Expand Up @@ -125,4 +121,5 @@ func init() {
kubectlCmd.Flags().String("cluster", "", "Name or ID of cluster")
_ = kubectlCmd.MarkFlagRequired("cluster")
kubectlCmd.Flags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project")
_ = flags.MarkAsNoForward(kubectlCmd.Flags(), "project")
}
18 changes: 12 additions & 6 deletions cmd/kube_nodepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

oksv1beta2 "github.com/outscale/goutils/oks/clientset/typed/oks.dev/v1beta2"
"github.com/outscale/octl/pkg/builder"
"github.com/outscale/octl/pkg/flags"
"github.com/outscale/octl/pkg/preferences"
"github.com/samber/lo"
"github.com/spf13/cobra"
Expand All @@ -26,11 +27,16 @@ func init() {
return slices.Contains([]string{"List", "Get", "Create", "Update", "Delete"}, m.Name)
}, kubeapi("kubeclient_nodepool"))
apiCmd, _ := lo.Find(nodepoolCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "api" })
apiCmd.PersistentFlags().String("cluster", "", "[REQUIRED] Name or ID of cluster")
_ = apiCmd.MarkPersistentFlagRequired("cluster")
apiCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project")
// nodepool commands need to be added to the upper level, otherwise we will get kube nodepool nodepool
b.Build(oksCmd, apiCmd)
clusterCmd, _ := lo.Find(oksCmd.Commands(), func(c *cobra.Command) bool { return c.Name() == "nodepool" })
clusterCmd.PersistentFlags().String("project", preferences.Preferences.Kube.DefaultProject, "project name")
for _, cmd := range nodepoolCmd.Commands() {
if cmd.Name() == "api" {
cmd.PersistentFlags().String("cluster", "", "[REQUIRED] ID of cluster")
_ = cmd.MarkPersistentFlagRequired("cluster")
} else {
cmd.Flags().String("cluster", "", "[REQUIRED] Name or ID of cluster")
cmd.Flags().String("project", preferences.Preferences.Kube.DefaultProject, "Name or ID of project")
_ = cmd.MarkFlagRequired("cluster")
_ = flags.MarkAsNoForward(cmd.Flags(), "project")
}
}
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ func Root() *cobra.Command {
}

func init() {
cobra.EnableTraverseRunHooks = true

md := markdown.NewRenderer()
if long, err := md.Render(rootCmd.Long); err == nil {
rootCmd.Long = long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ octl iaas consumptionaccount aggregate all [flags]
### Options

```
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14).
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month)
-h, --help help for all
--overall If false, returns only the consumption of the specific account that sends this request.
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30).
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today)
```

### Options inherited from parent commands
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ octl iaas consumptionaccount aggregate compute [flags]
### Options

```
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14).
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month)
-h, --help help for compute
--overall If false, returns only the consumption of the specific account that sends this request.
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30).
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today)
```

### Options inherited from parent commands
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ octl iaas consumptionaccount aggregate gpu [flags]
### Options

```
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14).
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month)
-h, --help help for gpu
--overall If false, returns only the consumption of the specific account that sends this request.
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30).
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today)
```

### Options inherited from parent commands
Expand Down
4 changes: 2 additions & 2 deletions docs/reference/octl_iaas_consumptionaccount_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ octl iaas consumptionaccount list [flags]
### Options

```
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14).
--from-date osctime The beginning of the time period, in ISO 8601 date format (for example, 2020-06-14). (default beginning-of-month)
-h, --help help for list
--overall If false, returns only the consumption of the specific account that sends this request.
--show-price If true, the response also includes the unit price of the consumed resource (UnitPrice) and the total price of the consumed resource during the specified time period (Price), in the currency of the Region's catalog.
--show-resource-details By default or if false, returns the consumption aggregated by resource type.
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30).
--to-date osctime The end of the time period, in ISO 8601 date format (for example, 2020-06-30). (default today)
```

### Options inherited from parent commands
Expand Down
1 change: 0 additions & 1 deletion docs/reference/octl_kube_api_CreateCluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ octl kube api CreateCluster [flags]
--Tags stringToString (default [])
--Version string Version of Kubernetes to be deployed
-h, --help help for CreateCluster
--project string project name
```

### Options inherited from parent commands
Expand Down
3 changes: 1 addition & 2 deletions docs/reference/octl_kube_api_DeleteCluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ octl kube api DeleteCluster id [flags]
### Options

```
-h, --help help for DeleteCluster
--project string project name
-h, --help help for DeleteCluster
```

### Options inherited from parent commands
Expand Down
3 changes: 1 addition & 2 deletions docs/reference/octl_kube_api_GetCluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ octl kube api GetCluster id [flags]
### Options

```
-h, --help help for GetCluster
--project string project name
-h, --help help for GetCluster
```

### Options inherited from parent commands
Expand Down
Loading
Loading