diff --git a/scripts/portainer/client/client.go b/scripts/portainer/client/client.go new file mode 100644 index 0000000..cdf6d25 --- /dev/null +++ b/scripts/portainer/client/client.go @@ -0,0 +1,64 @@ +package client + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +const ( + applicationJson = "application/json" +) + +type PortainerClient struct { + authToken string + baseUrl string +} + +func NewPortainerClient(baseUrl string) *PortainerClient { + return &PortainerClient{ + baseUrl: baseUrl, + } +} + +func (c *PortainerClient) IsLoggedIn() bool { + return c.authToken != "" +} + +func (c *PortainerClient) post(path string, payload interface{}) ([]byte, error) { + jsonBytes, err := json.Marshal(payload) + if err != nil { + return nil, err + } + + url := fmt.Sprintf("%s/%s", c.baseUrl, path) + resp, err := http.Post(url, applicationJson, bytes.NewBuffer(jsonBytes)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return body, nil +} + +func (c *PortainerClient) Login(username, password string) error { + payload := map[string]string{"Username": username, "Password": password} + body, err := c.post("api/auth", payload) + if err != nil { + return err + } + type JwtToken struct { + Token string `json:"jwt"` + } + token := JwtToken{} + if err := json.Unmarshal(body, &token); err != nil { + return err + } + c.authToken = token.Token + return nil +} diff --git a/scripts/portainer/go.mod b/scripts/portainer/go.mod new file mode 100644 index 0000000..007ae31 --- /dev/null +++ b/scripts/portainer/go.mod @@ -0,0 +1,3 @@ +module github.com/chatton/portainer + +go 1.18 diff --git a/scripts/portainer/main.go b/scripts/portainer/main.go new file mode 100644 index 0000000..60e2f02 --- /dev/null +++ b/scripts/portainer/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "log" + "os" + "os/user" + + "github.com/chatton/portainer/client" +) + +const ( + applicationJson = "application/json" + baseUrl = "http://qnap:9000" +) + +type PortainerCredentials struct { + Username string `json:"username"` + Password string `json:"password"` +} + +func loadCreds() PortainerCredentials { + usr, _ := user.Current() + credPath := fmt.Sprintf("%s/.homelab/portainer-creds.json", usr.HomeDir) + + if _, err := os.Stat(credPath); errors.Is(err, os.ErrNotExist) { + log.Fatal(fmt.Errorf("there must be a credentials file under: %s", credPath)) + } + + fileBytes, err := os.ReadFile(credPath) + if err != nil { + log.Fatal(err) + } + + creds := PortainerCredentials{} + if err := json.Unmarshal(fileBytes, &creds); err != nil { + log.Fatal(err) + } + return creds +} + +func main() { + c := client.NewPortainerClient(baseUrl) + creds := loadCreds() + err := c.Login(creds.Username, creds.Password) + if err != nil { + log.Fatalln(err) + } +}