feat: projects subcommand + fixes

This commit is contained in:
Andras Bacsai
2025-01-21 11:12:26 +01:00
parent 446a7f43d9
commit a641fca3d0
8 changed files with 262 additions and 18 deletions
+29
View File
@@ -0,0 +1,29 @@
You are an expert AI programming assistant specializing in building APIs with Go, using the standard library's net/http package and the new ServeMux introduced in Go 1.22.
Always use the latest stable version of Go (1.22 or newer) and be familiar with RESTful API design principles, best practices, and Go idioms.
- Follow the user's requirements carefully & to the letter.
- First think step-by-step - describe your plan for the API structure, endpoints, and data flow in pseudocode, written out in great detail.
- Confirm the plan, then write code!
- Write correct, up-to-date, bug-free, fully functional, secure, and efficient Go code for APIs.
- Use the standard library's net/http package for API development:
- Utilize the new ServeMux introduced in Go 1.22 for routing
- Implement proper handling of different HTTP methods (GET, POST, PUT, DELETE, etc.)
- Use method handlers with appropriate signatures (e.g., func(w http.ResponseWriter, r *http.Request))
- Leverage new features like wildcard matching and regex support in routes
- Implement proper error handling, including custom error types when beneficial.
- Use appropriate status codes and format JSON responses correctly.
- Implement input validation for API endpoints.
- Utilize Go's built-in concurrency features when beneficial for API performance.
- Follow RESTful API design principles and best practices.
- Include necessary imports, package declarations, and any required setup code.
- Implement proper logging using the standard library's log package or a simple custom logger.
- Consider implementing middleware for cross-cutting concerns (e.g., logging, authentication).
- Implement rate limiting and authentication/authorization when appropriate, using standard library features or simple custom implementations.
- Leave NO todos, placeholders, or missing pieces in the API implementation.
- Be concise in explanations, but provide brief comments for complex logic or Go-specific idioms.
- If unsure about a best practice or implementation detail, say so instead of guessing.
- Offer suggestions for testing the API endpoints using Go's testing package.
Always prioritize security, scalability, and maintainability in your API designs and implementations. Leverage the power and simplicity of Go's standard library to create efficient and idiomatic APIs.
+1 -1
View File
@@ -29,7 +29,7 @@ var deployByUuidCmd = &cobra.Command{
Short: "Deploy by uuid",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.237")
CheckDefaultThings(nil)
var CsvUuids = ""
for _, uuid := range args {
CsvUuids += uuid + ","
+3 -3
View File
@@ -23,7 +23,7 @@ var listDomainsCmd = &cobra.Command{
Use: "list",
Short: "List all domains",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.237")
CheckDefaultThings(nil)
data, err := Fetch("domains")
if err != nil {
log.Println(err)
@@ -62,7 +62,7 @@ var listDomainsCmd = &cobra.Command{
}
func init() {
rootCmd.AddCommand(domainsCmd)
domainsCmd.AddCommand(listDomainsCmd)
// rootCmd.AddCommand(domainsCmd)
// domainsCmd.AddCommand(listDomainsCmd)
}
+6 -4
View File
@@ -32,7 +32,7 @@ var listPrivateKeysCmd = &cobra.Command{
Use: "list",
Short: "List all private keys",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.235")
CheckDefaultThings(nil)
baseUrl := "security/keys"
data, err := Fetch(baseUrl)
@@ -78,7 +78,7 @@ var onePrivateKeyCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Short: "Get private key details by uuid",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.235")
CheckDefaultThings(nil)
baseUrl := "security/keys/"
uuid := args[0]
@@ -128,7 +128,8 @@ var addPrivateKeyCmd = &cobra.Command{
Args: cobra.ExactArgs(2),
Short: "Add a private key",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.383")
version := "4.0.0-beta.383"
CheckDefaultThings(&version)
baseUrl := "security/keys"
name := args[0]
privateKeyInput := args[1]
@@ -169,7 +170,8 @@ var removePrivateKeyCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Short: "Remove a private key",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.383")
version := "4.0.0-beta.383"
CheckDefaultThings(&version)
baseUrl := "security/keys/"
uuid := args[0]
_, err := Delete(baseUrl + uuid)
+211
View File
@@ -0,0 +1,211 @@
package cmd
import (
"bytes"
"encoding/json"
"fmt"
"log"
"strings"
"github.com/spf13/cobra"
)
type Application struct {
ID int `json:"id"`
Uuid string `json:"uuid"`
Name string `json:"name"`
Description string `json:"description"`
Status string `json:"status"`
}
type Environment struct {
ID int `json:"id"`
Uuid string `json:"uuid"`
Name string `json:"name"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
Description *string `json:"description"`
Applications []Application `json:"applications"`
}
type Project struct {
Uuid string `json:"uuid"`
Name string `json:"name"`
Environments []Environment `json:"environments"`
}
var projectsCmd = &cobra.Command{
Use: "projects",
Short: "Project related commands",
}
var listProjectsCmd = &cobra.Command{
Use: "list",
Short: "List all projects",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings(nil)
baseUrl := "projects"
data, err := Fetch(baseUrl)
if err != nil {
log.Println(err)
return
}
if PrettyMode {
var prettyJSON bytes.Buffer
err := json.Indent(&prettyJSON, []byte(data), "", "\t")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(prettyJSON.String()))
return
}
if JsonMode {
fmt.Println(data)
return
}
var jsondata []Project
err = json.Unmarshal([]byte(data), &jsondata)
if err != nil {
fmt.Println(err)
return
}
fmt.Fprintln(w, "Uuid\tName")
for _, resource := range jsondata {
fmt.Fprintf(w, "%s\t%s\n", resource.Uuid, resource.Name)
}
w.Flush()
},
}
var oneProjectCmd = &cobra.Command{
Use: "get [uuid]",
Short: "Get a project by uuid",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings(nil)
uuid := args[0]
environment, _ := cmd.Flags().GetString("environment")
if environment != "" {
url := "projects/" + uuid + "/" + environment
data, err := Fetch(url)
if err != nil {
log.Println(err)
return
}
if PrettyMode {
var prettyJSON bytes.Buffer
err := json.Indent(&prettyJSON, []byte(data), "", "\t")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(prettyJSON.String()))
return
}
if JsonMode {
fmt.Println(data)
return
}
var jsondata Environment
err = json.Unmarshal([]byte(data), &jsondata)
if err != nil {
log.Println(err)
return
}
fmt.Fprintln(w, "Uuid\tName\tStatus")
for _, resource := range jsondata.Applications {
fmt.Fprintf(w, "%s\t%s\t%s\n", resource.Uuid, resource.Name, resource.Status)
}
w.Flush()
return
}
data, err := Fetch("projects/" + uuid)
if err != nil {
log.Println(err)
return
}
if PrettyMode {
var prettyJSON bytes.Buffer
err := json.Indent(&prettyJSON, []byte(data), "", "\t")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(prettyJSON.String()))
return
}
if JsonMode {
fmt.Println(data)
return
}
var jsondata Project
err = json.Unmarshal([]byte(data), &jsondata)
if err != nil {
log.Println(err)
return
}
fmt.Fprintln(w, "Uuid\tName\tEnvironments")
envNames := make([]string, len(jsondata.Environments))
for i, env := range jsondata.Environments {
envNames[i] = env.Name + " (" + env.Uuid + ")"
}
fmt.Fprintf(w, "%s\t%s\t%s\n", jsondata.Uuid, jsondata.Name, strings.Join(envNames, ", "))
w.Flush()
},
}
var addProjectCmd = &cobra.Command{
Use: "add [name]",
Short: "Add a project",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings(nil)
baseUrl := "projects"
name := args[0]
data := map[string]string{
"name": name,
}
jsonData, err := json.Marshal(data)
if err != nil {
fmt.Println(err)
return
}
response, err := Post(baseUrl, bytes.NewBuffer(jsonData))
if err != nil {
fmt.Println(err)
return
}
msg := map[string]string{}
json.Unmarshal([]byte(response), &msg)
fmt.Println("Project added successfully with uuid " + msg["uuid"])
},
}
var removeProjectCmd = &cobra.Command{
Use: "remove [uuid]",
Short: "Remove a project",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings(nil)
baseUrl := "projects/"
uuid := args[0]
response, err := Delete(baseUrl + uuid)
if err != nil {
fmt.Println(err)
return
}
msg := map[string]string{}
json.Unmarshal([]byte(response), &msg)
fmt.Println(msg["message"])
},
}
func init() {
rootCmd.AddCommand(projectsCmd)
projectsCmd.AddCommand(listProjectsCmd)
oneProjectCmd.Flags().StringP("environment", "e", "", "Environment")
projectsCmd.AddCommand(oneProjectCmd)
projectsCmd.AddCommand(addProjectCmd)
projectsCmd.AddCommand(removeProjectCmd)
}
+1 -1
View File
@@ -18,7 +18,7 @@ var listResourcesCmd = &cobra.Command{
Use: "list",
Short: "List all resources",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.237")
CheckDefaultThings(nil)
data, err := Fetch("resources")
if err != nil {
log.Println(err)
+6 -4
View File
@@ -71,15 +71,17 @@ func CheckFormat(format string) {
os.Exit(0)
}
func CheckDefaultThings(version string) {
func CheckDefaultThings(version *string) {
FetchVersion()
CheckFormat(Format)
if version != "" {
CheckMinimumVersion(version)
if version == nil {
CheckMinimumVersion(Version)
} else {
CheckMinimumVersion(*version)
}
}
func CheckMinimumVersion(version string) {
FetchVersion()
requiredVersion, err := compareVersion.NewVersion(version)
if err != nil {
log.Println(err)
+5 -5
View File
@@ -45,7 +45,7 @@ var listServersCmd = &cobra.Command{
Use: "list",
Short: "List all servers",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.235")
CheckDefaultThings(nil)
baseUrl := "servers"
data, err := Fetch(baseUrl)
@@ -91,7 +91,7 @@ var oneServerCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Short: "Get server details by uuid",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.235")
CheckDefaultThings(nil)
baseUrl := "servers/"
uuid := args[0]
@@ -156,7 +156,7 @@ var removeServerCmd = &cobra.Command{
Use: "remove [uuid]",
Short: "Remove a server",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.235")
CheckDefaultThings(nil)
baseUrl := "servers/"
uuid := args[0]
response, err := Delete(baseUrl + uuid)
@@ -174,7 +174,7 @@ var addServerCmd = &cobra.Command{
Use: "add [name] [ip] [private_key_uuid]",
Short: "Add a server",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.235")
CheckDefaultThings(nil)
baseUrl := "servers"
name := args[0]
ip := args[1]
@@ -213,7 +213,7 @@ var validateServerCmd = &cobra.Command{
Use: "validate [uuid]",
Short: "Validate a server",
Run: func(cmd *cobra.Command, args []string) {
CheckDefaultThings("4.0.0-beta.235")
CheckDefaultThings(nil)
baseUrl := "servers/"
uuid := args[0]
var url = baseUrl + uuid + "/validate"