예제 #1
0
func main() {
	tsdbFlag := flag.String("tsdb", "",
		"Address of the OpenTSDB server where to push telemetry to")
	textFlag := flag.Bool("text", false,
		"Print the output as simple text")
	configFlag := flag.String("config", "",
		"Config to turn OpenConfig telemetry into OpenTSDB put requests")
	username, password, subscriptions, addrs, opts := client.ParseFlags()

	if !(*tsdbFlag != "" || *textFlag) {
		glog.Fatal("Specify the address of the OpenTSDB server to write to with -tsdb")
	} else if *configFlag == "" {
		glog.Fatal("Specify a JSON configuration file with -config")
	}

	config, err := loadConfig(*configFlag)
	if err != nil {
		glog.Fatal(err)
	}
	// Ignore the default "subscribe-to-everything" subscription of the
	// -subscribe flag.
	if subscriptions[0] == "" {
		subscriptions = subscriptions[1:]
	}
	// Add the subscriptions from the config file.
	subscriptions = append(subscriptions, config.Subscriptions...)

	var c OpenTSDBConn
	if *textFlag {
		c = newTextDumper()
	} else {
		// TODO: support HTTP(S).
		c = newTelnetClient(*tsdbFlag)
	}

	wg := new(sync.WaitGroup)
	for _, addr := range addrs {
		wg.Add(1)
		publish := func(addr string, message proto.Message) {
			resp, ok := message.(*openconfig.SubscribeResponse)
			if !ok {
				glog.Errorf("Unexpected type of message: %T", message)
				return
			}
			if notif := resp.GetUpdate(); notif != nil {
				pushToOpenTSDB(addr, c, config, notif)
			}
		}
		c := client.New(username, password, addr, opts)
		go c.Subscribe(wg, subscriptions, publish)
	}
	wg.Wait()
}
예제 #2
0
func main() {
	username, password, subscriptions, hostAddrs, opts := occlient.ParseFlags()
	if *redisFlag == "" {
		glog.Fatal("Specify the address of the Redis server to write to with -redis")
	}

	redisAddrs := strings.Split(*redisFlag, ",")
	if !*clusterMode && len(redisAddrs) > 1 {
		glog.Fatal("Please pass only 1 redis address in noncluster mode or enable cluster mode")
	}

	if *clusterMode {
		client = redis.NewClusterClient(&redis.ClusterOptions{
			Addrs:    redisAddrs,
			Password: *redisPassword,
		})
	} else {
		client = redis.NewClient(&redis.Options{
			Addr:     *redisFlag,
			Password: *redisPassword,
		})
	}
	defer client.Close()

	// TODO: Figure out ways to handle being in the wrong mode:
	// Connecting to cluster in non cluster mode - we get a MOVED error on the first HMSET
	// Connecting to a noncluster in cluster mode - we get stuck forever
	_, err := client.Ping().Result()
	if err != nil {
		glog.Fatal("Failed to connect to client: ", err)
	}

	ocPublish := func(addr string, message proto.Message) {
		resp, ok := message.(*openconfig.SubscribeResponse)
		if !ok {
			glog.Errorf("Unexpected type of message: %T", message)
			return
		}
		if notif := resp.GetUpdate(); notif != nil {
			bufferToRedis(addr, notif)
		}
	}

	wg := new(sync.WaitGroup)
	for _, hostAddr := range hostAddrs {
		wg.Add(1)
		c := occlient.New(username, password, hostAddr, opts)
		go c.Subscribe(wg, subscriptions, ocPublish)
	}
	wg.Wait()
}
예제 #3
0
func main() {
	username, password, subscriptions, addrs, opts := client.ParseFlags()

	if *getFlag != "" {
		c := client.New(username, password, addrs[0], opts)
		for _, notification := range c.Get(*getFlag) {
			var notifStr string
			if *jsonFlag {
				var err error
				if notifStr, err = openconfig.NotificationToJSON(notification); err != nil {
					glog.Fatal(err)
				}
			} else {
				notifStr = notification.String()
			}
			fmt.Println(notifStr)

		}
		return
	}

	publish := func(addr string, message proto.Message) {
		resp, ok := message.(*pb.SubscribeResponse)
		if !ok {
			glog.Errorf("Unexpected type of message: %T", message)
			return
		}
		if resp.GetHeartbeat() != nil && !glog.V(1) {
			return // Log heartbeats with verbose logging only.
		}
		var respTxt string
		var err error
		if *jsonFlag {
			respTxt, err = openconfig.SubscribeResponseToJSON(resp)
			if err != nil {
				glog.Fatal(err)
			}
		} else {
			respTxt = proto.MarshalTextString(resp)
		}
		fmt.Println(respTxt)
	}

	wg := new(sync.WaitGroup)
	for _, addr := range addrs {
		wg.Add(1)
		c := client.New(username, password, addr, opts)
		go c.Subscribe(wg, subscriptions, publish)
	}
	wg.Wait()
}
예제 #4
0
func pushToRedis(data *redisData) {
	_, err := client.Pipelined(func(pipe *redis.Pipeline) error {
		if data.hmset != nil {
			if reply := client.HMSet(data.key, data.hmset); reply.Err() != nil {
				glog.Fatal("Redis HMSET error: ", reply.Err())
			}
			redisPublish(data.key, "updates", data.pub)
		}
		if data.hdel != nil {
			if reply := client.HDel(data.key, data.hdel...); reply.Err() != nil {
				glog.Fatal("Redis HDEL error: ", reply.Err())
			}
			redisPublish(data.key, "deletes", data.hdel)
		}
		return nil
	})
	if err != nil {
		glog.Fatal("Failed to send Pipelined commands: ", err)
	}
}
예제 #5
0
func redisPublish(path, kind string, payload interface{}) {
	js, err := json.Marshal(map[string]interface{}{
		"kind":    kind,
		"payload": payload,
	})
	if err != nil {
		glog.Fatalf("JSON error: %s", err)
	}
	if reply := client.Publish(path, string(js)); reply.Err() != nil {
		glog.Fatal("Redis PUBLISH error: ", reply.Err())
	}
}
예제 #6
0
// Run sets up the HTTP server and any handlers
func (s *server) Run() {
	http.HandleFunc("/debug", debugHandler)
	http.HandleFunc("/debug/latency", latencyHandler)

	var listener net.Listener
	var listenErr error
	err := netns.Do(s.vrfName, func() {
		listener, listenErr = net.Listen("tcp", s.serverName)
	})
	if err != nil {
		glog.Fatalf("Failed to go to network namespace for vrf %s: %s", s.vrfName, err)
	}
	if listenErr != nil {
		glog.Fatal("Could not start monitor server:", listenErr)
	}

	err = http.Serve(listener, nil)
	if err != nil {
		glog.Fatal("http serve returned with error:", err)
	}
}
예제 #7
0
// ParseFlags registers some additional common flags,
// parses the flags, and returns the resulting gRPC options,
// and other settings to connect to the gRPC interface.
func ParseFlags() (username string, password string, subscriptions, addrs []string,
	opts []grpc.DialOption) {

	var (
		addrsFlag = flag.String("addrs", "localhost:6042",
			"Comma-separated list of addresses of OpenConfig gRPC servers")

		caFileFlag = flag.String("cafile", "",
			"Path to server TLS certificate file")

		certFileFlag = flag.String("certfile", "",
			"Path to client TLS certificate file")

		keyFileFlag = flag.String("keyfile", "",
			"Path to client TLS private key file")

		passwordFlag = flag.String("password", "",
			"Password to authenticate with")

		subscribeFlag = flag.String("subscribe", "",
			"Comma-separated list of paths to subscribe to upon connecting to the server")

		usernameFlag = flag.String("username", "",
			"Username to authenticate with")

		tlsFlag = flag.Bool("tls", false,
			"Enable TLS")
	)

	flag.Parse()
	if *tlsFlag || *caFileFlag != "" || *certFileFlag != "" {
		config := &tls.Config{}
		if *caFileFlag != "" {
			b, err := ioutil.ReadFile(*caFileFlag)
			if err != nil {
				glog.Fatal(err)
			}
			cp := x509.NewCertPool()
			if !cp.AppendCertsFromPEM(b) {
				glog.Fatalf("credentials: failed to append certificates")
			}
			config.RootCAs = cp
		} else {
			config.InsecureSkipVerify = true
		}
		if *certFileFlag != "" {
			if *keyFileFlag == "" {
				glog.Fatalf("Please provide both -certfile and -keyfile")
			}
			cert, err := tls.LoadX509KeyPair(*certFileFlag, *keyFileFlag)
			if err != nil {
				glog.Fatal(err)
			}
			config.Certificates = []tls.Certificate{cert}
		}
		opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(config)))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}
	addrs = strings.Split(*addrsFlag, ",")
	subscriptions = strings.Split(*subscribeFlag, ",")
	return *usernameFlag, *passwordFlag, subscriptions, addrs, opts
}