in ipam/azure.go [73:185]
func (s *azureSource) refresh() error {
// Refresh only if enough time has passed since the last query.
if time.Since(s.lastRefresh) < s.queryInterval {
return nil
}
s.lastRefresh = time.Now()
// Query the list of local interfaces.
interfaces, err := net.Interfaces()
if err != nil {
return err
}
// Configure the local default address space.
local, err := s.sink.newAddressSpace(LocalDefaultAddressSpaceId, LocalScope)
if err != nil {
return err
}
httpClient := common.InitHttpClient(httpConnectionTimeout, responseHeaderTimeout)
if httpClient == nil {
logger.Error("Failed intializing http client")
return fmt.Errorf("Error intializing http client")
}
logger.Info("Wireserver call to retrieve IP List", zap.String("queryUrl", s.queryUrl))
// Fetch configuration.
resp, err := httpClient.Get(s.queryUrl)
if err != nil {
logger.Error("wireserver call failed", zap.Error(err))
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
logger.Error("http return error code for wireserver call", zap.Any("response", resp))
return fmt.Errorf("wireserver http error %+v", resp)
}
// Decode XML document.
var doc common.XmlDocument
decoder := xml.NewDecoder(resp.Body)
err = decoder.Decode(&doc)
if err != nil {
return err
}
// For each interface...
for _, i := range doc.Interface {
ifName := ""
priority := 0
i.MacAddress = strings.ToLower(i.MacAddress)
// Find the interface with the matching MacAddress.
for _, iface := range interfaces {
macAddr := strings.Replace(iface.HardwareAddr.String(), ":", "", -1)
macAddr = strings.ToLower(macAddr)
if macAddr == i.MacAddress || i.MacAddress == "*" {
ifName = iface.Name
// Prioritize secondary interfaces.
if !i.IsPrimary {
priority = 1
}
break
}
}
// Skip if interface is not found.
if ifName == "" {
logger.Info("Failed to find interface with", zap.String("MAC Address", i.MacAddress))
continue
}
// For each subnet on the interface...
for _, s := range i.IPSubnet {
_, subnet, err := net.ParseCIDR(s.Prefix)
if err != nil {
logger.Error("Failed to parse subnet", zap.String("prefix", s.Prefix), zap.Error(err))
continue
}
ap, err := local.newAddressPool(ifName, priority, subnet)
if err != nil {
logger.Error("Failed to create pool", zap.Any("subnet", subnet), zap.String("ifName", ifName), zap.Error(err))
continue
}
addressCount := 0
// For each address in the subnet...
for _, a := range s.IPAddress {
// Primary addresses are reserved for the host.
if a.IsPrimary {
continue
}
address := net.ParseIP(a.Address)
_, err = ap.newAddressRecord(&address)
if err != nil {
logger.Error("Failed to create", zap.Any("address", address), zap.Error(err))
continue
}
addressCount++
}
logger.Info("got addresses from interface subnet", zap.Int("addressCount", addressCount), zap.String("ifName", ifName), zap.Any("subnet", subnet))
}
}
// Set the local address space as active.
return s.sink.setAddressSpace(local)
}