func newConsulClient(consulAgent string) (*consulapi.Client, error) { var ( client *consulapi.Client err error ) consulConfig := consulapi.DefaultConfig() consulAgentUrl, err := url.Parse(consulAgent) if err != nil { glog.Infof("Error parsing Consul url") return nil, err } if consulAgentUrl.Host != "" { consulConfig.Address = consulAgentUrl.Host } if consulAgentUrl.Scheme != "" { consulConfig.Scheme = consulAgentUrl.Scheme } client, err = consulapi.NewClient(consulConfig) if err != nil { glog.Infof("Error creating Consul client") return nil, err } for attempt := 1; attempt <= maxConnectAttempts; attempt++ { if _, err = client.Agent().Self(); err == nil { break } if attempt == maxConnectAttempts { break } glog.Infof("[Attempt: %d] Attempting access to Consul after 5 second sleep", attempt) time.Sleep(5 * time.Second) } if err != nil { return nil, fmt.Errorf("failed to connect to Consul agent: %v, error: %v", consulAgent, err) } glog.Infof("Consul agent found: %v", consulAgent) return client, nil }
// Replace will delete the contents of 'f', using instead the given map. // 'f' takes ownership of the map, you should not reference the map again // after calling this function. f's queue is reset, too; upon return, it // will contain the items in the map, in no particular order. func (f *DeltaFIFO) Replace(list []interface{}, resourceVersion string) error { f.lock.Lock() defer f.lock.Unlock() for _, item := range list { if err := f.queueActionLocked(Sync, item); err != nil { return fmt.Errorf("couldn't enqueue object: %v", err) } } if f.knownObjectKeys == nil { return nil } keySet := make(sets.String, len(list)) for _, item := range list { key, err := f.KeyOf(item) if err != nil { return KeyError{item, err} } keySet.Insert(key) } // Detect deletions not already in the queue. knownKeys := f.knownObjectKeys.ListKeys() for _, k := range knownKeys { if _, exists := keySet[k]; exists { continue } // This key isn't in the complete set we got, so it must have been deleted. if d, exists := f.items[k]; exists { // Don't issue a delete delta if we have one enqueued as the most // recent delta. if d.Newest().Type == Deleted { continue } } var deletedObj interface{} if keyGetter, ok := f.knownObjectKeys.(KeyGetter); ok { var exists bool var err error deletedObj, exists, err = keyGetter.GetByKey(k) if err != nil || !exists { deletedObj = nil if err != nil { glog.Errorf("Unexpected error %v during lookup of key %v, placing DeleteFinalStateUnknown marker without object", err, k) } else { glog.Infof("Key %v does not exist in known objects store, placing DeleteFinalStateUnknown marker without object", k) } } } if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil { return err } } return nil }
func (ks *kube2consul) createDNS(record string, service *kapi.Service, node *nodeInformation) error { if strings.Contains(record, ".") { glog.Infof("Service names containing '.' are not supported: %s\n", service.Name) return nil } // if ClusterIP is not set, do not create a DNS records if !kapi.IsServiceIPSet(service) { glog.Infof("Skipping dns record for headless service: %s\n", service.Name) return nil } for i := range service.Spec.Ports { newId := node.name + record + service.Spec.Ports[i].Name var asrName string if len(service.Spec.Ports[i].Name) > 0 { asrName = record + "-" + service.Spec.Ports[i].Name } else { asrName = record } asr := &consulapi.AgentServiceRegistration{ ID: newId, Name: asrName, Address: node.address, Port: service.Spec.Ports[i].NodePort, Tags: []string{"Kube"}, } if Contains(node.ids[record], newId) == false { glog.Infof("Setting DNS record: %v -> %v:%d\n", asr.Name, asr.Address, asr.Port) if err := ks.consulClient.Agent().ServiceRegister(asr); err != nil { return err } node.ids[record] = append(node.ids[record], newId) } } return nil }
// TODO: evaluate using pkg/client/clientcmd func newKubeClient() (*kclient.Client, error) { var config *kclient.Config masterUrl, err := getKubeMasterUrl() if err != nil { return nil, err } if *argKubecfgFile == "" { config = &kclient.Config{ Host: masterUrl, Version: "v1", } } else { var err error overrides := &kclientcmd.ConfigOverrides{} overrides.ClusterInfo.Server = masterUrl // might be "", but that is OK rules := &kclientcmd.ClientConfigLoadingRules{ExplicitPath: *argKubecfgFile} // might be "", but that is OK if config, err = kclientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides).ClientConfig(); err != nil { return nil, err } } glog.Infof("Using %s for kubernetes master", config.Host) glog.Infof("Using kubernetes API %s", config.Version) return kclient.New(config) }
func (rt *DebuggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { reqInfo := NewRequestInfo(req) if rt.Levels.Has(JustURL) { glog.Infof("%s %s", reqInfo.RequestVerb, reqInfo.RequestURL) } if rt.Levels.Has(CurlCommand) { glog.Infof("%s", reqInfo.ToCurl()) } if rt.Levels.Has(RequestHeaders) { glog.Infof("Request Headers:") for key, values := range reqInfo.RequestHeaders { for _, value := range values { glog.Infof(" %s: %s", key, value) } } } startTime := time.Now() response, err := rt.delegatedRoundTripper.RoundTrip(req) reqInfo.Duration = time.Since(startTime) reqInfo.Complete(response, err) if rt.Levels.Has(URLTiming) { glog.Infof("%s %s %s in %d milliseconds", reqInfo.RequestVerb, reqInfo.RequestURL, reqInfo.ResponseStatus, reqInfo.Duration.Nanoseconds()/int64(time.Millisecond)) } if rt.Levels.Has(ResponseStatus) { glog.Infof("Response Status: %s in %d milliseconds", reqInfo.ResponseStatus, reqInfo.Duration.Nanoseconds()/int64(time.Millisecond)) } if rt.Levels.Has(ResponseHeaders) { glog.Infof("Response Headers:") for key, values := range reqInfo.ResponseHeaders { for _, value := range values { glog.Infof(" %s: %s", key, value) } } } return response, err }
// getListener creates a listener on the interface targeted by the given hostname on the given port with // the given protocol. protocol is in net.Listen style which basically admits values like tcp, tcp4, tcp6 func (pf *PortForwarder) getListener(protocol string, hostname string, port *ForwardedPort) (net.Listener, error) { listener, err := net.Listen(protocol, fmt.Sprintf("%s:%d", hostname, port.Local)) if err != nil { util.HandleError(fmt.Errorf("Unable to create listener: Error %s", err)) return nil, err } listenerAddress := listener.Addr().String() host, localPort, _ := net.SplitHostPort(listenerAddress) localPortUInt, err := strconv.ParseUint(localPort, 10, 16) if err != nil { return nil, fmt.Errorf("Error parsing local port: %s from %s (%s)", err, listenerAddress, host) } port.Local = uint16(localPortUInt) glog.Infof("Forwarding from %s:%d -> %d", hostname, localPortUInt, port.Remote) return listener, nil }
// handleConnection copies data between the local connection and the stream to // the remote server. func (pf *PortForwarder) handleConnection(conn net.Conn, port ForwardedPort) { defer conn.Close() glog.Infof("Handling connection for %d", port.Local) requestID := pf.nextRequestID() // create error stream headers := http.Header{} headers.Set(api.StreamType, api.StreamTypeError) headers.Set(api.PortHeader, fmt.Sprintf("%d", port.Remote)) headers.Set(api.PortForwardRequestIDHeader, strconv.Itoa(requestID)) errorStream, err := pf.streamConn.CreateStream(headers) if err != nil { util.HandleError(fmt.Errorf("error creating error stream for port %d -> %d: %v", port.Local, port.Remote, err)) return } // we're not writing to this stream errorStream.Close() errorChan := make(chan error) go func() { message, err := ioutil.ReadAll(errorStream) switch { case err != nil: errorChan <- fmt.Errorf("error reading from error stream for port %d -> %d: %v", port.Local, port.Remote, err) case len(message) > 0: errorChan <- fmt.Errorf("an error occurred forwarding %d -> %d: %v", port.Local, port.Remote, string(message)) } close(errorChan) }() // create data stream headers.Set(api.StreamType, api.StreamTypeData) dataStream, err := pf.streamConn.CreateStream(headers) if err != nil { util.HandleError(fmt.Errorf("error creating forwarding stream for port %d -> %d: %v", port.Local, port.Remote, err)) return } localError := make(chan struct{}) remoteDone := make(chan struct{}) go func() { // Copy from the remote side to the local port. if _, err := io.Copy(conn, dataStream); err != nil && !strings.Contains(err.Error(), "use of closed network connection") { util.HandleError(fmt.Errorf("error copying from remote stream to local connection: %v", err)) } // inform the select below that the remote copy is done close(remoteDone) }() go func() { // inform server we're not sending any more data after copy unblocks defer dataStream.Close() // Copy from the local port to the remote side. if _, err := io.Copy(dataStream, conn); err != nil && !strings.Contains(err.Error(), "use of closed network connection") { util.HandleError(fmt.Errorf("error copying from local connection to remote stream: %v", err)) // break out of the select below without waiting for the other copy to finish close(localError) } }() // wait for either a local->remote error or for copying from remote->local to finish select { case <-remoteDone: case <-localError: } // always expect something on errorChan (it may be nil) err = <-errorChan if err != nil { util.HandleError(err) } }
func (ks *kube2consul) removeDNS(recordID string) error { glog.Infof("Removing %s from DNS", recordID) ks.consulClient.Agent().ServiceDeregister(recordID) return nil }