func ListenAndServe() error { svrConfig := InitSSHConfig() listener, err := net.Listen("tcp", g.Config.Bind) if err != nil { logs.Assert(err, "net.Listen failed") } defer listener.Close() for { conn, err := listener.Accept() if err != nil { logs.Assert(err, "listen.Accept failed") } sshConn := &SSHConn{conn, svrConfig} go func() { if err := sshConn.serve(); err != nil { logs.Info("Error occured while serving", err) return } logs.Info("Connection closed.") }() } }
func load() { containers, err := g.Docker.ListContainers(docker.ListContainersOptions{All: true}) if err != nil { logs.Assert(err, "List containers") } conn := g.GetRedisConn() defer g.ReleaseRedisConn(conn) containersKey := fmt.Sprintf("eru:agent:%s:containers:meta", g.Config.HostName) logs.Debug("Status get targets from", containersKey) rep, err := gore.NewCommand("HGETALL", containersKey).Run(conn) if err != nil { logs.Assert(err, "Status get targets") } if rep.IsNil() { return } targets, err := rep.Map() if err != nil { logs.Assert(err, "Status load targets") } logs.Debug("Status targets:", targets) logs.Info("Status load container") for _, container := range containers { if _, ok := targets[container.ID]; !ok { continue } status := getStatus(container.Status) if status != common.STATUS_START { reportContainerDeath(container.ID) continue } var meta map[string]interface{} if err := json.Unmarshal([]byte(targets[container.ID]), &meta); err != nil { logs.Info("Status load failed", err) continue } c, err := g.Docker.InspectContainer(container.ID) if err != nil { logs.Info("Status inspect docker failed", err) continue } if eruApp := app.NewEruApp(c, meta); eruApp != nil { lenz.Attacher.Attach(&eruApp.Meta) app.Add(eruApp) reportContainerCure(container.ID) } } }
func GetRedisConn() *gore.Conn { conn, err := Rds.Acquire() if err != nil || conn == nil { logs.Assert(err, "Get redis conn") } return conn }
func HTTPServe() { restfulAPIServer := pat.New() handlers := map[string]map[string]func(*Request) (int, interface{}){ "GET": { "/profile/": profile, "/version/": version, "/api/app/list/": listEruApps, }, "POST": { "/api/container/add/": addNewContainer, "/api/container/:container_id/addvlan/": addVlanForContainer, "/api/container/:container_id/addcalico/": addCalicoForContainer, "/api/container/:container_id/setroute/": setRouteForContainer, "/api/container/:container_id/addroute/": addRouteForContainer, "/api/eip/bind/": bindEIP, "/api/eip/release/": releaseEIP, "/api/container/publish/": publishContainer, "/api/container/unpublish/": unpublishContainer, }, } for method, routes := range handlers { for route, handler := range routes { restfulAPIServer.Add(method, route, http.HandlerFunc(JSONWrapper(handler))) } } http.Handle("/", restfulAPIServer) logs.Info("API http server start at", g.Config.API.Addr) err := http.ListenAndServe(g.Config.API.Addr, nil) if err != nil { logs.Assert(err, "ListenAndServe: ") } }
func load(configPath string) { if _, err := os.Stat(configPath); err != nil { logs.Assert(err, "config file invaild") } b, err := ioutil.ReadFile(configPath) if err != nil { logs.Assert(err, "Read config file failed") } if err := yaml.Unmarshal(b, &Config); err != nil { logs.Assert(err, "Load config file failed") } logs.Debug("Configure:", Config) }
func ping() { ticker := time.Tick(time.Duration(g.Config.Docker.Health) * time.Second) for _ = range ticker { if err := g.Docker.Ping(); err != nil { url := fmt.Sprintf("%s/api/host/%s/down/", g.Config.Eru.Endpoint, g.Config.HostName) utils.DoPut(url) logs.Assert(err, "Docker exit") } } }
func InitialConn() { var err error Rds = &gore.Pool{ InitialConn: Config.Redis.Min, MaximumConn: Config.Redis.Max, } redisHost := fmt.Sprintf("%s:%d", Config.Redis.Host, Config.Redis.Port) if err := Rds.Dial(redisHost); err != nil { logs.Assert(err, "Redis init failed") } if Docker, err = defines.NewDocker( Config.Docker.Endpoint, Config.Docker.Cert, Config.Docker.Key, Config.Docker.Ca, ); err != nil { logs.Assert(err, "Docker") } logs.Info("Global connections initiated") }
func InitialConn() { Rds = &gore.Pool{ InitialConn: Config.Redis.Min, MaximumConn: Config.Redis.Max, } redisHost := fmt.Sprintf("%s:%d", Config.Redis.Host, Config.Redis.Port) if err := Rds.Dial(redisHost); err != nil { logs.Assert(err, "Redis init failed") } logs.Info("Global connections initiated") }
func InitLenz() { Attacher = NewAttachManager() Router = NewRouteManager(Attacher) Routefs = RouteFileStore(g.Config.Lenz.Routes) if len(g.Config.Lenz.Forwards) > 0 { logs.Debug("Lenz Routing all to", g.Config.Lenz.Forwards) target := defines.Target{Addrs: g.Config.Lenz.Forwards} route := defines.Route{ID: common.LENZ_DEFAULT, Target: &target} route.LoadBackends() Router.Add(&route) } if _, err := os.Stat(g.Config.Lenz.Routes); err == nil { logs.Debug("Loading and persisting routes in", g.Config.Lenz.Routes) logs.Assert(Router.Load(Routefs), "persistor") } logs.Info("Lenz initiated") }
func InitStatus() { logs.Assert(g.Docker.AddEventListener(events), "Attacher") logs.Info("Status initiated") }
func WritePid(path string) { if err := ioutil.WriteFile(path, []byte(strconv.Itoa(os.Getpid())), 0755); err != nil { logs.Assert(err, "Save pid file failed") } }
func InitSSHConfig() *ssh.ServerConfig { privKey, err := utils.LoadKey(g.Config.PrivKey) if err != nil { logs.Assert(err, "Failed to load priv key") } config := &ssh.ServerConfig{ AuthLogCallback: func(conn ssh.ConnMetadata, method string, err error) { logs.Debug("Method type", method, "Error", err) }, PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { username := conn.User() clientAddr := conn.RemoteAddr() keyHex := utils.GetFingerPrint(key.Marshal()) user, remote := utils.GetRealUserRemote(username) if user == "" || remote == "" { return nil, errors.New("Wrong info") } logs.Info("Login attempt", conn.RemoteAddr(), username, user, remote, keyHex) if !utils.CheckKey(user, keyHex) { return nil, errors.New("Wrong key") } meta := defines.Meta{ Username: username, Pubkey: key, } clientConfig := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.PublicKeys(privKey), }, } client, err := ssh.Dial("tcp", remote, clientConfig) if err != nil { return nil, err } logs.Info("Login success", remote) meta.Remote = remote meta.Client = client Lock.Lock() defer Lock.Unlock() MetaData[clientAddr] = meta return nil, nil }, PasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) { username := conn.User() clientAddr := conn.RemoteAddr() user, remote := utils.GetRealUserRemote(username) if user == "" || remote == "" { return nil, errors.New("Wrong info") } logs.Info("Login attempt", conn.RemoteAddr(), username, string(password)) meta := defines.Meta{ Username: username, Password: string(password), } clientConfig := &ssh.ClientConfig{ User: "******", Auth: []ssh.AuthMethod{ ssh.Password(string(password)), }, } client, err := ssh.Dial("tcp", remote, clientConfig) if err != nil { return nil, err } logs.Info("Login success", remote) meta.Remote = remote meta.Client = client Lock.Lock() defer Lock.Unlock() MetaData[clientAddr] = meta return nil, nil }, } hostKey, err := utils.LoadKey(g.Config.HostKey) if err != nil { logs.Assert(err, "Failed to load host key") } config.AddHostKey(hostKey) return config }