package main import ( "context" "fmt" "time" "github.com/spf13/cobra" "git.wntrmute.dev/mc/mc-proxy/client/mcproxy" ) func firewallCmd() *cobra.Command { cmd := &cobra.Command{ Use: "firewall", Short: "Manage firewall rules", Long: "Manage firewall rules for mc-proxy.", } cmd.AddCommand(firewallListCmd()) cmd.AddCommand(firewallAddCmd()) cmd.AddCommand(firewallRemoveCmd()) return cmd } func firewallListCmd() *cobra.Command { return &cobra.Command{ Use: "list", Short: "List all firewall rules", Long: "List all configured firewall rules.", RunE: func(cmd *cobra.Command, args []string) error { client := clientFromContext(cmd.Context()) ctx, cancel := context.WithTimeout(cmd.Context(), 5*time.Second) defer cancel() rules, err := client.GetFirewallRules(ctx) if err != nil { return fmt.Errorf("listing firewall rules: %w", err) } if len(rules) == 0 { fmt.Println("No firewall rules configured") return nil } // Find max type length for alignment maxTypeLen := 0 for _, r := range rules { if len(r.Type) > maxTypeLen { maxTypeLen = len(string(r.Type)) } } fmt.Println("Firewall rules:") for _, r := range rules { fmt.Printf(" %-*s %s\n", maxTypeLen, r.Type, r.Value) } return nil }, } } func firewallAddCmd() *cobra.Command { return &cobra.Command{ Use: "add TYPE VALUE", Short: "Add a firewall rule", Long: "Add a firewall rule. TYPE must be one of: ip, cidr, country.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { ruleType, err := parseRuleType(args[0]) if err != nil { return err } value := args[1] client := clientFromContext(cmd.Context()) ctx, cancel := context.WithTimeout(cmd.Context(), 5*time.Second) defer cancel() if err := client.AddFirewallRule(ctx, ruleType, value); err != nil { return fmt.Errorf("adding firewall rule: %w", err) } fmt.Printf("Added firewall rule: %s %s\n", ruleType, value) return nil }, } } func firewallRemoveCmd() *cobra.Command { return &cobra.Command{ Use: "remove TYPE VALUE", Short: "Remove a firewall rule", Long: "Remove a firewall rule. TYPE must be one of: ip, cidr, country.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { ruleType, err := parseRuleType(args[0]) if err != nil { return err } value := args[1] client := clientFromContext(cmd.Context()) ctx, cancel := context.WithTimeout(cmd.Context(), 5*time.Second) defer cancel() if err := client.RemoveFirewallRule(ctx, ruleType, value); err != nil { return fmt.Errorf("removing firewall rule: %w", err) } fmt.Printf("Removed firewall rule: %s %s\n", ruleType, value) return nil }, } } func parseRuleType(s string) (mcproxy.FirewallRuleType, error) { switch s { case "ip": return mcproxy.FirewallRuleIP, nil case "cidr": return mcproxy.FirewallRuleCIDR, nil case "country": return mcproxy.FirewallRuleCountry, nil default: return "", fmt.Errorf("invalid rule type %q: must be one of: ip, cidr, country", s) } }