github.com/rootless-containers/rootlesskit/v2@v2.3.4/cmd/rootlessctl/port.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"os"
     9  	"strconv"
    10  	"text/tabwriter"
    11  
    12  	"github.com/urfave/cli/v2"
    13  
    14  	"github.com/rootless-containers/rootlesskit/v2/pkg/port"
    15  	"github.com/rootless-containers/rootlesskit/v2/pkg/port/portutil"
    16  )
    17  
    18  var listPortsCommand = cli.Command{
    19  	Name:      "list-ports",
    20  	Usage:     "List ports",
    21  	ArgsUsage: "[flags]",
    22  	Flags: []cli.Flag{
    23  		&cli.BoolFlag{
    24  			Name:  "json",
    25  			Usage: "Prints as JSON",
    26  		},
    27  	},
    28  	Action: listPortsAction,
    29  }
    30  
    31  func listPortsAction(clicontext *cli.Context) error {
    32  	c, err := newClient(clicontext)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	pm := c.PortManager()
    37  	ctx := context.Background()
    38  	portStatuses, err := pm.ListPorts(ctx)
    39  	if err != nil {
    40  		return err
    41  	}
    42  	if clicontext.Bool("json") {
    43  		// Marshal per entry, for consistency with add-ports
    44  		// (and for potential streaming support)
    45  		for _, p := range portStatuses {
    46  			m, err := json.Marshal(p)
    47  			if err != nil {
    48  				return err
    49  			}
    50  			fmt.Println(string(m))
    51  		}
    52  		return nil
    53  	}
    54  	w := tabwriter.NewWriter(os.Stdout, 4, 8, 4, ' ', 0)
    55  	if _, err := fmt.Fprintln(w, "ID\tPROTO\tPARENTIP\tPARENTPORT\tCHILDIP\tCHILDPORT\t"); err != nil {
    56  		return err
    57  	}
    58  	for _, p := range portStatuses {
    59  		if _, err := fmt.Fprintf(w, "%d\t%s\t%s\t%d\t%s\t%d\t\n",
    60  			p.ID, p.Spec.Proto, p.Spec.ParentIP, p.Spec.ParentPort, p.Spec.ChildIP, p.Spec.ChildPort); err != nil {
    61  			return err
    62  		}
    63  	}
    64  	return w.Flush()
    65  }
    66  
    67  var addPortsCommand = cli.Command{
    68  	Name:        "add-ports",
    69  	Usage:       "Add ports",
    70  	ArgsUsage:   "[flags] PARENTIP:PARENTPORT:CHILDPORT/PROTO [PARENTIP:PARENTPORT:CHILDPORT/PROTO...]",
    71  	Description: "Add exposed ports. The port spec is similar to `docker run -p`. e.g. \"127.0.0.1:8080:80/tcp\".",
    72  	Flags: []cli.Flag{
    73  		&cli.BoolFlag{
    74  			Name:  "json",
    75  			Usage: "Prints as JSON",
    76  		},
    77  	},
    78  	Action: addPortsAction,
    79  }
    80  
    81  func addPortsAction(clicontext *cli.Context) error {
    82  	if clicontext.NArg() < 1 {
    83  		return errors.New("no port specified")
    84  	}
    85  	var portSpecs []port.Spec
    86  	for _, s := range clicontext.Args().Slice() {
    87  		sp, err := portutil.ParsePortSpec(s)
    88  		if err != nil {
    89  			return err
    90  		}
    91  		portSpecs = append(portSpecs, *sp)
    92  	}
    93  
    94  	c, err := newClient(clicontext)
    95  	if err != nil {
    96  		return err
    97  	}
    98  	pm := c.PortManager()
    99  	ctx := context.Background()
   100  	for _, sp := range portSpecs {
   101  		portStatus, err := pm.AddPort(ctx, sp)
   102  		if err != nil {
   103  			return err
   104  		}
   105  		if clicontext.Bool("json") {
   106  			m, err := json.Marshal(portStatus)
   107  			if err != nil {
   108  				return err
   109  			}
   110  			fmt.Println(string(m))
   111  		} else {
   112  			fmt.Printf("%d\n", portStatus.ID)
   113  		}
   114  	}
   115  	return nil
   116  }
   117  
   118  var removePortsCommand = cli.Command{
   119  	Name:      "remove-ports",
   120  	Usage:     "Remove ports",
   121  	ArgsUsage: "[flags] ID [ID...]",
   122  	Action:    removePortsAction,
   123  }
   124  
   125  func removePortsAction(clicontext *cli.Context) error {
   126  	if clicontext.NArg() < 1 {
   127  		return errors.New("no ID specified")
   128  	}
   129  	var ids []int
   130  	for _, s := range clicontext.Args().Slice() {
   131  		id, err := strconv.Atoi(s)
   132  		if err != nil {
   133  			return err
   134  		}
   135  		ids = append(ids, id)
   136  	}
   137  	c, err := newClient(clicontext)
   138  	if err != nil {
   139  		return err
   140  	}
   141  	pm := c.PortManager()
   142  	ctx := context.Background()
   143  	for _, id := range ids {
   144  		if err := pm.RemovePort(ctx, id); err != nil {
   145  			return err
   146  		}
   147  		fmt.Printf("%d\n", id)
   148  	}
   149  	return nil
   150  }