firewall

package
v1.47.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2024 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AddRuleCmd = base.Cmd{
	BaseCobraCommand: func(client hcapi2.Client) *cobra.Command {
		cmd := &cobra.Command{
			Use:                   "add-rule [options] (--direction in --source-ips <ips> | --direction out --destination-ips <ips>) (--protocol <tcp|udp> --port <port> | --protocol <icmp|esp|gre>) <firewall>",
			Short:                 "Add a single rule to a firewall",
			ValidArgsFunction:     cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Firewall().Names)),
			TraverseChildren:      true,
			DisableFlagsInUseLine: true,
		}
		cmd.Flags().String("direction", "", "Direction (in, out) (required)")
		_ = cmd.RegisterFlagCompletionFunc("direction", cmpl.SuggestCandidates("in", "out"))
		_ = cmd.MarkFlagRequired("direction")

		cmd.Flags().String("protocol", "", "Protocol (icmp, esp, gre, udp or tcp) (required)")
		_ = cmd.RegisterFlagCompletionFunc("protocol", cmpl.SuggestCandidates("icmp", "udp", "tcp", "esp", "gre"))
		_ = 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")

		cmd.Flags().String("description", "", "Description of the firewall rule")
		return cmd
	},
	Run: func(s state.State, cmd *cobra.Command, args []string) error {
		idOrName := args[0]
		firewall, _, err := s.Client().Firewall().Get(s, idOrName)
		if err != nil {
			return err
		}
		if firewall == nil {
			return fmt.Errorf("Firewall not found: %v", idOrName)
		}

		rule, err := parseRuleFromArgs(cmd.Flags())
		if err != nil {
			return err
		}

		rules := append(firewall.Rules, *rule)

		actions, _, err := s.Client().Firewall().SetRules(s, firewall,
			hcloud.FirewallSetRulesOpts{Rules: rules},
		)
		if err != nil {
			return err
		}
		if err := s.WaitForActions(s, cmd, actions...); err != nil {
			return err
		}

		cmd.Printf("Firewall Rules for Firewall %d updated\n", firewall.ID)

		return nil
	},
}
View Source
var ApplyToResourceCmd = base.Cmd{
	BaseCobraCommand: func(client hcapi2.Client) *cobra.Command {
		cmd := &cobra.Command{
			Use:                   "apply-to-resource (--type server --server <server> | --type label_selector --label-selector <label-selector>) <firewall>",
			Short:                 "Applies a Firewall to a single resource",
			ValidArgsFunction:     cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Firewall().Names)),
			TraverseChildren:      true,
			DisableFlagsInUseLine: true,
		}
		cmd.Flags().String("type", "", "Resource Type (server, label_selector) (required)")
		_ = cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidates("server", "label_selector"))
		_ = cmd.MarkFlagRequired("type")

		cmd.Flags().String("server", "", "Server name of ID (required when type is server)")
		_ = cmd.RegisterFlagCompletionFunc("server", cmpl.SuggestCandidatesF(client.Server().Names))

		cmd.Flags().StringP("label-selector", "l", "", "Label Selector")
		return cmd
	},
	Run: func(s state.State, cmd *cobra.Command, args []string) error {
		resourceType, _ := cmd.Flags().GetString("type")

		switch resourceType {
		case string(hcloud.FirewallResourceTypeServer):
			server, _ := cmd.Flags().GetString("server")
			if server == "" {
				return fmt.Errorf("type %s need a --server specific", resourceType)
			}
		case string(hcloud.FirewallResourceTypeLabelSelector):
			labelSelector, _ := cmd.Flags().GetString("label-selector")
			if labelSelector == "" {
				return fmt.Errorf("type %s need a --label-selector specific", resourceType)
			}
		default:
			return fmt.Errorf("unknown type %s", resourceType)
		}

		serverIDOrName, _ := cmd.Flags().GetString("server")
		labelSelector, _ := cmd.Flags().GetString("label-selector")
		idOrName := args[0]
		firewall, _, err := s.Client().Firewall().Get(s, idOrName)
		if err != nil {
			return err
		}
		if firewall == nil {
			return fmt.Errorf("Firewall not found: %v", idOrName)
		}
		opts := hcloud.FirewallResource{Type: hcloud.FirewallResourceType(resourceType)}

		switch opts.Type {
		case hcloud.FirewallResourceTypeServer:
			server, _, err := s.Client().Server().Get(s, serverIDOrName)
			if err != nil {
				return err
			}
			if server == nil {
				return fmt.Errorf("Server not found: %v", serverIDOrName)
			}
			opts.Server = &hcloud.FirewallResourceServer{ID: server.ID}
		case hcloud.FirewallResourceTypeLabelSelector:
			opts.LabelSelector = &hcloud.FirewallResourceLabelSelector{Selector: labelSelector}
		default:
			return fmt.Errorf("unknown type %s", opts.Type)
		}

		actions, _, err := s.Client().Firewall().ApplyResources(s, firewall, []hcloud.FirewallResource{opts})
		if err != nil {
			return err
		}
		if err := s.WaitForActions(s, cmd, actions...); err != nil {
			return err
		}
		cmd.Printf("Firewall %d applied to resource\n", firewall.ID)

		return nil
	},
}
View Source
var CreateCmd = base.CreateCmd{
	BaseCobraCommand: func(hcapi2.Client) *cobra.Command {
		cmd := &cobra.Command{
			Use:   "create [options] --name <name>",
			Short: "Create a Firewall",
		}
		cmd.Flags().String("name", "", "Name")
		_ = cmd.MarkFlagRequired("name")

		cmd.Flags().StringToString("label", nil, "User-defined labels ('key=value') (can be specified multiple times)")

		cmd.Flags().String("rules-file", "", "JSON file containing your routes (use - to read from stdin). The structure of the file needs to be the same as within the API: https://docs.hetzner.cloud/#firewalls-get-a-firewall ")
		return cmd
	},
	Run: func(s state.State, cmd *cobra.Command, _ []string) (any, any, error) {
		name, _ := cmd.Flags().GetString("name")
		labels, _ := cmd.Flags().GetStringToString("label")

		opts := hcloud.FirewallCreateOpts{
			Name:   name,
			Labels: labels,
		}

		rulesFile, _ := cmd.Flags().GetString("rules-file")
		if rulesFile != "" {
			rules, err := parseRulesFile(rulesFile)
			if err != nil {
				return nil, nil, err
			}
			opts.Rules = rules
		}

		result, _, err := s.Client().Firewall().Create(s, opts)
		if err != nil {
			return nil, nil, err
		}

		if err := s.WaitForActions(s, cmd, result.Actions...); err != nil {
			return nil, nil, err
		}

		cmd.Printf("Firewall %d created\n", result.Firewall.ID)

		return result.Firewall, util.Wrap("firewall", hcloud.SchemaFromFirewall(result.Firewall)), err
	},
}
View Source
var DeleteCmd = base.DeleteCmd{
	ResourceNameSingular: "firewall",
	ResourceNamePlural:   "firewalls",
	ShortDescription:     "Delete a firewall",
	NameSuggestions:      func(c hcapi2.Client) func() []string { return c.Firewall().Names },
	Fetch: func(s state.State, _ *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
		return s.Client().Firewall().Get(s, idOrName)
	},
	Delete: func(s state.State, _ *cobra.Command, resource interface{}) (*hcloud.Action, error) {
		firewall := resource.(*hcloud.Firewall)
		_, err := s.Client().Firewall().Delete(s, firewall)
		return nil, err
	},
}
View Source
var DeleteRuleCmd = base.Cmd{
	BaseCobraCommand: func(client hcapi2.Client) *cobra.Command {
		cmd := &cobra.Command{
			Use:                   "delete-rule [options] (--direction in --source-ips <ips> | --direction out --destination-ips <ips>) (--protocol <tcp|udp> --port <port> | --protocol <icmp|esp|gre>) <firewall>",
			Short:                 "Delete a single rule to a firewall",
			ValidArgsFunction:     cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Firewall().Names)),
			TraverseChildren:      true,
			DisableFlagsInUseLine: true,
		}
		cmd.Flags().String("direction", "", "Direction (in, out) (required)")
		_ = cmd.RegisterFlagCompletionFunc("direction", cmpl.SuggestCandidates("in", "out"))
		_ = cmd.MarkFlagRequired("direction")

		cmd.Flags().String("protocol", "", "Protocol (icmp, esp, gre, udp or tcp) (required)")
		_ = cmd.RegisterFlagCompletionFunc("protocol", cmpl.SuggestCandidates("icmp", "udp", "tcp", "esp", "gre"))
		_ = 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")

		cmd.Flags().String("description", "", "Description of the firewall rule")
		return cmd
	},
	Run: func(s state.State, cmd *cobra.Command, args []string) error {
		idOrName := args[0]
		firewall, _, err := s.Client().Firewall().Get(s, idOrName)
		if err != nil {
			return err
		}
		if firewall == nil {
			return fmt.Errorf("Firewall not found: %v", idOrName)
		}

		rule, err := parseRuleFromArgs(cmd.Flags())
		if err != nil {
			return err
		}

		var rules = make([]hcloud.FirewallRule, 0)
		for _, existingRule := range firewall.Rules {
			if !reflect.DeepEqual(existingRule, *rule) {
				rules = append(rules, existingRule)
			}
		}
		if len(rules) == len(firewall.Rules) {
			return fmt.Errorf("the specified rule was not found in the ruleset of Firewall %d", firewall.ID)
		}
		actions, _, err := s.Client().Firewall().SetRules(s, firewall,
			hcloud.FirewallSetRulesOpts{Rules: rules},
		)
		if err != nil {
			return err
		}
		if err := s.WaitForActions(s, cmd, actions...); err != nil {
			return err
		}
		cmd.Printf("Firewall Rules for Firewall %d updated\n", firewall.ID)

		return nil
	},
}
View Source
var DescribeCmd = base.DescribeCmd{
	ResourceNameSingular: "firewall",
	ShortDescription:     "Describe an firewall",
	JSONKeyGetByID:       "firewall",
	JSONKeyGetByName:     "firewalls",
	NameSuggestions:      func(c hcapi2.Client) func() []string { return c.Firewall().Names },
	Fetch: func(s state.State, _ *cobra.Command, idOrName string) (interface{}, interface{}, error) {
		fw, _, err := s.Client().Firewall().Get(s, idOrName)
		if err != nil {
			return nil, nil, err
		}
		return fw, hcloud.SchemaFromFirewall(fw), nil
	},
	PrintText: func(s state.State, cmd *cobra.Command, resource interface{}) error {
		firewall := resource.(*hcloud.Firewall)

		cmd.Printf("ID:\t\t%d\n", firewall.ID)
		cmd.Printf("Name:\t\t%s\n", firewall.Name)
		cmd.Printf("Created:\t%s (%s)\n", util.Datetime(firewall.Created), humanize.Time(firewall.Created))

		cmd.Print("Labels:\n")
		if len(firewall.Labels) == 0 {
			cmd.Print("  No labels\n")
		} else {
			for key, value := range firewall.Labels {
				cmd.Printf("  %s: %s\n", key, value)
			}
		}

		cmd.Print("Rules:\n")
		if len(firewall.Rules) == 0 {
			cmd.Print("  No rules\n")
		} else {
			for _, rule := range firewall.Rules {
				cmd.Printf("  - Direction:\t\t%s\n", rule.Direction)
				if rule.Description != nil {
					cmd.Printf("    Description:\t%s\n", *rule.Description)
				}
				cmd.Printf("    Protocol:\t\t%s\n", rule.Protocol)
				if rule.Port != nil {
					cmd.Printf("    Port:\t\t%s\n", *rule.Port)
				}

				var ips []net.IPNet
				switch rule.Direction {
				case hcloud.FirewallRuleDirectionIn:
					cmd.Print("    Source IPs:\n")
					ips = rule.SourceIPs
				case hcloud.FirewallRuleDirectionOut:
					cmd.Print("    Destination IPs:\n")
					ips = rule.DestinationIPs
				}

				for _, cidr := range ips {
					cmd.Printf("     \t\t\t%s\n", cidr.String())
				}
			}
		}
		cmd.Print("Applied To:\n")
		if len(firewall.AppliedTo) == 0 {
			cmd.Print("  Not applied\n")
		} else {
			for _, resource := range firewall.AppliedTo {
				cmd.Printf("  - Type:\t\t%s\n", resource.Type)
				switch resource.Type {
				case hcloud.FirewallResourceTypeServer:
					cmd.Printf("    Server ID:\t\t%d\n", resource.Server.ID)
					cmd.Printf("    Server Name:\t%s\n", s.Client().Server().ServerName(resource.Server.ID))
				case hcloud.FirewallResourceTypeLabelSelector:
					cmd.Printf("    Label Selector:\t%s\n", resource.LabelSelector.Selector)
				}
			}
		}
		return nil
	},
}
View Source
var LabelCmds = base.LabelCmds{
	ResourceNameSingular:   "firewall",
	ShortDescriptionAdd:    "Add a label to an firewall",
	ShortDescriptionRemove: "Remove a label from an firewall",
	NameSuggestions:        func(c hcapi2.Client) func() []string { return c.Firewall().Names },
	LabelKeySuggestions:    func(c hcapi2.Client) func(idOrName string) []string { return c.Firewall().LabelKeys },
	FetchLabels: func(s state.State, idOrName string) (map[string]string, int64, error) {
		firewall, _, err := s.Client().Firewall().Get(s, idOrName)
		if err != nil {
			return nil, 0, err
		}
		if firewall == nil {
			return nil, 0, fmt.Errorf("firewall not found: %s", idOrName)
		}
		return firewall.Labels, firewall.ID, nil
	},
	SetLabels: func(s state.State, id int64, labels map[string]string) error {
		opts := hcloud.FirewallUpdateOpts{
			Labels: labels,
		}
		_, _, err := s.Client().Firewall().Update(s, &hcloud.Firewall{ID: id}, opts)
		return err
	},
}
View Source
var ListCmd = base.ListCmd{
	ResourceNamePlural: "Firewalls",
	JSONKeyGetByName:   "firewalls",
	DefaultColumns:     []string{"id", "name", "rules_count", "applied_to_count"},
	SortOption:         config.OptionSortFirewall,

	Fetch: func(s state.State, _ *pflag.FlagSet, listOpts hcloud.ListOpts, sorts []string) ([]interface{}, error) {
		opts := hcloud.FirewallListOpts{ListOpts: listOpts}
		if len(sorts) > 0 {
			opts.Sort = sorts
		}
		firewalls, err := s.Client().Firewall().AllWithOpts(s, opts)

		var resources []interface{}
		for _, n := range firewalls {
			resources = append(resources, n)
		}
		return resources, err
	},

	OutputTable: func(hcapi2.Client) *output.Table {
		return output.NewTable().
			AddAllowedFields(hcloud.Firewall{}).
			AddFieldFn("rules_count", output.FieldFn(func(obj interface{}) string {
				firewall := obj.(*hcloud.Firewall)
				count := len(firewall.Rules)
				if count == 1 {
					return fmt.Sprintf("%d Rule", count)
				}
				return fmt.Sprintf("%d Rules", count)
			})).
			AddFieldFn("applied_to_count", output.FieldFn(func(obj interface{}) string {
				firewall := obj.(*hcloud.Firewall)
				servers := 0
				labelSelectors := 0
				for _, r := range firewall.AppliedTo {
					if r.Type == hcloud.FirewallResourceTypeLabelSelector {
						labelSelectors++
						continue
					}
					servers++
				}
				serversText := "Servers"
				if servers == 1 {
					serversText = "Server"
				}
				labelSelectorsText := "Label Selectors"
				if labelSelectors == 1 {
					labelSelectorsText = "Label Selector"
				}
				return fmt.Sprintf("%d %s | %d %s", servers, serversText, labelSelectors, labelSelectorsText)
			}))
	},

	Schema: func(resources []interface{}) interface{} {
		firewallSchemas := make([]schema.Firewall, 0, len(resources))
		for _, resource := range resources {
			fw := resource.(*hcloud.Firewall)
			firewallSchemas = append(firewallSchemas, hcloud.SchemaFromFirewall(fw))
		}
		return firewallSchemas
	},
}
View Source
var RemoveFromResourceCmd = base.Cmd{
	BaseCobraCommand: func(client hcapi2.Client) *cobra.Command {
		cmd := &cobra.Command{
			Use:                   "remove-from-resource (--type server --server <server> | --type label_selector --label-selector <label-selector>) <firewall>",
			Short:                 "Removes a Firewall from a single resource",
			ValidArgsFunction:     cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Firewall().Names)),
			TraverseChildren:      true,
			DisableFlagsInUseLine: true,
		}
		cmd.Flags().String("type", "", "Resource Type (server) (required)")
		_ = cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidates("server", "label_selector"))
		_ = cmd.MarkFlagRequired("type")

		cmd.Flags().String("server", "", "Server name of ID (required when type is server)")
		_ = cmd.RegisterFlagCompletionFunc("server", cmpl.SuggestCandidatesF(client.Server().Names))

		cmd.Flags().StringP("label-selector", "l", "", "Label Selector")
		return cmd
	},
	Run: func(s state.State, cmd *cobra.Command, args []string) error {
		resourceType, _ := cmd.Flags().GetString("type")

		switch resourceType {
		case string(hcloud.FirewallResourceTypeServer):
			server, _ := cmd.Flags().GetString("server")
			if server == "" {
				return fmt.Errorf("type %s need a --server specific", resourceType)
			}
		case string(hcloud.FirewallResourceTypeLabelSelector):
			labelSelector, _ := cmd.Flags().GetString("label-selector")
			if labelSelector == "" {
				return fmt.Errorf("type %s need a --label-selector specific", resourceType)
			}
		default:
			return fmt.Errorf("unknown type %s", resourceType)
		}
		serverIDOrName, _ := cmd.Flags().GetString("server")
		labelSelector, _ := cmd.Flags().GetString("label-selector")

		idOrName := args[0]
		firewall, _, err := s.Client().Firewall().Get(s, idOrName)
		if err != nil {
			return err
		}
		if firewall == nil {
			return fmt.Errorf("Firewall not found: %v", idOrName)
		}
		opts := hcloud.FirewallResource{Type: hcloud.FirewallResourceType(resourceType)}

		switch opts.Type {
		case hcloud.FirewallResourceTypeServer:
			server, _, err := s.Client().Server().Get(s, serverIDOrName)
			if err != nil {
				return err
			}
			if server == nil {
				return fmt.Errorf("Server not found: %v", serverIDOrName)
			}
			opts.Server = &hcloud.FirewallResourceServer{ID: server.ID}
		case hcloud.FirewallResourceTypeLabelSelector:
			opts.LabelSelector = &hcloud.FirewallResourceLabelSelector{Selector: labelSelector}
		default:
			return fmt.Errorf("unknown type %s", opts.Type)
		}
		actions, _, err := s.Client().Firewall().RemoveResources(s, firewall, []hcloud.FirewallResource{opts})
		if err != nil {
			return err
		}
		if err := s.WaitForActions(s, cmd, actions...); err != nil {
			return err
		}
		cmd.Printf("Firewall %d removed from resource\n", firewall.ID)

		return nil
	},
}
View Source
var ReplaceRulesCmd = base.Cmd{
	BaseCobraCommand: func(client hcapi2.Client) *cobra.Command {
		cmd := &cobra.Command{
			Use:                   "replace-rules --rules-file <file> <firewall>",
			Short:                 "Replaces all rules from a Firewall from a file",
			ValidArgsFunction:     cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Firewall().Names)),
			TraverseChildren:      true,
			DisableFlagsInUseLine: true,
		}
		cmd.Flags().String("rules-file", "", "JSON file containing your routes (use - to read from stdin). The structure of the file needs to be the same as within the API: https://docs.hetzner.cloud/#firewalls-get-a-firewall")
		_ = cmd.MarkFlagRequired("rules-file")
		return cmd
	},
	Run: func(s state.State, cmd *cobra.Command, args []string) error {
		idOrName := args[0]
		firewall, _, err := s.Client().Firewall().Get(s, idOrName)
		if err != nil {
			return err
		}
		if firewall == nil {
			return fmt.Errorf("Firewall not found: %v", idOrName)
		}

		opts := hcloud.FirewallSetRulesOpts{}
		rulesFile, _ := cmd.Flags().GetString("rules-file")
		if rulesFile != "" {
			rules, err := parseRulesFile(rulesFile)
			if err != nil {
				return err
			}
			opts.Rules = rules
		}

		actions, _, err := s.Client().Firewall().SetRules(s, firewall, opts)
		if err != nil {
			return err
		}
		if err := s.WaitForActions(s, cmd, actions...); err != nil {
			return err
		}
		cmd.Printf("Firewall Rules for Firewall %d updated\n", firewall.ID)

		return nil
	},
}
View Source
var UpdateCmd = base.UpdateCmd{
	ResourceNameSingular: "Firewall",
	ShortDescription:     "Update a firewall",
	NameSuggestions:      func(c hcapi2.Client) func() []string { return c.Firewall().Names },
	Fetch: func(s state.State, _ *cobra.Command, idOrName string) (interface{}, *hcloud.Response, error) {
		return s.Client().Firewall().Get(s, idOrName)
	},
	DefineFlags: func(cmd *cobra.Command) {
		cmd.Flags().String("name", "", "Firewall name")
	},
	Update: func(s state.State, _ *cobra.Command, resource interface{}, flags map[string]pflag.Value) error {
		firewall := resource.(*hcloud.Firewall)
		updOpts := hcloud.FirewallUpdateOpts{
			Name: flags["name"].String(),
		}
		_, _, err := s.Client().Firewall().Update(s, firewall, updOpts)
		if err != nil {
			return err
		}
		return nil
	},
}

Functions

func NewCommand

func NewCommand(s state.State) *cobra.Command

func ValidateFirewallIP added in v1.42.0

func ValidateFirewallIP(ip string) (*net.IPNet, error)

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL