Skip to content

Commit e45e1f6

Browse files
committed
Initial commit
0 parents  commit e45e1f6

File tree

11 files changed

+339
-0
lines changed

11 files changed

+339
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
onyxia-cli
2+
go.sum
3+
.gitlab-ci.yml

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Onyxia CLI
2+
3+
## Work in progress
4+
5+
This is currently a work in progress.
6+
7+
## Enable autocompletion
8+
9+
```
10+
PROG=onyxia source bash_autocomplete
11+
```

bash_autocomplete

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#! /bin/bash
2+
3+
: ${PROG:=$(basename ${BASH_SOURCE})}
4+
5+
_cli_bash_autocomplete() {
6+
if [[ "${COMP_WORDS[0]}" != "source" ]]; then
7+
local cur opts base
8+
COMPREPLY=()
9+
cur="${COMP_WORDS[COMP_CWORD]}"
10+
if [[ "$cur" == "-"* ]]; then
11+
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} ${cur} --generate-bash-completion )
12+
else
13+
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
14+
local IFS=$'\n'
15+
fi
16+
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
17+
unset IFS
18+
return 0
19+
fi
20+
}
21+
22+
complete -o bashdefault -o default -F _cli_bash_autocomplete $PROG
23+
unset PROG

config.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
API:
2+
URL: "https://example.com"

go.mod

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module onyxia-cli
2+
3+
go 1.13
4+
5+
require (
6+
github.com/kelseyhightower/envconfig v1.4.0
7+
github.com/urfave/cli/v2 v2.1.1
8+
gopkg.in/yaml.v2 v2.2.8
9+
)

main.go

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package main
2+
3+
import (
4+
"crypto/tls"
5+
"fmt"
6+
"log"
7+
"net/http"
8+
"os"
9+
10+
// "strings"
11+
12+
"onyxia-cli/src/api"
13+
. "onyxia-cli/src/configuration"
14+
"onyxia-cli/src/oidc"
15+
16+
"github.com/urfave/cli/v2"
17+
)
18+
19+
func main() {
20+
ReadConfig()
21+
// Disable SSL validation
22+
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
23+
24+
app := &cli.App{
25+
Version: "v0.1",
26+
Name: "onyxia-cli",
27+
Usage: "CLI for Onyxia services",
28+
EnableBashCompletion: true,
29+
Flags: []cli.Flag{
30+
&cli.StringFlag{
31+
Name: "accessToken",
32+
Aliases: []string{"token"},
33+
EnvVars: []string{"KC_ACCESS_TOKEN"},
34+
Required: true,
35+
},
36+
},
37+
Commands: []*cli.Command{
38+
{
39+
Name: "whoami",
40+
Usage: "Show user's informations",
41+
Action: func(c *cli.Context) error {
42+
tokenString := c.String("accessToken")
43+
oidc.DisplayID(tokenString)
44+
return nil
45+
},
46+
},
47+
{
48+
Name: "kub",
49+
Usage: "Setup kubernetes",
50+
Subcommands: []*cli.Command{
51+
{
52+
Name: "create",
53+
Usage: "Create resources",
54+
Subcommands: []*cli.Command{
55+
{
56+
Name: "namespace",
57+
Usage: "Create namespace",
58+
Flags: []cli.Flag{
59+
&cli.StringFlag{
60+
Name: "namespaceName",
61+
Aliases: []string{"name", "n"},
62+
Usage: "Name of the namespace to create",
63+
Required: true,
64+
},
65+
&cli.StringFlag{
66+
Name: "namespaceOwnerType",
67+
Aliases: []string{"ownerType", "t"},
68+
Required: false,
69+
Usage: "The type of ownership. Can be either USER or GROUP.",
70+
DefaultText: "USER",
71+
Value: "USER",
72+
},
73+
&cli.StringFlag{
74+
Name: "namespaceOwner",
75+
Aliases: []string{"owner", "o"},
76+
Required: false,
77+
Usage: "The owner of the namespace.",
78+
DefaultText: "YOU",
79+
},
80+
},
81+
Action: func(c *cli.Context) error {
82+
namespaceName := c.String("namespaceName")
83+
tokenString := c.String("accessToken")
84+
ownerType := c.String("namespaceOwnerType")
85+
ownerName := c.String("namespaceOwner")
86+
if ownerType == "USER" {
87+
api.CreateNamespace(tokenString, namespaceName, ownerType, "oidc"+oidc.GetID(tokenString).Preferred_username)
88+
} else {
89+
if ownerName == "" {
90+
fmt.Println("Veuillez choisir un groupe parmi ceux-ci :")
91+
oidc.DisplayGroups(oidc.GetID(tokenString), false)
92+
} else {
93+
api.CreateNamespace(tokenString, namespaceName, ownerType, "oidc"+ownerName)
94+
}
95+
}
96+
return nil
97+
},
98+
BashComplete: func(c *cli.Context) {
99+
if c.NArg() > 0 {
100+
return
101+
}
102+
if os.Args[len(os.Args)-2] == "-o" || os.Args[len(os.Args)-2] == "--owner" {
103+
oidc.DisplayGroups(oidc.GetID(c.String("accessToken")), true)
104+
} else if os.Args[len(os.Args)-2] == "-t" || os.Args[len(os.Args)-2] == "--ownerType" {
105+
for _, elem := range []string{"GROUP", "USER"} {
106+
fmt.Println(elem)
107+
}
108+
}
109+
},
110+
},
111+
},
112+
},
113+
},
114+
},
115+
},
116+
}
117+
118+
err := app.Run(os.Args)
119+
if err != nil {
120+
log.Fatal(err)
121+
}
122+
}

src/api/api.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
"os"
10+
11+
"onyxia-cli/src/configuration"
12+
)
13+
14+
func CreateNamespace(token string, namespaceName string, ownerType string, ownerId string) {
15+
request := &CreateNamespaceDTO{
16+
Namespace: Namespace{
17+
Id: namespaceName,
18+
},
19+
Owner: Owner{
20+
Type: ownerType,
21+
Id: ownerId,
22+
},
23+
}
24+
fmt.Printf("Creating namespace %s as %s %s\n", namespaceName, request.Owner.Type, request.Owner.Id)
25+
buf := new(bytes.Buffer)
26+
json.NewEncoder(buf).Encode(request)
27+
req, _ := http.NewRequest("POST", configuration.Configuration.API.URL+"/api/namespace", buf)
28+
29+
req.Header.Add("Authorization", "Bearer "+token)
30+
req.Header.Set("Content-Type", "application/json")
31+
32+
client := &http.Client{}
33+
res, e := client.Do(req)
34+
if e != nil {
35+
panic(e)
36+
}
37+
38+
defer res.Body.Close()
39+
40+
fmt.Println("response Status:", res.Status)
41+
// Print the body to the stdout
42+
io.Copy(os.Stdout, res.Body)
43+
}

src/api/createNamespaceDTO.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package api
2+
3+
type CreateNamespaceDTO struct {
4+
Owner Owner `json:"owner"`
5+
Namespace Namespace `json:"namespace"`
6+
}
7+
8+
type Owner struct {
9+
Id string `json:"id"`
10+
Type string `json:"type"`
11+
}
12+
13+
type Namespace struct {
14+
Id string `json:"id"`
15+
}

src/configuration/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package configuration
2+
3+
type Config struct {
4+
API struct {
5+
URL string `yaml:"URL", envconfig:"API_URL"`
6+
} `yaml:"API"`
7+
}

src/configuration/readConfig.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package configuration
2+
3+
import (
4+
"fmt"
5+
"os"
6+
7+
"gopkg.in/yaml.v2"
8+
9+
"github.com/kelseyhightower/envconfig"
10+
)
11+
12+
var Configuration Config
13+
14+
func ReadConfig() {
15+
readFile(&Configuration)
16+
readEnv(&Configuration)
17+
}
18+
19+
func processError(err error) {
20+
fmt.Println(err)
21+
os.Exit(2)
22+
}
23+
24+
func readFile(cfg *Config) {
25+
f, err := os.Open("config.yml")
26+
if err != nil {
27+
processError(err)
28+
}
29+
defer f.Close()
30+
31+
decoder := yaml.NewDecoder(f)
32+
err = decoder.Decode(cfg)
33+
if err != nil {
34+
processError(err)
35+
}
36+
}
37+
38+
func readEnv(cfg *Config) {
39+
err := envconfig.Process("", cfg)
40+
if err != nil {
41+
processError(err)
42+
}
43+
}

0 commit comments

Comments
 (0)