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 }