github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/network/create.go (about)

     1  package network
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net"
     7  	"strings"
     8  
     9  	"github.com/docker/swarmkit/api"
    10  	"github.com/docker/swarmkit/cmd/swarmctl/common"
    11  	"github.com/spf13/cobra"
    12  )
    13  
    14  var (
    15  	createCmd = &cobra.Command{
    16  		Use:   "create",
    17  		Short: "Create a network",
    18  		RunE: func(cmd *cobra.Command, args []string) error {
    19  			if len(args) != 0 {
    20  				return errors.New("create command takes no arguments")
    21  			}
    22  
    23  			flags := cmd.Flags()
    24  			if !flags.Changed("name") {
    25  				return errors.New("--name is required")
    26  			}
    27  
    28  			name, err := flags.GetString("name")
    29  			if err != nil {
    30  				return err
    31  			}
    32  
    33  			// Process driver configurations
    34  			var driver *api.Driver
    35  			if flags.Changed("driver") {
    36  				driver = new(api.Driver)
    37  
    38  				driverName, err := flags.GetString("driver")
    39  				if err != nil {
    40  					return err
    41  				}
    42  
    43  				driver.Name = driverName
    44  
    45  				opts, err := cmd.Flags().GetStringSlice("opts")
    46  				if err != nil {
    47  					return err
    48  				}
    49  
    50  				driver.Options = map[string]string{}
    51  				for _, opt := range opts {
    52  					optPair := strings.Split(opt, "=")
    53  					if len(optPair) != 2 {
    54  						return fmt.Errorf("Malformed opts: %s", opt)
    55  					}
    56  					driver.Options[optPair[0]] = optPair[1]
    57  				}
    58  			}
    59  
    60  			ipamOpts, err := processIPAMOptions(cmd)
    61  			if err != nil {
    62  				return err
    63  			}
    64  
    65  			spec := &api.NetworkSpec{
    66  				Annotations: api.Annotations{
    67  					Name: name,
    68  				},
    69  				DriverConfig: driver,
    70  				IPAM:         ipamOpts,
    71  			}
    72  
    73  			c, err := common.Dial(cmd)
    74  			if err != nil {
    75  				return err
    76  			}
    77  			r, err := c.CreateNetwork(common.Context(cmd), &api.CreateNetworkRequest{Spec: spec})
    78  			if err != nil {
    79  				return err
    80  			}
    81  			fmt.Println(r.Network.ID)
    82  			return nil
    83  		},
    84  	}
    85  )
    86  
    87  func processIPAMOptions(cmd *cobra.Command) (*api.IPAMOptions, error) {
    88  	flags := cmd.Flags()
    89  
    90  	var ipamOpts *api.IPAMOptions
    91  	if flags.Changed("ipam-driver") {
    92  		driver, err := cmd.Flags().GetString("ipam-driver")
    93  		if err != nil {
    94  			return nil, err
    95  		}
    96  
    97  		ipamOpts = &api.IPAMOptions{
    98  			Driver: &api.Driver{
    99  				Name: driver,
   100  			},
   101  		}
   102  	}
   103  
   104  	if !flags.Changed("subnet") {
   105  		return ipamOpts, nil
   106  	}
   107  
   108  	subnets, err := cmd.Flags().GetStringSlice("subnet")
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	gateways, err := cmd.Flags().GetStringSlice("gateway")
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	ranges, err := cmd.Flags().GetStringSlice("ip-range")
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	ipamConfigs := make([]*api.IPAMConfig, 0, len(subnets))
   124  	for _, s := range subnets {
   125  		_, ipNet, err := net.ParseCIDR(s)
   126  		if err != nil {
   127  			return nil, err
   128  		}
   129  
   130  		family := api.IPAMConfig_IPV6
   131  		if ipNet.IP.To4() != nil {
   132  			family = api.IPAMConfig_IPV4
   133  		}
   134  
   135  		var gateway string
   136  		for i, g := range gateways {
   137  			if ipNet.Contains(net.ParseIP(g)) {
   138  				gateways = append(gateways[:i], gateways[i+1:]...)
   139  				gateway = g
   140  				break
   141  			}
   142  		}
   143  
   144  		var iprange string
   145  		for i, r := range ranges {
   146  			_, rangeNet, err := net.ParseCIDR(r)
   147  			if err != nil {
   148  				return nil, err
   149  			}
   150  
   151  			if ipNet.Contains(rangeNet.IP) {
   152  				ranges = append(ranges[:i], ranges[i+1:]...)
   153  				iprange = r
   154  				break
   155  			}
   156  		}
   157  
   158  		ipamConfigs = append(ipamConfigs, &api.IPAMConfig{
   159  			Family:  family,
   160  			Subnet:  s,
   161  			Gateway: gateway,
   162  			Range:   iprange,
   163  		})
   164  	}
   165  
   166  	if ipamOpts == nil {
   167  		ipamOpts = &api.IPAMOptions{}
   168  	}
   169  
   170  	ipamOpts.Configs = ipamConfigs
   171  	return ipamOpts, nil
   172  }
   173  
   174  func init() {
   175  	createCmd.Flags().String("name", "", "Network name")
   176  	createCmd.Flags().String("driver", "", "Network driver")
   177  	createCmd.Flags().String("ipam-driver", "", "IPAM driver")
   178  	createCmd.Flags().StringSlice("subnet", []string{}, "Subnets in CIDR format that represents a network segments")
   179  	createCmd.Flags().StringSlice("gateway", []string{}, "Gateway IP addresses for network segments")
   180  	createCmd.Flags().StringSlice("ip-range", []string{}, "IP ranges to allocate from within the subnets")
   181  	createCmd.Flags().StringSlice("opts", []string{}, "Network driver options")
   182  }