func prepareOrGetContainerInterfaceInfo( api APICalls, machineID string, bridgeDevice string, allocateOrMaintain bool, startingNetworkInfo []network.InterfaceInfo, log loggo.Logger, ) ([]network.InterfaceInfo, error) { maintain := !allocateOrMaintain if maintain { log.Debugf("not running maintenance for machine %q", machineID) return nil, nil } log.Debugf("using multi-bridge networking for container %q", machineID) containerTag := names.NewMachineTag(machineID) preparedInfo, err := api.PrepareContainerInterfaceInfo(containerTag) if err != nil { return nil, errors.Trace(err) } log.Tracef("PrepareContainerInterfaceInfo returned %+v", preparedInfo) return preparedInfo, nil }
func logAllSeverities(logger loggo.Logger) { logger.Criticalf("something critical") logger.Errorf("an error") logger.Warningf("a warning message") logger.Infof("an info message") logger.Debugf("a debug message") logger.Tracef("a trace message") }
// tracingRespondDecorator returns an autorest.RespondDecorator that // logs responses at trace level. func tracingRespondDecorator(logger loggo.Logger) autorest.RespondDecorator { return func(r autorest.Responder) autorest.Responder { return autorest.ResponderFunc(func(resp *http.Response) error { dump, err := httputil.DumpResponse(resp, true) if err != nil { logger.Tracef("failed to dump response: %v", err) logger.Tracef("%+v", resp) } else { logger.Tracef("%s", dump) } return r.Respond(resp) }) } }
// tracingPrepareDecorator returns an autorest.PrepareDecorator that // logs requests at trace level. func tracingPrepareDecorator(logger loggo.Logger) autorest.PrepareDecorator { return func(p autorest.Preparer) autorest.Preparer { return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { dump, err := httputil.DumpRequest(r, true) if err != nil { logger.Tracef("failed to dump request: %v", err) logger.Tracef("%+v", r) } else { logger.Tracef("%s", dump) } return p.Prepare(r) }) } }
// Sends the specified request to URL and checks that the HTTP response status is as expected. // reqReader: a reader returning the data to send. // length: the number of bytes to send. // headers: HTTP headers to include with the request. // expectedStatus: a slice of allowed response status codes. func (c *Client) sendRequest(method, URL string, reqReader io.Reader, length int, headers http.Header, expectedStatus []int, logger *loggo.Logger) (rc io.ReadCloser, respHeader *http.Header, err error) { reqData := make([]byte, length) if reqReader != nil { nrRead, err := io.ReadFull(reqReader, reqData) if err != nil { err = errors.Newf(err, "failed reading the request data, read %v of %v bytes", nrRead, length) return rc, respHeader, err } } rawResp, err := c.sendRateLimitedRequest(method, URL, headers, reqData, logger) if err != nil { return } if logger != nil && logger.IsTraceEnabled() { logger.Tracef("Request: %s %s\n", method, URL) logger.Tracef("Request header: %s\n", headers) logger.Tracef("Request body: %s\n", reqData) logger.Tracef("Response: %s\n", rawResp.Status) logger.Tracef("Response header: %s\n", rawResp.Header) logger.Tracef("Response body: %s\n", rawResp.Body) logger.Tracef("Response error: %s\n", err) } foundStatus := false if len(expectedStatus) == 0 { expectedStatus = []int{http.StatusOK} } for _, status := range expectedStatus { if rawResp.StatusCode == status { foundStatus = true break } } if !foundStatus && len(expectedStatus) > 0 { err = handleError(URL, rawResp) rawResp.Body.Close() return } return rawResp.Body, &rawResp.Header, err }
func prepareOrGetContainerInterfaceInfo( api APICalls, machineID string, bridgeDevice string, allocateOrMaintain bool, enableNAT bool, startingNetworkInfo []network.InterfaceInfo, log loggo.Logger, providerType string, ) ([]network.InterfaceInfo, error) { maintain := !allocateOrMaintain if environs.AddressAllocationEnabled(providerType) { if maintain { log.Debugf("running maintenance for container %q", machineID) } else { log.Debugf("trying to allocate static IP for container %q", machineID) } allocatedInfo, err := configureContainerNetwork( machineID, bridgeDevice, api, startingNetworkInfo, allocateOrMaintain, enableNAT, ) if err != nil && !maintain { log.Infof("not allocating static IP for container %q: %v", machineID, err) } return allocatedInfo, err } if maintain { log.Debugf("address allocation disabled: Not running maintenance for machine %q", machineID) return nil, nil } log.Debugf("address allocation feature flag not enabled; using multi-bridge networking for container %q", machineID) // In case we're running on MAAS 1.8+ with devices support, we'll still // call PrepareContainerInterfaceInfo(), but we'll ignore a NotSupported // error if we get it (which means we're not using MAAS 1.8+). containerTag := names.NewMachineTag(machineID) preparedInfo, err := api.PrepareContainerInterfaceInfo(containerTag) if err != nil && errors.IsNotSupported(err) { log.Warningf("new container %q not registered as device: not running on MAAS 1.8+", machineID) return nil, nil } else if err != nil { return nil, errors.Trace(err) } log.Tracef("PrepareContainerInterfaceInfo returned %+v", preparedInfo) dnsServersFound := false for _, info := range preparedInfo { if len(info.DNSServers) > 0 { dnsServersFound = true break } } if !dnsServersFound { logger.Warningf("no DNS settings found, discovering the host settings") dnsServers, searchDomain, err := localDNSServers() if err != nil { return nil, errors.Trace(err) } // Since the result is sorted, the first entry is the primary NIC. preparedInfo[0].DNSServers = dnsServers preparedInfo[0].DNSSearchDomains = []string{searchDomain} logger.Debugf( "setting DNS servers %+v and domains %+v on container interface %q", preparedInfo[0].DNSServers, preparedInfo[0].DNSSearchDomains, preparedInfo[0].InterfaceName, ) } return preparedInfo, nil }
func prepareOrGetContainerInterfaceInfo( api APICalls, machineID string, bridgeDevice string, allocateOrMaintain bool, enableNAT bool, startingNetworkInfo []network.InterfaceInfo, log loggo.Logger, ) ([]network.InterfaceInfo, error) { maintain := !allocateOrMaintain if environs.AddressAllocationEnabled() { if maintain { log.Debugf("running maintenance for container %q", machineID) } else { log.Debugf("trying to allocate static IP for container %q", machineID) } allocatedInfo, err := configureContainerNetwork( machineID, bridgeDevice, api, startingNetworkInfo, allocateOrMaintain, enableNAT, ) if err != nil && !maintain { log.Infof("not allocating static IP for container %q: %v", machineID, err) } return allocatedInfo, err } if maintain { log.Debugf("address allocation disabled: Not running maintenance for machine %q", machineID) return nil, nil } log.Debugf("address allocation feature flag not enabled; using DHCP for container %q", machineID) // In case we're running on MAAS 1.8+ with devices support, we'll still // call PrepareContainerInterfaceInfo(), but we'll ignore a NotSupported // error if we get it (which means we're not using MAAS 1.8+). containerTag := names.NewMachineTag(machineID) preparedInfo, err := api.PrepareContainerInterfaceInfo(containerTag) if err != nil && errors.IsNotSupported(err) { log.Warningf("new container %q not registered as device: not running on MAAS 1.8+", machineID) return nil, nil } else if err != nil { return nil, errors.Trace(err) } dnsServers, searchDomain, dnsErr := localDNSServers() if dnsErr != nil { return nil, errors.Trace(dnsErr) } for i, _ := range preparedInfo { preparedInfo[i].DNSServers = dnsServers preparedInfo[i].DNSSearch = searchDomain } log.Tracef("PrepareContainerInterfaceInfo returned %#v", preparedInfo) // Most likely there will be only one item in the list, but check // all of them for forward compatibility. macAddresses := set.NewStrings() for _, prepInfo := range preparedInfo { macAddresses.Add(prepInfo.MACAddress) } log.Infof( "new container %q registered as a MAAS device with MAC address(es) %v", machineID, macAddresses.SortedValues(), ) return preparedInfo, nil }