~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/lxc/lxd/lxd/networks.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package main
 
2
 
 
3
import (
 
4
        "fmt"
 
5
        "net"
 
6
        "net/http"
 
7
        "strconv"
 
8
 
 
9
        "github.com/gorilla/mux"
 
10
 
 
11
        "github.com/lxc/lxd/shared"
 
12
)
 
13
 
 
14
func networksGet(d *Daemon, r *http.Request) Response {
 
15
        recursionStr := r.FormValue("recursion")
 
16
        recursion, err := strconv.Atoi(recursionStr)
 
17
        if err != nil {
 
18
                recursion = 0
 
19
        }
 
20
 
 
21
        ifs, err := net.Interfaces()
 
22
        if err != nil {
 
23
                return InternalError(err)
 
24
        }
 
25
 
 
26
        resultString := []string{}
 
27
        resultMap := []network{}
 
28
        for _, iface := range ifs {
 
29
                if recursion == 0 {
 
30
                        resultString = append(resultString, fmt.Sprintf("/%s/networks/%s", shared.APIVersion, iface.Name))
 
31
                } else {
 
32
                        net, err := doNetworkGet(d, iface.Name)
 
33
                        if err != nil {
 
34
                                continue
 
35
                        }
 
36
                        resultMap = append(resultMap, net)
 
37
 
 
38
                }
 
39
        }
 
40
 
 
41
        if recursion == 0 {
 
42
                return SyncResponse(true, resultString)
 
43
        }
 
44
 
 
45
        return SyncResponse(true, resultMap)
 
46
}
 
47
 
 
48
var networksCmd = Command{name: "networks", get: networksGet}
 
49
 
 
50
type network struct {
 
51
        Name   string   `json:"name"`
 
52
        Type   string   `json:"type"`
 
53
        UsedBy []string `json:"used_by"`
 
54
}
 
55
 
 
56
func isOnBridge(c container, bridge string) bool {
 
57
        for _, device := range c.ExpandedDevices() {
 
58
                if device["type"] != "nic" {
 
59
                        continue
 
60
                }
 
61
 
 
62
                if !shared.StringInSlice(device["nictype"], []string{"bridged", "macvlan"}) {
 
63
                        continue
 
64
                }
 
65
 
 
66
                if device["parent"] == "" {
 
67
                        continue
 
68
                }
 
69
 
 
70
                if device["parent"] == bridge {
 
71
                        return true
 
72
                }
 
73
        }
 
74
 
 
75
        return false
 
76
}
 
77
 
 
78
func networkGet(d *Daemon, r *http.Request) Response {
 
79
        name := mux.Vars(r)["name"]
 
80
 
 
81
        n, err := doNetworkGet(d, name)
 
82
        if err != nil {
 
83
                return InternalError(err)
 
84
        }
 
85
 
 
86
        return SyncResponse(true, &n)
 
87
}
 
88
 
 
89
func doNetworkGet(d *Daemon, name string) (network, error) {
 
90
        iface, err := net.InterfaceByName(name)
 
91
        if err != nil {
 
92
                return network{}, err
 
93
        }
 
94
 
 
95
        // Prepare the response
 
96
        n := network{}
 
97
        n.Name = iface.Name
 
98
        n.UsedBy = []string{}
 
99
 
 
100
        // Look for containers using the interface
 
101
        cts, err := dbContainersList(d.db, cTypeRegular)
 
102
        if err != nil {
 
103
                return network{}, err
 
104
        }
 
105
 
 
106
        for _, ct := range cts {
 
107
                c, err := containerLoadByName(d, ct)
 
108
                if err != nil {
 
109
                        return network{}, err
 
110
                }
 
111
 
 
112
                if isOnBridge(c, n.Name) {
 
113
                        n.UsedBy = append(n.UsedBy, fmt.Sprintf("/%s/containers/%s", shared.APIVersion, ct))
 
114
                }
 
115
        }
 
116
 
 
117
        // Set the device type as needed
 
118
        if shared.IsLoopback(iface) {
 
119
                n.Type = "loopback"
 
120
        } else if shared.PathExists(fmt.Sprintf("/sys/class/net/%s/bridge", n.Name)) {
 
121
                n.Type = "bridge"
 
122
        } else if shared.PathExists(fmt.Sprintf("/sys/class/net/%s/device", n.Name)) {
 
123
                n.Type = "physical"
 
124
        } else {
 
125
                n.Type = "unknown"
 
126
        }
 
127
 
 
128
        return n, nil
 
129
}
 
130
 
 
131
var networkCmd = Command{name: "networks/{name}", get: networkGet}