github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/tools/lxdclient/client_network.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // +build go1.3
     5  
     6  package lxdclient
     7  
     8  import (
     9  	"fmt"
    10  
    11  	"github.com/juju/errors"
    12  	"github.com/lxc/lxd"
    13  	"github.com/lxc/lxd/shared"
    14  
    15  	"github.com/juju/juju/network"
    16  )
    17  
    18  type rawNetworkClient interface {
    19  	NetworkCreate(name string, config map[string]string) error
    20  	NetworkGet(name string) (shared.NetworkConfig, error)
    21  }
    22  
    23  type networkClient struct {
    24  	raw       rawNetworkClient
    25  	supported bool
    26  }
    27  
    28  // NetworkCreate creates the specified network.
    29  func (c *networkClient) NetworkCreate(name string, config map[string]string) error {
    30  	if !c.supported {
    31  		return errors.NotSupportedf("network API not supported on this remote")
    32  	}
    33  
    34  	return c.raw.NetworkCreate(name, config)
    35  }
    36  
    37  // NetworkGet returns the specified network's configuration.
    38  func (c *networkClient) NetworkGet(name string) (shared.NetworkConfig, error) {
    39  	if !c.supported {
    40  		return shared.NetworkConfig{}, errors.NotSupportedf("network API not supported on this remote")
    41  	}
    42  
    43  	return c.raw.NetworkGet(name)
    44  }
    45  
    46  type creator interface {
    47  	rawNetworkClient
    48  	ProfileDeviceAdd(profile, devname, devtype string, props []string) (*lxd.Response, error)
    49  	ProfileConfig(profile string) (*shared.ProfileConfig, error)
    50  }
    51  
    52  func checkBridgeConfig(client rawNetworkClient, bridge string) error {
    53  	n, err := client.NetworkGet(bridge)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	if n.Config["ipv6.address"] != "none" {
    59  		return errors.Errorf(`juju doesn't support ipv6. Please disable LXD's IPV6:
    60  
    61  	$ lxc network set %s ipv6.address none
    62  
    63  and rebootstrap`, bridge)
    64  	}
    65  
    66  	return nil
    67  }
    68  
    69  // CreateDefaultBridgeInDefaultProfile creates a default bridge if it doesn't
    70  // exist and (if necessary) inserts it into the default profile.
    71  func CreateDefaultBridgeInDefaultProfile(client creator) error {
    72  	/* create the default bridge if it doesn't exist */
    73  	n, err := client.NetworkGet(network.DefaultLXDBridge)
    74  	if err != nil {
    75  		err := client.NetworkCreate(network.DefaultLXDBridge, map[string]string{
    76  			"ipv6.address": "none",
    77  			"ipv6.nat":     "false",
    78  		})
    79  		if err != nil {
    80  			return err
    81  		}
    82  
    83  		n, err = client.NetworkGet(network.DefaultLXDBridge)
    84  		if err != nil {
    85  			return err
    86  		}
    87  	} else {
    88  		if err := checkBridgeConfig(client, network.DefaultLXDBridge); err != nil {
    89  			return err
    90  		}
    91  	}
    92  
    93  	nicType := "macvlan"
    94  	if n.Type == "bridge" {
    95  		nicType = "bridged"
    96  	}
    97  
    98  	props := []string{fmt.Sprintf("nictype=%s", nicType), fmt.Sprintf("parent=%s", network.DefaultLXDBridge)}
    99  
   100  	config, err := client.ProfileConfig("default")
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	_, ok := config.Devices["eth0"]
   106  	if ok {
   107  		/* don't configure an eth0 if it already exists */
   108  		return nil
   109  	}
   110  
   111  	_, err = client.ProfileDeviceAdd("default", "eth0", "nic", props)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	return nil
   117  }