func (a *Agent) Start() { var err error go a.WSServer.ListenAndServe() addr, port, err := config.GetAnalyzerClientAddr() if err != nil { logging.GetLogger().Errorf("Unable to parse analyzer client %s", err.Error()) os.Exit(1) } if addr != "" { authOptions := &shttp.AuthenticationOpts{ Username: config.GetConfig().GetString("agent.analyzer_username"), Password: config.GetConfig().GetString("agent.analyzer_password"), } authClient := waitAnalyzer(addr, port, authOptions) a.WSClient, err = shttp.NewWSAsyncClientFromConfig("skydive-agent", addr, port, "/ws", authClient) if err != nil { logging.GetLogger().Errorf("Unable to instantiate analyzer client %s", err.Error()) os.Exit(1) } graph.NewForwarder(a.WSClient, a.Graph, a.Root) a.WSClient.Connect() // send a first reset event to the analyzers a.Graph.DelSubGraph(a.Root) } a.TopologyProbeBundle = tprobes.NewTopologyProbeBundleFromConfig(a.Graph, a.Root) a.TopologyProbeBundle.Start() go a.HTTPServer.ListenAndServe() if addr != "" { a.EtcdClient, err = etcd.NewEtcdClientFromConfig() if err != nil { logging.GetLogger().Errorf("Unable to start etcd client %s", err.Error()) os.Exit(1) } captureApiHandler := &api.CaptureApiHandler{ BasicApiHandler: api.BasicApiHandler{ ResourceHandler: &api.CaptureResourceHandler{}, EtcdKeyAPI: a.EtcdClient.KeysApi, }, Graph: a.Graph, } for { flowtableUpdate, err := a.EtcdClient.GetInt64("/agent/config/flowtable_update") if err != nil { time.Sleep(time.Second) continue } flowtableExpire, err := a.EtcdClient.GetInt64("/agent/config/flowtable_expire") if err != nil { time.Sleep(time.Second) continue } updateTime := time.Duration(flowtableUpdate) * time.Second expireTime := time.Duration(flowtableExpire) * time.Second a.FlowTableAllocator = flow.NewTableAllocator(updateTime, expireTime) // expose a flow server through the client connection flow.NewServer(a.FlowTableAllocator, a.WSClient) a.FlowProbeBundle = fprobes.NewFlowProbeBundleFromConfig(a.TopologyProbeBundle, a.Graph, a.FlowTableAllocator) a.FlowProbeBundle.Start() l, err := fprobes.NewOnDemandProbeListener(a.FlowProbeBundle, a.Graph, captureApiHandler) if err != nil { logging.GetLogger().Errorf("Unable to start on-demand flow probe %s", err.Error()) os.Exit(1) } a.OnDemandProbeListener = l a.OnDemandProbeListener.Start() break } } }
func (a *Agent) Start() { var err error go a.WSServer.ListenAndServe() addr, port, err := config.GetAnalyzerClientAddr() if err != nil { logging.GetLogger().Errorf("Unable to parse analyzer client %s", err.Error()) os.Exit(1) } if addr != "" { authOptions := &shttp.AuthenticationOpts{ Username: config.GetConfig().GetString("agent.analyzer_username"), Password: config.GetConfig().GetString("agent.analyzer_password"), } authClient := waitAnalyzer(addr, port, authOptions) a.WSClient, err = shttp.NewWSAsyncClientFromConfig("skydive-agent", addr, port, "/ws", authClient) if err != nil { logging.GetLogger().Errorf("Unable to instantiate analyzer client %s", err.Error()) os.Exit(1) } graph.NewForwarder(a.WSClient, a.Graph, config.GetConfig().GetString("host_id")) a.WSClient.Connect() } a.TopologyProbeBundle, err = NewTopologyProbeBundleFromConfig(a.Graph, a.Root, a.WSClient) if err != nil { logging.GetLogger().Errorf("Unable to instantiate topology probes: %s", err.Error()) os.Exit(1) } a.TopologyProbeBundle.Start() go a.HTTPServer.ListenAndServe() if addr != "" { a.EtcdClient, err = etcd.NewEtcdClientFromConfig() if err != nil { logging.GetLogger().Errorf("Unable to start etcd client %s", err.Error()) os.Exit(1) } for { flowtableUpdate, err := a.EtcdClient.GetInt64("/agent/config/flowtable_update") if err != nil { time.Sleep(time.Second) continue } flowtableExpire, err := a.EtcdClient.GetInt64("/agent/config/flowtable_expire") if err != nil { time.Sleep(time.Second) continue } updateTime := time.Duration(flowtableUpdate) * time.Second expireTime := time.Duration(flowtableExpire) * time.Second a.FlowTableAllocator = flow.NewTableAllocator(updateTime, expireTime) // expose a flow server through the client connection flow.NewServer(a.FlowTableAllocator, a.WSClient) packet_injector.NewServer(a.WSClient, a.Graph) a.FlowProbeBundle = fprobes.NewFlowProbeBundleFromConfig(a.TopologyProbeBundle, a.Graph, a.FlowTableAllocator) a.FlowProbeBundle.Start() l, err := ondemand.NewOnDemandProbeServer(a.FlowProbeBundle, a.Graph, a.WSClient) if err != nil { logging.GetLogger().Errorf("Unable to start on-demand flow probe %s", err.Error()) os.Exit(1) } a.OnDemandProbeServer = l a.OnDemandProbeServer.Start() break } } }
func NewServerFromConfig() (*Server, error) { embedEtcd := config.GetConfig().GetBool("etcd.embedded") backend, err := graph.BackendFromConfig() if err != nil { return nil, err } g, err := graph.NewGraphFromConfig(backend) if err != nil { return nil, err } httpServer, err := shttp.NewServerFromConfig("analyzer") if err != nil { return nil, err } wsServer := shttp.NewWSServerFromConfig(httpServer, "/ws") var etcdServer *etcd.EmbeddedEtcd if embedEtcd { if etcdServer, err = etcd.NewEmbeddedEtcdFromConfig(); err != nil { return nil, err } } etcdClient, err := etcd.NewEtcdClientFromConfig() if err != nil { return nil, err } analyzerUpdate := config.GetConfig().GetInt("analyzer.flowtable_update") analyzerExpire := config.GetConfig().GetInt("analyzer.flowtable_expire") agentRatio := config.GetConfig().GetFloat64("analyzer.flowtable_agent_ratio") if agentRatio == 0.0 { agentRatio = 0.5 } agentUpdate := int64(float64(analyzerUpdate) * agentRatio) agentExpire := int64(float64(analyzerExpire) * agentRatio) if err := etcdClient.SetInt64("/agent/config/flowtable_update", agentUpdate); err != nil { return nil, err } if err := etcdClient.SetInt64("/agent/config/flowtable_expire", agentExpire); err != nil { return nil, err } apiServer, err := api.NewApi(httpServer, etcdClient.KeysApi) if err != nil { return nil, err } captureApiHandler := &api.CaptureApiHandler{ BasicApiHandler: api.BasicApiHandler{ ResourceHandler: &api.CaptureResourceHandler{}, EtcdKeyAPI: etcdClient.KeysApi, }, Graph: g, } err = apiServer.RegisterApiHandler(captureApiHandler) if err != nil { return nil, err } alertApiHandler := &api.AlertApiHandler{ BasicApiHandler: api.BasicApiHandler{ ResourceHandler: &api.AlertResourceHandler{}, EtcdKeyAPI: etcdClient.KeysApi, }, } err = apiServer.RegisterApiHandler(alertApiHandler) if err != nil { return nil, err } alertManager := alert.NewAlertManager(g, alertApiHandler) aserver := alert.NewServer(alertManager, wsServer) gserver := graph.NewServer(g, wsServer) gfe := mappings.NewGraphFlowEnhancer(g) ofe := mappings.NewOvsFlowEnhancer(g) pipeline := mappings.NewFlowMappingPipeline(gfe, ofe) tableClient := flow.NewTableClient(wsServer) server := &Server{ HTTPServer: httpServer, WSServer: wsServer, GraphServer: gserver, AlertServer: aserver, FlowMappingPipeline: pipeline, TableClient: tableClient, EmbeddedEtcd: etcdServer, EtcdClient: etcdClient, } server.SetStorageFromConfig() updateHandler := flow.NewFlowHandler(server.flowExpireUpdate, time.Second*time.Duration(analyzerUpdate)) expireHandler := flow.NewFlowHandler(server.flowExpireUpdate, time.Second*time.Duration(analyzerExpire)) flowtable := flow.NewTable(updateHandler, expireHandler) server.FlowTable = flowtable api.RegisterTopologyApi("analyzer", g, httpServer, tableClient, server.Storage) api.RegisterFlowApi("analyzer", flowtable, server.Storage, httpServer) return server, nil }