func Follow() { followBootStrap() // bootstrap proxy config var c ctx.Context c, ConfigReset = ctx.WithCancel(RootContext) go func() { watcher, err := disc.NewWatcher(&disc.WatcherOptions{ Config: etcd.Config{Endpoints: disc.Endpoints()}, Key: ProxyConfigKey, }) if err != nil { log.WithFields(log.Fields{"err": err}).Warning("config") return } order := reloadWorker() defer close(order) for yay := true; yay; { v := watcheWorker(c, watcher) select { case <-c.Done(): yay = false case proxyTargets, ok := <-v: if ok && proxyTargets != nil { order <- proxyTargets } yay = ok } } }() }
func ClusterList(w http.ResponseWriter, r *http.Request) { if err := common("GET", r); err != nil { http.Error(w, err.Error(), 400) return } // We are sending json data w.Header().Add("Content-Type", "application/json") var RootPath = DefaultRootPath if root := r.Form.Get("root"); root != "" { RootPath = root } var ClusterSize = DefaultListClusterSize if projSizeStr := r.Form.Get("size"); projSizeStr != "" { projSize, err := strconv.ParseInt(projSizeStr, 10, 0) if err == nil { ClusterSize = int(projSize) } } var ClusterNodes = &Clusters{ Root: RootPath, Size: ClusterSize, Nodes: make([]string, 0, ClusterSize), } kAPI, _ := disc.NewKeysAPI(etcd.Config{ Endpoints: disc.Endpoints(), }) work, abort := ctx.WithTimeout(ctx.Background(), 3*time.Second) defer abort() resp, err := kAPI.Get(work, RootPath, &etcd.GetOptions{ Recursive: true, }) if err != nil { json.NewEncoder(w).Encode(ClusterNodes) return } // Go traverse the discovery tree for _, node := range resp.Node.Nodes { checkCluster(ClusterNodes, node) } ClusterNodes.Size = len(ClusterNodes.Nodes) json.NewEncoder(w).Encode(ClusterNodes) return }
func followBootStrap() { kAPI, err := disc.NewKeysAPI(etcd.Config{Endpoints: disc.Endpoints()}) if err != nil { log.WithFields(log.Fields{"err": err}).Warning("bootstrap") return } resp, err := kAPI.Get(RootContext, ProxyConfigKey, nil) if err != nil { log.WithFields(log.Fields{"err": err}).Warning("bootstrap") reload(make([]*Info, 0)) } else if resp.Node.Dir { log.WithFields(log.Fields{"key": resp.Node.Key}).Warning("not a valid node") reload(make([]*Info, 0)) } else { log.WithFields(log.Fields{"key": resp.Node.Key, "val": resp.Node.Value}).Debug("cfgkey") if pxycfg := get(resp.Node.Value); pxycfg != nil { reload(pxycfg) } else { reload(make([]*Info, 0)) } } }
func (i *Info) Listen() { var ( // proxy type handler handle ProxyFunc // proxy connection option opts *proxy.ConnOptions // tls configuration info tlscfg proxy.TLSConfig logger = log.WithFields(log.Fields{ "Name": i.Name, "Net": i.Net, "From": i.From, "Range": i.FromRange, "To": i.To, "Service": i.Service, "Role": i.ServerRole, }) ) // Setup TLS configuration switch { case i.ServerRole == "server": cfg, err := proxy.LoadCertificate(proxy.CertOptions{ CA: i.CA, TlsCert: i.Cert, TlsKey: i.Key, Server: true, }) if err != nil { logger.Error(err) return } tlscfg = proxy.TLSConfig{Server: cfg} break case i.ServerRole == "client": cfg, err := proxy.LoadCertificate(proxy.CertOptions{ CA: i.CA, TlsCert: i.Cert, TlsKey: i.Key, }) if err != nil { logger.Error(err) return } tlscfg = proxy.TLSConfig{Client: cfg} break case i.ServerRole == "": // not processing TLS break default: // fall through as if not processing TLS break } // Setup destination and listener information switch { case i.Service != "": discovery := &proxy.DiscOptions{ Service: i.Service, Endpoints: disc.Endpoints(), } opts = &proxy.ConnOptions{ Net: i.Net, Discovery: discovery, TLSConfig: tlscfg, } if len(i.FromRange) != 0 { handle = proxy.ClusterSrv opts.FromRange = i.FromRange } else { handle = proxy.Srv opts.From = i.From } break case len(i.To) != 0: opts = &proxy.ConnOptions{ Net: i.Net, To: i.To, TLSConfig: tlscfg, } if len(i.FromRange) != 0 { handle = proxy.ClusterTo opts.FromRange = i.FromRange } else { handle = proxy.To opts.From = i.From } break } // Attach context to proxy daemon order, abort := ctx.WithCancel(RootContext) // This proxy shall have its isolated abort feature i.Cancel = abort go func() { logger.Info("begin") err := handle(order, opts) logger.Warning(err) }() }