-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Load Balancers and Certificates (#245)
Signed-off-by: Lukas Kämmerling <[email protected]>
- Loading branch information
1 parent
196557e
commit 50a7de3
Showing
38 changed files
with
2,344 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package cli | ||
|
||
import "github.com/spf13/cobra" | ||
|
||
func newCertificatesCommand(cli *CLI) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "certificate", | ||
Short: "Manage certificates", | ||
Args: cobra.NoArgs, | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
RunE: cli.wrap(runCertificates), | ||
} | ||
cmd.AddCommand( | ||
newCertificatesListCommand(cli), | ||
newCertificateCreateCommand(cli), | ||
newCertificateUpdateCommand(cli), | ||
newCertificateAddLabelCommand(cli), | ||
newCertificateRemoveLabelCommand(cli), | ||
newCertificateDeleteCommand(cli), | ||
newCertificateDescribeCommand(cli), | ||
) | ||
|
||
return cmd | ||
} | ||
|
||
func runCertificates(cli *CLI, cmd *cobra.Command, args []string) error { | ||
return cmd.Usage() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package cli | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hetznercloud/hcloud-go/hcloud" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func newCertificateAddLabelCommand(cli *CLI) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "add-label [FLAGS] CERTIFICATE LABEL", | ||
Short: "Add a label to a certificate", | ||
Args: cobra.ExactArgs(2), | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
PreRunE: chainRunE(validateCertificateAddLabel, cli.ensureToken), | ||
RunE: cli.wrap(runCertificateAddLabel), | ||
} | ||
|
||
cmd.Flags().BoolP("overwrite", "o", false, "Overwrite label if it exists already") | ||
return cmd | ||
} | ||
|
||
func validateCertificateAddLabel(cmd *cobra.Command, args []string) error { | ||
label := splitLabel(args[1]) | ||
if len(label) != 2 { | ||
return fmt.Errorf("invalid label: %s", args[1]) | ||
} | ||
return nil | ||
} | ||
|
||
func runCertificateAddLabel(cli *CLI, cmd *cobra.Command, args []string) error { | ||
overwrite, err := cmd.Flags().GetBool("overwrite") | ||
if err != nil { | ||
return err | ||
} | ||
idOrName := args[0] | ||
cert, _, err := cli.Client().Certificate.Get(cli.Context, idOrName) | ||
if err != nil { | ||
return err | ||
} | ||
if cert == nil { | ||
return fmt.Errorf("Certificate not found: %s", idOrName) | ||
} | ||
label := splitLabel(args[1]) | ||
if _, ok := cert.Labels[label[0]]; ok && !overwrite { | ||
return fmt.Errorf("Label %s on certificate %d already exists", label[0], cert.ID) | ||
} | ||
if cert.Labels == nil { | ||
cert.Labels = make(map[string]string) | ||
} | ||
labels := cert.Labels | ||
labels[label[0]] = label[1] | ||
opts := hcloud.CertificateUpdateOpts{ | ||
Labels: labels, | ||
} | ||
_, _, err = cli.Client().Certificate.Update(cli.Context, cert, opts) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("Label %s added to certificate %d\n", label[0], cert.ID) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package cli | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
|
||
"github.com/hetznercloud/hcloud-go/hcloud" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func newCertificateCreateCommand(cli *CLI) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "create [FLAGS]", | ||
Short: "Create or upload a Certificate", | ||
Args: cobra.NoArgs, | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
PreRunE: cli.ensureToken, | ||
RunE: cli.wrap(runCertificateCreate), | ||
} | ||
|
||
cmd.Flags().String("name", "", "Certificate name") | ||
cmd.MarkFlagRequired("name") | ||
|
||
cmd.Flags().String("cert-file", "", "File containing the PEM encoded certificate") | ||
cmd.MarkFlagRequired("cert-file") | ||
|
||
cmd.Flags().String("key-file", "", "File containing the PEM encoded private key for the certificate") | ||
cmd.MarkFlagRequired("key-file") | ||
|
||
return cmd | ||
} | ||
|
||
func runCertificateCreate(cli *CLI, cmd *cobra.Command, args []string) error { | ||
var ( | ||
name string | ||
|
||
certFile, keyFile string | ||
certPEM, keyPEM []byte | ||
cert *hcloud.Certificate | ||
|
||
err error | ||
) | ||
if name, err = cmd.Flags().GetString("name"); err != nil { | ||
return err | ||
} | ||
if certFile, err = cmd.Flags().GetString("cert-file"); err != nil { | ||
return err | ||
} | ||
if keyFile, err = cmd.Flags().GetString("key-file"); err != nil { | ||
return err | ||
} | ||
|
||
if certPEM, err = ioutil.ReadFile(certFile); err != nil { | ||
return err | ||
} | ||
if keyPEM, err = ioutil.ReadFile(keyFile); err != nil { | ||
return err | ||
} | ||
|
||
createOpts := hcloud.CertificateCreateOpts{ | ||
Certificate: string(certPEM), | ||
Name: name, | ||
PrivateKey: string(keyPEM), | ||
} | ||
if cert, _, err = cli.Client().Certificate.Create(cli.Context, createOpts); err != nil { | ||
return err | ||
} | ||
fmt.Printf("Certificate %d created\n", cert.ID) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package cli | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
func newCertificateDeleteCommand(cli *CLI) *cobra.Command { | ||
return &cobra.Command{ | ||
Use: "delete CERTIFICATE", | ||
Short: "Delete a certificate", | ||
Args: cobra.ExactArgs(1), | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
PreRunE: cli.ensureToken, | ||
RunE: cli.wrap(runCertificateDelete), | ||
} | ||
} | ||
|
||
func runCertificateDelete(cli *CLI, cmd *cobra.Command, args []string) error { | ||
idOrName := args[0] | ||
cert, _, err := cli.Client().Certificate.Get(cli.Context, idOrName) | ||
if err != nil { | ||
return err | ||
} | ||
if cert == nil { | ||
return fmt.Errorf("Certificate %s not found", idOrName) | ||
} | ||
_, err = cli.Client().Certificate.Delete(cli.Context, cert) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("Certificate %d deleted\n", cert.ID) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package cli | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
humanize "github.com/dustin/go-humanize" | ||
"github.com/hetznercloud/hcloud-go/hcloud" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
func newCertificateDescribeCommand(cli *CLI) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "describe [FLAGS] CERTIFICATE", | ||
Short: "Describe a certificate", | ||
Args: cobra.ExactArgs(1), | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
PreRunE: cli.ensureToken, | ||
RunE: cli.wrap(runCertificateDescribe), | ||
} | ||
addOutputFlag(cmd, outputOptionJSON(), outputOptionFormat()) | ||
return cmd | ||
} | ||
|
||
func runCertificateDescribe(cli *CLI, cmd *cobra.Command, args []string) error { | ||
outputFlags := outputFlagsForCommand(cmd) | ||
|
||
idOrName := args[0] | ||
cert, resp, err := cli.Client().Certificate.Get(cli.Context, idOrName) | ||
if err != nil { | ||
return err | ||
} | ||
if cert == nil { | ||
return fmt.Errorf("certificate not found: %s", idOrName) | ||
} | ||
|
||
switch { | ||
case outputFlags.IsSet("json"): | ||
return certificateDescribeJSON(resp) | ||
case outputFlags.IsSet("format"): | ||
return describeFormat(cert, outputFlags["format"][0]) | ||
default: | ||
return certificateDescribeText(cli, cert) | ||
} | ||
} | ||
|
||
func certificateDescribeJSON(resp *hcloud.Response) error { | ||
var data map[string]interface{} | ||
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil { | ||
return err | ||
} | ||
if server, ok := data["certificate"]; ok { | ||
return describeJSON(server) | ||
} | ||
if servers, ok := data["certificates"].([]interface{}); ok { | ||
return describeJSON(servers[0]) | ||
} | ||
return describeJSON(data) | ||
} | ||
|
||
func certificateDescribeText(cli *CLI, cert *hcloud.Certificate) error { | ||
fmt.Printf("ID:\t\t\t%d\n", cert.ID) | ||
fmt.Printf("Name:\t\t\t%s\n", cert.Name) | ||
fmt.Printf("Fingerprint:\t\t%s\n", cert.Fingerprint) | ||
fmt.Printf("Created:\t\t%s (%s)\n", datetime(cert.Created), humanize.Time(cert.Created)) | ||
fmt.Printf("Not valid before:\t%s (%s)\n", datetime(cert.NotValidBefore), humanize.Time(cert.NotValidBefore)) | ||
fmt.Printf("Not valid after:\t%s (%s)\n", datetime(cert.NotValidAfter), humanize.Time(cert.NotValidAfter)) | ||
fmt.Printf("Domain names:\n") | ||
for _, domainName := range cert.DomainNames { | ||
fmt.Printf(" - %s\n", domainName) | ||
} | ||
fmt.Print("Labels:\n") | ||
if len(cert.Labels) == 0 { | ||
fmt.Print(" No labels\n") | ||
} else { | ||
for key, value := range cert.Labels { | ||
fmt.Printf(" %s:\t%s\n", key, value) | ||
} | ||
} | ||
return nil | ||
} |
Oops, something went wrong.