#Task This is the main command of the CLI tool. It's where you can do `mc-auto create` and an entire Minecraft server with DNS, port-forwarding, SFTP, and FRPC tunneling for the SFTP are all created instantly within your user namespace. It's a long command so we'll split it up into parts: ```go var createCmd = &cobra.Command{ Use: "create", Short: "Create a new server", Long: `Use this command to create a new Minecraft server. You can have a max of 3 servers. If you do not specify any flags, the default values are: serverType: "PAPER" serverModLink: str = "https://www.curseforge.com/minecraft/modpacks/all-the-mods-10/" serverDifficulty: str = "easy" serverGamemode: str = "survival" serverMotd: str = "Hello vro"`, Run: func(cmd *cobra.Command, args []string) { authToken := config.GetToken() serverType, _ := cmd.Flags().GetString("type") modLink, _ := cmd.Flags().GetString("mod-link") difficulty, _ := cmd.Flags().GetString("difficulty") gamemode, _ := cmd.Flags().GetString("gamemode") motd, _ := cmd.Flags().GetString("motd") insecureFlag, err := cmd.Flags().GetBool("insecure") server := struct { ServerType config.ServerType `json:"serverType"` ServerModLink string `json:"serverModLink"` ServerDifficulty string `json:"serverDifficulty"` ServerGamemode string `json:"serverGamemode"` ServerMotd string `json:"serverMotd"` }{ ServerType: config.ServerType(serverType), // Cast string to ServerType ServerModLink: modLink, ServerDifficulty: difficulty, ServerGamemode: gamemode, ServerMotd: motd, } json_server, err := json.Marshal(server) result := &struct { DNS string `json:"DNS"` SFTPPass string `json:"SFTP Password"` RCONPass string `json:"RCON Password"` Warnings []string `json:"Warnings"` }{} ``` - Here is the start of the function and the explanation of what the command does along with the default flags. - We define the server struct inline to avoid declaring a type out of scope that we'll never use again. - That `json:"serverType"...` part of the struct is used in the `json.Marshal()` command to map JSON fields to our struct's data fields to form the correct JSON body for the POST request later. - Same thing with the `result` struct but it's for the API's response, so it's currently empty. Moving on to the second part of the function: ```go tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: false}, } if insecureFlag { tr = &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } } client := resty.New() client.SetTransport(tr) resp, err := client.R(). SetHeader("Content-Type", "application/json"). SetHeader("authorization", "Bearer "+authToken). SetBody(json_server). SetResult(result). Post("https://" + os.Getenv("API_URL") + "servers?deploy=yes") if err != nil { fmt.Println("Error occurred creating server: ", err) } if resp.StatusCode() != 200 { fmt.Println("\nError from API: ", resp.StatusCode(), resp.String()+"\n") return } //fmt.Println("Response: ", resp) fmt.Println("DNS: ", result.DNS) fmt.Println("SFTP Password: ", result.SFTPPass) fmt.Println("RCON Password: ", result.RCONPass) if len(result.Warnings) != 0 { for _, warning := range result.Warnings { fmt.Println("\nWarnings:\n" + warning + "\n") } } ``` - The top part of the function with `http.Transport{}` allows us to specify `--insecure` when making API requests if our API currently uses an untrusted cert. - Then we use resty, which is a nice wrapper for `net/http` to create a new POST request. - The auth token was obtained at the very top of the function. - Finally, we print the response and any warnings during the server creation process described in [Develop Create Server Route](../../Python%20API/Tasks/Routes/Develop%20Create%20Server%20Route.md).