-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
67ba0ad
commit afd597a
Showing
23 changed files
with
1,191 additions
and
10 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ | |
/dist | ||
/bats | ||
/cmd/hcloud/hcloud | ||
hcloud_cli.p12 |
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,24 @@ | ||
[ | ||
{ | ||
"direction": "in", | ||
"source_ips": [ | ||
"28.239.13.1/32", | ||
"28.239.14.0/24", | ||
"ff21:1eac:9a3b:ee58:5ca:990c:8bc9:c03b/128" | ||
], | ||
"destination_ips": [], | ||
"protocol": "tcp", | ||
"port": "80" | ||
}, | ||
{ | ||
"direction": "out", | ||
"source_ips": [], | ||
"destination_ips": [ | ||
"28.239.13.1/32", | ||
"28.239.14.0/24", | ||
"ff21:1eac:9a3b:ee58:5ca:990c:8bc9:c03b/128" | ||
], | ||
"protocol": "tcp", | ||
"port": "80" | ||
} | ||
] |
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
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,68 @@ | ||
package firewall | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hetznercloud/hcloud-go/hcloud" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/hetznercloud/cli/internal/cmd/cmpl" | ||
"github.com/hetznercloud/cli/internal/cmd/util" | ||
"github.com/hetznercloud/cli/internal/state" | ||
) | ||
|
||
func newAddLabelCommand(cli *state.State) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "add-label [FLAGS] FIREWALL LABEL", | ||
Short: "Add a label to a Firewall", | ||
Args: cobra.ExactArgs(2), | ||
ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(cli.FirewallNames)), | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
PreRunE: util.ChainRunE(validateFirewallAddLabel, cli.EnsureToken), | ||
RunE: cli.Wrap(runFirewallAddLabel), | ||
} | ||
|
||
cmd.Flags().BoolP("overwrite", "o", false, "Overwrite label if it exists already") | ||
return cmd | ||
} | ||
|
||
func validateFirewallAddLabel(cmd *cobra.Command, args []string) error { | ||
label := util.SplitLabel(args[1]) | ||
if len(label) != 2 { | ||
return fmt.Errorf("invalid label: %s", args[1]) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func runFirewallAddLabel(cli *state.State, cmd *cobra.Command, args []string) error { | ||
overwrite, _ := cmd.Flags().GetBool("overwrite") | ||
|
||
idOrName := args[0] | ||
firewall, _, err := cli.Client().Firewall.Get(cli.Context, idOrName) | ||
if err != nil { | ||
return err | ||
} | ||
if firewall == nil { | ||
return fmt.Errorf("Firewall not found: %v", idOrName) | ||
} | ||
|
||
label := util.SplitLabel(args[1]) | ||
|
||
if _, ok := firewall.Labels[label[0]]; ok && !overwrite { | ||
return fmt.Errorf("label %s on Firewall %d already exists", label[0], firewall.ID) | ||
} | ||
labels := firewall.Labels | ||
labels[label[0]] = label[1] | ||
opts := hcloud.FirewallUpdateOpts{ | ||
Labels: labels, | ||
} | ||
_, _, err = cli.Client().Firewall.Update(cli.Context, firewall, opts) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Printf("Label %s added to Firewall %d\n", label[0], firewall.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,112 @@ | ||
package firewall | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
|
||
"github.com/hetznercloud/hcloud-go/hcloud" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/hetznercloud/cli/internal/cmd/cmpl" | ||
"github.com/hetznercloud/cli/internal/cmd/util" | ||
"github.com/hetznercloud/cli/internal/state" | ||
) | ||
|
||
func newAddRuleCommand(cli *state.State) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "add-rule FIREWALL FLAGS", | ||
Short: "Add a single rule to a firewall", | ||
Args: cobra.ExactArgs(1), | ||
ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(cli.FirewallNames)), | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
PreRunE: util.ChainRunE(cli.EnsureToken), | ||
RunE: cli.Wrap(runAddRule), | ||
} | ||
cmd.Flags().String("direction", "", "Direction (in, out) (required)") | ||
cmd.RegisterFlagCompletionFunc("direction", cmpl.SuggestCandidates("in", "out")) | ||
cmd.MarkFlagRequired("direction") | ||
|
||
cmd.Flags().String("protocol", "", "Protocol (icmp, udp or tcp) (required)") | ||
cmd.RegisterFlagCompletionFunc("protocol", cmpl.SuggestCandidates("icmp", "udp", "tcp")) | ||
cmd.MarkFlagRequired("protocol") | ||
|
||
cmd.Flags().StringArray("source-ips", []string{}, "Source IPs (CIDR Notation) (required when direction is in)") | ||
|
||
cmd.Flags().StringArray("destination-ips", []string{}, "Destination IPs (CIDR Notation) (required when direction is out)") | ||
|
||
cmd.Flags().String("port", "", "Port to which traffic will be allowed, only applicable for protocols TCP and UDP, you can specify port ranges, sample: 80-85") | ||
return cmd | ||
} | ||
|
||
func runAddRule(cli *state.State, cmd *cobra.Command, args []string) error { | ||
direction, _ := cmd.Flags().GetString("direction") | ||
protocol, _ := cmd.Flags().GetString("protocol") | ||
sourceIPs, _ := cmd.Flags().GetStringArray("source-ips") | ||
destinationIPs, _ := cmd.Flags().GetStringArray("destination-ips") | ||
port, _ := cmd.Flags().GetString("port") | ||
|
||
idOrName := args[0] | ||
firewall, _, err := cli.Client().Firewall.Get(cli.Context, idOrName) | ||
if err != nil { | ||
return err | ||
} | ||
if firewall == nil { | ||
return fmt.Errorf("Firewall not found: %v", idOrName) | ||
} | ||
|
||
var sourceNets []net.IPNet | ||
for i, sourceIP := range sourceIPs { | ||
_, sourceNet, err := net.ParseCIDR(sourceIP) | ||
if err != nil { | ||
return fmt.Errorf("invalid CIDR on index %d : %s", i, err) | ||
} | ||
sourceNets = append(sourceNets, *sourceNet) | ||
} | ||
d := hcloud.FirewallRuleDirection(direction) | ||
rule := hcloud.FirewallRule{ | ||
Direction: d, | ||
Protocol: hcloud.FirewallRuleProtocol(protocol), | ||
} | ||
|
||
if port != "" { | ||
rule.Port = hcloud.String(port) | ||
} | ||
|
||
switch d { | ||
case hcloud.FirewallRuleDirectionOut: | ||
rule.DestinationIPs = make([]net.IPNet, 0, len(destinationIPs)) | ||
for i, ip := range destinationIPs { | ||
_, n, err := net.ParseCIDR(ip) | ||
if err != nil { | ||
return fmt.Errorf("invalid CIDR on index %d : %s", i, err) | ||
} | ||
rule.DestinationIPs[i] = *n | ||
} | ||
case hcloud.FirewallRuleDirectionIn: | ||
rule.SourceIPs = make([]net.IPNet, 0, len(sourceIPs)) | ||
for i, ip := range sourceIPs { | ||
_, n, err := net.ParseCIDR(ip) | ||
if err != nil { | ||
return fmt.Errorf("invalid CIDR on index %d : %s", i, err) | ||
} | ||
rule.SourceIPs[i] = *n | ||
} | ||
} | ||
|
||
rules := append(firewall.Rules, rule) | ||
|
||
actions, _, err := cli.Client().Firewall.SetRules(cli.Context, firewall, | ||
hcloud.FirewallSetRulesOpts{Rules: rules}, | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
if err := cli.ActionsProgresses(cli.Context, actions); err != nil { | ||
return err | ||
} | ||
|
||
fmt.Printf("Firewall Rules for Firewall %d updated\n", firewall.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,88 @@ | ||
package firewall | ||
|
||
import ( | ||
"fmt" | ||
"github.com/hetznercloud/hcloud-go/hcloud" | ||
"github.com/spf13/cobra" | ||
|
||
"github.com/hetznercloud/cli/internal/cmd/cmpl" | ||
"github.com/hetznercloud/cli/internal/cmd/util" | ||
"github.com/hetznercloud/cli/internal/state" | ||
) | ||
|
||
func newApplyToResourceCommand(cli *state.State) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "apply-to-resource FIREWALL FLAGS", | ||
Short: "Applies a Firewall to a single resource", | ||
Args: cobra.ExactArgs(1), | ||
ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(cli.FirewallNames)), | ||
TraverseChildren: true, | ||
DisableFlagsInUseLine: true, | ||
PreRunE: util.ChainRunE(validateApplyToResource, cli.EnsureToken), | ||
RunE: cli.Wrap(runApplyToResource), | ||
} | ||
cmd.Flags().String("type", "", "Resource Type (server) (required)") | ||
cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidates("server")) | ||
cmd.MarkFlagRequired("type") | ||
|
||
cmd.Flags().String("server", "", "Server name of ID (required when type is server)") | ||
cmd.RegisterFlagCompletionFunc("server", cmpl.SuggestCandidatesF(cli.ServerNames)) | ||
|
||
return cmd | ||
} | ||
func validateApplyToResource(cmd *cobra.Command, args []string) error { | ||
resourceType, _ := cmd.Flags().GetString("type") | ||
|
||
switch resourceType { | ||
case "server": | ||
server, _ := cmd.Flags().GetString("server") | ||
if server == "" { | ||
return fmt.Errorf("type %s need a --server specific", resourceType) | ||
} | ||
default: | ||
return fmt.Errorf("unknown type %s", resourceType) | ||
} | ||
|
||
return nil | ||
} | ||
func runApplyToResource(cli *state.State, cmd *cobra.Command, args []string) error { | ||
resourceType, _ := cmd.Flags().GetString("type") | ||
serverIdOrName, _ := cmd.Flags().GetString("server") | ||
|
||
idOrName := args[0] | ||
firewall, _, err := cli.Client().Firewall.Get(cli.Context, idOrName) | ||
if err != nil { | ||
return err | ||
} | ||
if firewall == nil { | ||
return fmt.Errorf("Firewall not found: %v", idOrName) | ||
} | ||
|
||
server, _, err := cli.Client().Server.Get(cli.Context, serverIdOrName) | ||
if err != nil { | ||
return err | ||
} | ||
if server == nil { | ||
return fmt.Errorf("Server not found: %v", serverIdOrName) | ||
} | ||
|
||
opts := hcloud.FirewallResource{Type: hcloud.FirewallResourceType(resourceType)} | ||
|
||
switch opts.Type { | ||
case hcloud.FirewallResourceTypeServer: | ||
opts.Server = &hcloud.FirewallResourceServer{ID: server.ID} | ||
default: | ||
return fmt.Errorf("unkown type %s", resourceType) | ||
} | ||
|
||
actions, _, err := cli.Client().Firewall.ApplyResources(cli.Context, firewall, []hcloud.FirewallResource{opts}) | ||
if err != nil { | ||
return err | ||
} | ||
if err := cli.ActionsProgresses(cli.Context, actions); err != nil { | ||
return err | ||
} | ||
fmt.Printf("Firewall %d applied\n", firewall.ID) | ||
|
||
return nil | ||
} |
Oops, something went wrong.