func NewOrientDBBackendFromConfig() (*OrientDBBackend, error) { addr := config.GetConfig().GetString("storage.orientdb.addr") database := config.GetConfig().GetString("storage.orientdb.database") username := config.GetConfig().GetString("storage.orientdb.username") password := config.GetConfig().GetString("storage.orientdb.password") return NewOrientDBBackend(addr, database, username, password) }
func init() { Analyzer.Flags().String("listen", "127.0.0.1:8082", "address and port for the analyzer API") config.GetConfig().BindPFlag("analyzer.listen", Analyzer.Flags().Lookup("listen")) Analyzer.Flags().Int("flowtable-expire", 600, "expiration time for flowtable entries") config.GetConfig().BindPFlag("analyzer.flowtable_expire", Analyzer.Flags().Lookup("flowtable-expire")) Analyzer.Flags().Int("flowtable-update", 60, "send updated flows to storage every time (second)") config.GetConfig().BindPFlag("analyzer.flowtable_update", Analyzer.Flags().Lookup("flowtable-update")) Analyzer.Flags().String("elasticsearch", "127.0.0.1:9200", "elasticsearch server") config.GetConfig().BindPFlag("storage.elasticsearch", Analyzer.Flags().Lookup("elasticsearch")) Analyzer.Flags().Bool("embed-etcd", true, "embed etcd") config.GetConfig().BindPFlag("etcd.embedded", Analyzer.Flags().Lookup("embed-etcd")) Analyzer.Flags().Int("etcd-port", 2379, "embedded etcd port") config.GetConfig().BindPFlag("etcd.port", Analyzer.Flags().Lookup("etcd-port")) Analyzer.Flags().String("etcd-datadir", "/tmp/skydive-etcd", "embedded etcd data folder") config.GetConfig().BindPFlag("etcd.data_dir", Analyzer.Flags().Lookup("etcd-datadir")) Analyzer.Flags().String("graph-backend", "memory", "graph backend") config.GetConfig().BindPFlag("graph.backend", Analyzer.Flags().Lookup("graph-backend")) Analyzer.Flags().String("gremlin", "ws://127.0.0.1:8182", "gremlin server") config.GetConfig().BindPFlag("graph.gremlin", Analyzer.Flags().Lookup("gremlin")) }
func NewAgentAnalyzerServerConn(addr *net.UDPAddr) (a *AgentAnalyzerServerConn, err error) { a = &AgentAnalyzerServerConn{mode: UDP} certPEM := config.GetConfig().GetString("analyzer.X509_cert") keyPEM := config.GetConfig().GetString("analyzer.X509_key") clientCertPEM := config.GetConfig().GetString("agent.X509_cert") if len(certPEM) > 0 && len(keyPEM) > 0 { cert, err := tls.LoadX509KeyPair(certPEM, keyPEM) if err != nil { logging.GetLogger().Fatalf("Can't read X509 key pair set in config : cert '%s' key '%s'", certPEM, keyPEM) } rootPEM, err := ioutil.ReadFile(clientCertPEM) if err != nil { logging.GetLogger().Fatalf("Failed to open root certificate '%s' : %s", certPEM, err.Error()) } roots := x509.NewCertPool() ok := roots.AppendCertsFromPEM([]byte(rootPEM)) if !ok { logging.GetLogger().Fatal("Failed to parse root certificate " + certPEM) } cfgTLS := &tls.Config{ ClientCAs: roots, ClientAuth: tls.RequireAndVerifyClientCert, Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12, PreferServerCipherSuites: true, CipherSuites: []uint16{ tls.TLS_RSA_WITH_AES_128_CBC_SHA, tls.TLS_RSA_WITH_AES_256_CBC_SHA, tls.TLS_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, }, } cfgTLS.BuildNameToCertificate() a.tlsListen, err = tls.Listen("tcp", fmt.Sprintf("%s:%d", common.IPToString(addr.IP), addr.Port+1), cfgTLS) if err != nil { return nil, err } a.mode = TLS logging.GetLogger().Info("Analyzer listen agents on TLS socket") return a, nil } a.udpConn, err = net.ListenUDP("udp", addr) logging.GetLogger().Info("Analyzer listen agents on UDP socket") return a, err }
func NewElasticSearchClientFromConfig() (*ElasticSearchClient, error) { elasticonfig := strings.Split(config.GetConfig().GetString("storage.elasticsearch.host"), ":") if len(elasticonfig) != 2 { return nil, ErrBadConfig } maxConns := config.GetConfig().GetInt("storage.elasticsearch.maxconns") retrySeconds := config.GetConfig().GetInt("storage.elasticsearch.retry") bulkMaxDocs := config.GetConfig().GetInt("storage.elasticsearch.bulk_maxdocs") return NewElasticSearchClient(elasticonfig[0], elasticonfig[1], maxConns, retrySeconds, bulkMaxDocs) }
func NewElasticSearchBackendFromConfig() (*ElasticSearchBackend, error) { addr := config.GetConfig().GetString("storage.elasticsearch.host") c := strings.Split(addr, ":") if len(c) != 2 { return nil, ErrBadConfig } maxConns := config.GetConfig().GetInt("storage.elasticsearch.maxconns") retrySeconds := config.GetConfig().GetInt("storage.elasticsearch.retry") bulkMaxDocs := config.GetConfig().GetInt("storage.elasticsearch.bulk_maxdocs") return NewElasticSearchBackend(c[0], c[1], maxConns, retrySeconds, bulkMaxDocs) }
func NewOpenContrailMapper(g *graph.Graph, r *graph.Node) *OpenContrailMapper { host := config.GetConfig().GetString("opencontrail.host") port := config.GetConfig().GetInt("opencontrail.port") if host == "" { host = "localhost" } if port == 0 { port = 8085 } mapper := &OpenContrailMapper{graph: g, root: r, agentHost: host, agentPort: port} mapper.nodeUpdaterChan = make(chan graph.Identifier, 500) g.AddEventListener(mapper) return mapper }
func init() { host, err := os.Hostname() if err != nil { panic(err) } Agent.Flags().String("host-id", host, "ID used to reference the agent, defaults to hostname") config.GetConfig().BindPFlag("host_id", Agent.Flags().Lookup("host-id")) Agent.Flags().String("listen", "127.0.0.1:8081", "address and port for the agent API") config.GetConfig().BindPFlag("agent.listen", Agent.Flags().Lookup("listen")) Agent.Flags().String("ovsdb", "unix:///var/run/openvswitch/db.sock", "ovsdb connection") config.GetConfig().BindPFlag("ovs.ovsdb", Agent.Flags().Lookup("ovsdb")) }
func CreateRootNode(g *graph.Graph) *graph.Node { hostID := config.GetConfig().GetString("host_id") m := graph.Metadata{"Name": hostID, "Type": "host"} if config.GetConfig().IsSet("agent.metadata") { subtree := config.GetConfig().Sub("agent.metadata") for key, value := range subtree.AllSettings() { m[key] = value } } buffer, err := ioutil.ReadFile("/var/lib/cloud/data/instance-id") if err == nil { m["InstanceID"] = strings.TrimSpace(string(buffer)) } u, _ := uuid.NewV5(uuid.NamespaceOID, []byte(hostID)) return g.NewNode(graph.Identifier(u.String()), m) }
func NewOvsdbProbeFromConfig(g *graph.Graph, n *graph.Node) *OvsdbProbe { address := config.GetConfig().GetString("ovs.ovsdb") var protocol string var target string if strings.HasPrefix(address, "unix://") { target = strings.TrimPrefix(address, "unix://") protocol = "unix" } else if strings.HasPrefix(address, "tcp://") { target = strings.TrimPrefix(address, "tcp://") protocol = "tcp" } else { // fallback to the original address format addr:port addr, port, err := config.GetHostPortAttributes("ovs", "ovsdb") if err != nil { logging.GetLogger().Errorf("Configuration error: %s", err.Error()) return nil } protocol = "tcp" target = fmt.Sprintf("%s:%d", addr, port) } return NewOvsdbProbe(g, n, protocol, target) }
func (s *Server) SetStorageFromConfig() { if t := config.GetConfig().GetString("analyzer.storage"); t != "" { var ( err error storage storage.Storage ) switch t { case "elasticsearch": storage, err = elasticsearch.New() if err != nil { logging.GetLogger().Fatalf("Can't connect to ElasticSearch server: %v", err) } case "orientdb": storage, err = orientdb.New() if err != nil { logging.GetLogger().Fatalf("Can't connect to OrientDB server: %v", err) } default: logging.GetLogger().Fatalf("Storage type unknown: %s", t) os.Exit(1) } s.SetStorage(storage) logging.GetLogger().Infof("Using %s as storage", t) } }
func NewAgentAnalyzerClientConn(addr *net.UDPAddr) (a *AgentAnalyzerClientConn, err error) { a = &AgentAnalyzerClientConn{} certPEM := config.GetConfig().GetString("agent.X509_cert") keyPEM := config.GetConfig().GetString("agent.X509_key") serverCertPEM := config.GetConfig().GetString("analyzer.X509_cert") if len(certPEM) > 0 && len(keyPEM) > 0 { cert, err := tls.LoadX509KeyPair(certPEM, keyPEM) if err != nil { logging.GetLogger().Fatalf("Can't read X509 key pair set in config : cert '%s' key '%s'", certPEM, keyPEM) return nil, err } rootPEM, err := ioutil.ReadFile(serverCertPEM) if err != nil { logging.GetLogger().Fatalf("Failed to open root certificate '%s' : %s", certPEM, err.Error()) } roots := x509.NewCertPool() ok := roots.AppendCertsFromPEM(rootPEM) if !ok { logging.GetLogger().Fatal("Failed to parse root certificate " + certPEM) } cfgTLS := &tls.Config{ Certificates: []tls.Certificate{cert}, RootCAs: roots, } cfgTLS.BuildNameToCertificate() logging.GetLogger().Debugf("TLS client connection ... Dial %s:%d", common.IPToString(addr.IP), addr.Port+1) a.tlsConnClient, err = tls.Dial("tcp", fmt.Sprintf("%s:%d", common.IPToString(addr.IP), addr.Port+1), cfgTLS) if err != nil { logging.GetLogger().Errorf("TLS error %s:%d : %s", common.IPToString(addr.IP), addr.Port+1, err.Error()) return nil, err } state := a.tlsConnClient.ConnectionState() if state.HandshakeComplete == false { logging.GetLogger().Debugf("TLS Handshake is not complete %s:%d : %+v", common.IPToString(addr.IP), addr.Port+1, state) return nil, errors.New("TLS Handshake is not complete") } logging.GetLogger().Debugf("TLS v%d Handshake is complete on %s:%d", state.Version, common.IPToString(addr.IP), addr.Port+1) return a, nil } a.udpConn, err = net.DialUDP("udp", nil, addr) if err != nil { return nil, err } logging.GetLogger().Debug("UDP client dialup done") return a, nil }
func NewFlowProbeBundleFromConfig(tb *probes.TopologyProbeBundle, g *graph.Graph, fta *flow.TableAllocator) *FlowProbeBundle { list := config.GetConfig().GetStringSlice("agent.flow.probes") logging.GetLogger().Infof("Flow probes: %v", list) gfe := mappings.NewGraphFlowEnhancer(g) var aclient *analyzer.Client addr, port, err := config.GetAnalyzerClientAddr() if err != nil { logging.GetLogger().Errorf("Unable to parse analyzer client: %s", err.Error()) return nil } if addr != "" { aclient, err = analyzer.NewClient(addr, port) if err != nil { logging.GetLogger().Errorf("Analyzer client error %s:%d : %s", addr, port, err.Error()) return nil } } probes := make(map[string]probe.Probe) for _, t := range list { if _, ok := probes[t]; ok { continue } switch t { case "ovssflow": o := NewOvsSFlowProbesHandler(tb, g) if o != nil { ofe := mappings.NewOvsFlowEnhancer(g) pipeline := mappings.NewFlowMappingPipeline(gfe, ofe) probes[t] = FlowProbe{fpi: o, pipeline: pipeline, client: aclient} } case "gopacket": o := NewGoPacketProbesHandler(g) if o != nil { pipeline := mappings.NewFlowMappingPipeline(gfe) gopacket := FlowProbe{fpi: o, pipeline: pipeline, client: aclient} probes["afpacket"] = gopacket probes["pcap"] = gopacket } default: logging.GetLogger().Errorf("unknown probe type %s", t) } } p := probe.NewProbeBundle(probes) return &FlowProbeBundle{ ProbeBundle: *p, Graph: g, FlowTableAllocator: fta, } }
func initSkydiveLogger() { id := config.GetConfig().GetString("host_id") + ":" + skydiveLoggingID skydiveLogger = SkydiveLogger{ id: id, loggers: make(map[string]*logging.Logger), format: "%{color}%{time} " + id + " %{shortfile} %{shortpkg} %{longfunc} > %{level:.4s} %{id:03x}%{color:reset} %{message}", formatDebug: "%{color}%{time} " + id + " %{shortfile} %{shortpkg} %{callpath:5} %{longfunc} > %{level:.4s} %{id:03x}%{color:reset} %{message}", } newLogger("default", "INFO") }
func (a *SFlowAgentAllocator) Alloc(uuid string, p flow.FlowProbeNodeSetter, ft *flow.Table) (*SFlowAgent, error) { address := config.GetConfig().GetString("sflow.bind_address") if address == "" { address = "127.0.0.1" } min := config.GetConfig().GetInt("sflow.port_min") if min == 0 { min = 6345 } max := config.GetConfig().GetInt("sflow.port_max") if max == 0 { max = 6355 } a.Lock() defer a.Unlock() // check if there is an already allocated agent for this uuid for _, agent := range a.allocated { if uuid == agent.UUID { return agent, AgentAlreadyAllocated } } for i := min; i != max+1; i++ { if _, ok := a.allocated[i]; !ok { s := NewSFlowAgent(uuid, address, i, ft) s.SetFlowProbeNodeSetter(p) a.allocated[i] = s s.Start() return s, nil } } return nil, errors.New("sflow port exhausted") }
func NewSession() (*Session, error) { s := &Session{ analyzerAddr: "localhost:8082", authenticationOpts: shttp.AuthenticationOpts{ Username: "******", Password: "******", }, } config.GetConfig().Set("agent.analyzers", s.analyzerAddr) return s, nil }
func NewAuthenticationBackendFromConfig() (AuthenticationBackend, error) { t := config.GetConfig().GetString("auth.type") switch t { case "basic": return NewBasicAuthenticationBackendFromConfig() case "keystone": return NewKeystoneAuthenticationBackendFromConfig(), nil default: return NewNoAuthenticationBackend(), nil } }
func BackendFromConfig() (backend GraphBackend, err error) { cachingMode := Direct name := config.GetConfig().GetString("graph.backend") if len(name) == 0 { name = "memory" } switch name { case "memory": backend, err = NewMemoryBackend() case "gremlin": endpoint := config.GetConfig().GetString("graph.gremlin") backend, err = NewGremlinBackend(endpoint) cachingMode = Shadowed case "titangraph": endpoint := config.GetConfig().GetString("graph.gremlin") backend, err = NewTitangraphBackend(endpoint) cachingMode = Shadowed case "orientdb": backend, err = NewOrientDBBackendFromConfig() cachingMode = Shadowed case "elasticsearch": backend, err = NewElasticSearchBackendFromConfig() cachingMode = Shadowed default: return nil, errors.New("Config file is misconfigured, graph backend unknown: " + name) } if err != nil { return nil, err } switch cachingMode { case Shadowed: return NewShadowedBackend(backend) default: return backend, nil } }
func NewNeutronMapper(g *graph.Graph, wsClient *shttp.WSAsyncClient, authURL, username, password, tenantName, regionName, domainName string, availability gophercloud.Availability) (*NeutronMapper, error) { mapper := &NeutronMapper{graph: g, wsClient: wsClient} opts := gophercloud.AuthOptions{ IdentityEndpoint: authURL, Username: username, Password: password, TenantName: tenantName, DomainName: domainName, AllowReauth: true, } provider, err := openstack.AuthenticatedClient(opts) if err != nil { return nil, err } client, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{ Name: "neutron", Region: regionName, Availability: availability, }) if err != nil { return nil, err } mapper.client = client // Create a cache with a default expiration time of 5 minutes, and which // purges expired items every 30 seconds expire := config.GetConfig().GetInt("cache.expire") cleanup := config.GetConfig().GetInt("cache.cleanup") mapper.cache = cache.New(time.Duration(expire)*time.Second, time.Duration(cleanup)*time.Second) mapper.nodeUpdaterChan = make(chan graph.Identifier, 500) g.AddEventListener(mapper) return mapper, nil }
func NewTopologyProbeBundleFromConfig(g *graph.Graph, n *graph.Node) *TopologyProbeBundle { list := config.GetConfig().GetStringSlice("agent.topology.probes") // FIX(safchain) once viper setdefault on nested key will be fixed move this // to config init if len(list) == 0 { list = []string{"fabric", "netlink", "netns"} } logging.GetLogger().Infof("Topology probes: %v", list) probes := make(map[string]probe.Probe) for _, t := range list { if _, ok := probes[t]; ok { continue } switch t { case "netlink": probes[t] = NewNetLinkProbe(g, n) case "netns": probes[t] = NewNetNSProbeFromConfig(g, n) case "ovsdb": probes[t] = NewOvsdbProbeFromConfig(g, n) case "docker": probes[t] = NewDockerProbeFromConfig(g, n) case "neutron": neutron, err := NewNeutronMapperFromConfig(g) if err != nil { logging.GetLogger().Errorf("Failed to initialize Neutron probe: %s", err.Error()) continue } probes[t] = neutron case "fabric": probes[t] = NewFabricProbe(g) case "opencontrail": probes[t] = NewOpenContrailMapper(g, n) default: logging.GetLogger().Errorf("unknown probe type %s", t) } } p := probe.NewProbeBundle(probes) return &TopologyProbeBundle{*p} }
func NewTopologyProbeBundleFromConfig(g *graph.Graph, n *graph.Node, wsClient *shttp.WSAsyncClient) (*probe.ProbeBundle, error) { list := config.GetConfig().GetStringSlice("agent.topology.probes") logging.GetLogger().Infof("Topology probes: %v", list) probes := make(map[string]probe.Probe) bundle := probe.NewProbeBundle(probes) for _, t := range list { if _, ok := probes[t]; ok { continue } switch t { case "netlink": probes[t] = tprobes.NewNetLinkProbe(g, n) case "netns": nsProbe, err := tprobes.NewNetNSProbeFromConfig(g, n) if err != nil { return nil, err } probes[t] = nsProbe case "ovsdb": probes[t] = tprobes.NewOvsdbProbeFromConfig(g, n) case "docker": dockerProbe, err := tprobes.NewDockerProbeFromConfig(g, n) if err != nil { return nil, err } probes[t] = dockerProbe case "neutron": neutron, err := tprobes.NewNeutronMapperFromConfig(g, wsClient) if err != nil { logging.GetLogger().Errorf("Failed to initialize Neutron probe: %s", err.Error()) return nil, err } probes["neutron"] = neutron case "opencontrail": probes[t] = tprobes.NewOpenContrailMapper(g, n) default: logging.GetLogger().Errorf("unknown probe type %s", t) } } return bundle, nil }
func initLogger() (err error) { initSkydiveLogger() cfg := config.GetConfig() for cfgPkg, cfgLvl := range cfg.GetStringMapString("logging") { pkg := strings.TrimSpace(cfgPkg) lvl := strings.TrimSpace(cfgLvl) if pkg == "default" { err = newLogger("default", lvl) } else { err = newLogger("github.com/skydive-project/skydive/"+pkg, lvl) } if err != nil { return errors.New("Can't parse logging line : \"" + pkg + " " + lvl + "\" " + err.Error()) } } return }
func NewNeutronMapperFromConfig(g *graph.Graph, wsCient *shttp.WSAsyncClient) (*NeutronMapper, error) { authURL := config.GetConfig().GetString("openstack.auth_url") username := config.GetConfig().GetString("openstack.username") password := config.GetConfig().GetString("openstack.password") tenantName := config.GetConfig().GetString("openstack.tenant_name") regionName := config.GetConfig().GetString("openstack.region_name") endpointType := config.GetConfig().GetString("openstack.endpoint_type") domainName := config.GetConfig().GetString("openstack.domain_name") endpointTypes := map[string]gophercloud.Availability{ "public": gophercloud.AvailabilityPublic, "admin": gophercloud.AvailabilityAdmin, "internal": gophercloud.AvailabilityInternal} if a, ok := endpointTypes[endpointType]; !ok { return nil, fmt.Errorf("Endpoint type '%s' is not valid (must be 'public', 'admin' or 'internal')", endpointType) } else { return NewNeutronMapper(g, wsCient, authURL, username, password, tenantName, regionName, domainName, a) } }
func NewWSAsyncClientFromConfig(clientType string, addr string, port int, path string, authClient *AuthenticationClient) (*WSAsyncClient, error) { hostID := config.GetConfig().GetString("host_id") return NewWSAsyncClient(hostID, clientType, addr, port, path, authClient) }
func actionSetVarAnalyzer(s *Session, arg string) error { s.analyzerAddr = arg config.GetConfig().Set("agent.analyzers", s.analyzerAddr) return nil }
func NewGraphFromConfig(backend GraphBackend) (*Graph, error) { hostID := config.GetConfig().GetString("host_id") return NewGraph(hostID, backend) }
) var ( authenticationOpts shttp.AuthenticationOpts gremlinQuery string analyzerAddr string ) var Client = &cobra.Command{ Use: "client", Short: "Skydive client", Long: "Skydive client", SilenceUsage: true, PersistentPreRun: func(cmd *cobra.Command, args []string) { if flag := cmd.Flags().Lookup("analyzer"); !flag.Changed { config.GetConfig().Set("agent.analyzers", "localhost:8082") } else { config.GetConfig().Set("agent.analyzers", flag.Value) } }, } func printJSON(obj interface{}) { s, err := json.MarshalIndent(obj, "", " ") if err != nil { logging.GetLogger().Errorf(err.Error()) os.Exit(1) } fmt.Println(string(s)) }
func NewWSServerFromConfig(server *Server, endpoint string) *WSServer { w := config.GetConfig().GetInt("ws_pong_timeout") return NewWSServer(server, time.Duration(w)*time.Second, endpoint) }
func New() (*OrientDBStorage, error) { addr := config.GetConfig().GetString("storage.orientdb.addr") database := config.GetConfig().GetString("storage.orientdb.database") username := config.GetConfig().GetString("storage.orientdb.username") password := config.GetConfig().GetString("storage.orientdb.password") client, err := orient.NewClient(addr, database, username, password) if err != nil { return nil, err } if _, err := client.GetDocumentClass("FlowMetric"); err != nil { class := orient.ClassDefinition{ Name: "FlowMetric", Properties: []orient.Property{ {Name: "ABBytes", Type: "INTEGER", Mandatory: true, NotNull: true}, {Name: "ABPackets", Type: "INTEGER", Mandatory: true, NotNull: true}, {Name: "BABytes", Type: "INTEGER", Mandatory: true, NotNull: true}, {Name: "BAPackets", Type: "INTEGER", Mandatory: true, NotNull: true}, {Name: "Start", Type: "INTEGER", Mandatory: true, NotNull: true}, {Name: "Last", Type: "INTEGER", Mandatory: true, NotNull: true}, }, Indexes: []orient.Index{ {Name: "FlowMetric.TimeSpan", Fields: []string{"Start", "Last"}, Type: "NOTUNIQUE"}, }, } if err := client.CreateDocumentClass(class); err != nil { return nil, fmt.Errorf("Failed to register class FlowMetric: %s", err.Error()) } } if _, err := client.GetDocumentClass("Flow"); err != nil { class := orient.ClassDefinition{ Name: "Flow", Properties: []orient.Property{ {Name: "UUID", Type: "STRING", Mandatory: true, NotNull: true}, {Name: "LayersPath", Type: "STRING", Mandatory: true, NotNull: true}, {Name: "Metric", Type: "EMBEDDED", LinkedClass: "FlowMetric"}, {Name: "TrackingID", Type: "STRING", Mandatory: true, NotNull: true}, {Name: "NodeTID", Type: "STRING"}, {Name: "ANodeTID", Type: "STRING"}, {Name: "BNodeTID", Type: "STRING"}, }, Indexes: []orient.Index{ {Name: "Flow.UUID", Fields: []string{"UUID"}, Type: "UNIQUE"}, {Name: "Flow.TrackingID", Fields: []string{"TrackingID"}, Type: "NOTUNIQUE"}, }, } if err := client.CreateDocumentClass(class); err != nil { return nil, fmt.Errorf("Failed to register class Flow: %s", err.Error()) } } flowProp := orient.Property{Name: "Flow", Type: "LINK", LinkedClass: "Flow", Mandatory: false, NotNull: true} client.CreateProperty("FlowMetric", flowProp) flowIndex := orient.Index{Name: "FlowMetric.Flow", Fields: []string{"Flow"}, Type: "NOTUNIQUE"} client.CreateIndex("FlowMetric", flowIndex) return &OrientDBStorage{ client: client, }, nil }
func NewDockerProbeFromConfig(g *graph.Graph, n *graph.Node) (*DockerProbe, error) { dockerURL := config.GetConfig().GetString("docker.url") return NewDockerProbe(g, n, dockerURL) }
func NewEmbeddedEtcdFromConfig() (*EmbeddedEtcd, error) { dataDir := config.GetConfig().GetString("etcd.data_dir") port := config.GetConfig().GetInt("etcd.port") return NewEmbeddedEtcd(port, dataDir) }