github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/ports.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package jujuc
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/cmd/v3"
    11  	"github.com/juju/errors"
    12  	"github.com/juju/gnuflag"
    13  
    14  	jujucmd "github.com/juju/juju/cmd"
    15  	"github.com/juju/juju/core/network"
    16  )
    17  
    18  const (
    19  	portFormat = "<port>[/<protocol>] or <from>-<to>[/<protocol>] or icmp"
    20  )
    21  
    22  // portCommand implements the open-port and close-port commands.
    23  type portCommand struct {
    24  	cmd.CommandBase
    25  	info       *cmd.Info
    26  	action     func(*portCommand) error
    27  	portRange  network.PortRange
    28  	endpoints  string
    29  	formatFlag string // deprecated
    30  
    31  }
    32  
    33  func (c *portCommand) Info() *cmd.Info {
    34  	return jujucmd.Info(c.info)
    35  }
    36  
    37  func (c *portCommand) SetFlags(f *gnuflag.FlagSet) {
    38  	f.StringVar(&c.formatFlag, "format", "", "deprecated format flag")
    39  	f.StringVar(&c.endpoints, "endpoints", "", "a comma-delimited list of application endpoints to target with this operation")
    40  }
    41  
    42  func (c *portCommand) Init(args []string) error {
    43  	if args == nil {
    44  		return errors.Errorf("no port or range specified")
    45  	}
    46  
    47  	portRange, err := network.ParsePortRange(strings.ToLower(args[0]))
    48  	if err != nil {
    49  		return errors.Trace(err)
    50  	}
    51  	c.portRange = portRange
    52  
    53  	return cmd.CheckEmpty(args[1:])
    54  }
    55  
    56  func (c *portCommand) Run(ctx *cmd.Context) error {
    57  	if c.formatFlag != "" {
    58  		fmt.Fprintf(ctx.Stderr, "--format flag deprecated for command %q", c.Info().Name)
    59  	}
    60  	return c.action(c)
    61  }
    62  
    63  var openPortInfo = &cmd.Info{
    64  	Name:    "open-port",
    65  	Args:    portFormat,
    66  	Purpose: "register a request to open a port or port range",
    67  	Doc: `
    68  open-port registers a request to open the specified port or port range.
    69  
    70  By default, the specified port or port range will be opened for all defined
    71  application endpoints. The --endpoints option can be used to constrain the
    72  open request to a comma-delimited list of application endpoints.
    73  `,
    74  }
    75  
    76  func NewOpenPortCommand(ctx Context) (cmd.Command, error) {
    77  	return &portCommand{
    78  		info:   openPortInfo,
    79  		action: makePortRangeCommand(ctx.OpenPortRange),
    80  	}, nil
    81  }
    82  
    83  var closePortInfo = &cmd.Info{
    84  	Name:    "close-port",
    85  	Args:    portFormat,
    86  	Purpose: "register a request to close a port or port range",
    87  	Doc: `
    88  close-port registers a request to close the specified port or port range.
    89  
    90  By default, the specified port or port range will be closed for all defined
    91  application endpoints. The --endpoints option can be used to constrain the
    92  close request to a comma-delimited list of application endpoints.
    93  `,
    94  }
    95  
    96  func NewClosePortCommand(ctx Context) (cmd.Command, error) {
    97  	return &portCommand{
    98  		info:   closePortInfo,
    99  		action: makePortRangeCommand(ctx.ClosePortRange),
   100  	}, nil
   101  }
   102  
   103  func makePortRangeCommand(op func(string, network.PortRange) error) func(*portCommand) error {
   104  	return func(c *portCommand) error {
   105  		// Operation applies to all endpoints
   106  		if c.endpoints == "" {
   107  			return op("", c.portRange)
   108  		}
   109  
   110  		for _, endpoint := range strings.Split(c.endpoints, ",") {
   111  			endpoint = strings.TrimSpace(endpoint)
   112  			if err := op(endpoint, c.portRange); err != nil {
   113  				return errors.Trace(err)
   114  			}
   115  		}
   116  
   117  		return nil
   118  	}
   119  }