Beispiel #1
0
func TestGetConfigPolicy(t *testing.T) {
	Convey("Get Config Policy", t, func() {
		logger := log.New(os.Stdout,
			"test: ",
			log.Ldate|log.Ltime|log.Lshortfile)
		mockPlugin := &mockPlugin{}

		mockSessionState := &MockSessionState{
			Encoder:             encoding.NewGobEncoder(),
			listenPort:          "0",
			token:               "abcdef",
			logger:              logger,
			PingTimeoutDuration: time.Millisecond * 100,
			killChan:            make(chan int),
		}
		c := &collectorPluginProxy{
			Plugin:  mockPlugin,
			Session: mockSessionState,
		}
		var reply []byte
		c.Session.GetConfigPolicy([]byte{}, &reply)
		var cpr GetConfigPolicyReply
		err := c.Session.Decode(reply, &cpr)
		So(err, ShouldBeNil)
		So(cpr.Policy, ShouldNotBeNil)
	})
	Convey("Get error in Config Policy ", t, func() {
		logger := log.New(os.Stdout,
			"test: ",
			log.Ldate|log.Ltime|log.Lshortfile)
		errSession := &errSessionState{
			&MockSessionState{
				Encoder:             encoding.NewGobEncoder(),
				listenPort:          "0",
				token:               "abcdef",
				logger:              logger,
				PingTimeoutDuration: time.Millisecond * 100,
				killChan:            make(chan int),
			}}
		mockErrorPlugin := &mockErrorPlugin{}
		errC := &collectorPluginProxy{
			Plugin:  mockErrorPlugin,
			Session: errSession,
		}
		var reply []byte
		err := errC.Session.GetConfigPolicy([]byte{}, &reply)
		So(err, ShouldNotBeNil)
		So(err.Error(), ShouldResemble, "GetConfigPolicy call error : Error in get config policy")
	})
}
Beispiel #2
0
func newNativeClient(address string, timeout time.Duration, t plugin.PluginType, pub *rsa.PublicKey, secure bool) (*PluginNativeClient, error) {
	// Attempt to dial address error on timeout or problem
	conn, err := net.DialTimeout("tcp", address, timeout)
	// Return nil RPCClient and err if encoutered
	if err != nil {
		return nil, err
	}
	r := rpc.NewClient(conn)
	p := &PluginNativeClient{
		connection: r,
		pluginType: t,
		timeout:    timeout,
	}

	p.encoder = encoding.NewGobEncoder()

	if secure {
		key, err := encrypter.GenerateKey()
		if err != nil {
			return nil, err
		}
		encrypter := encrypter.New(pub, nil)
		encrypter.Key = key
		p.encrypter = encrypter
		p.encoder.SetEncrypter(encrypter)
	}

	return p, nil
}
Beispiel #3
0
func startCollectorServer() (int, Session, error) {
	lis, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return 0, nil, err
	}

	mockPlugin := &mockPlugin{}
	mockSessionState := &MockSessionState{
		Encoder:    encoding.NewGobEncoder(),
		listenPort: "0",
		token:      "abcdef",
		logger: log.New(os.Stdout,
			"test: ",
			log.Ldate|log.Ltime|log.Lshortfile),
		PingTimeoutDuration: time.Millisecond * 100,
		killChan:            make(chan int),
	}

	opts := []grpc.ServerOption{}
	grpcServer := grpc.NewServer(opts...)
	collectProxy := &gRPCCollectorProxy{
		Plugin:  mockPlugin,
		Session: mockSessionState,
		gRPCPluginProxy: gRPCPluginProxy{
			plugin:  mockPlugin,
			session: mockSessionState,
		},
	}

	rpc.RegisterCollectorServer(grpcServer, collectProxy)
	go func() {
		err := grpcServer.Serve(lis)
		if err != nil {
			log.Print(err)
		}
	}()
	return lis.Addr().(*net.TCPAddr).Port, mockSessionState, nil
}
Beispiel #4
0
func TestCollectorProxy(t *testing.T) {
	Convey("Test collector plugin proxy for get metric types ", t, func() {

		logger := log.New()
		mockPlugin := &mockPlugin{}

		mockSessionState := &MockSessionState{
			Encoder:             encoding.NewGobEncoder(),
			listenPort:          "0",
			token:               "abcdef",
			logger:              logger,
			PingTimeoutDuration: time.Millisecond * 100,
			killChan:            make(chan int),
		}
		c := &collectorPluginProxy{
			Plugin:  mockPlugin,
			Session: mockSessionState,
		}
		Convey("Get Metric Types", func() {
			var reply []byte
			c.GetMetricTypes([]byte{}, &reply)
			var mtr GetMetricTypesReply
			err := c.Session.Decode(reply, &mtr)
			So(err, ShouldBeNil)
			So(mtr.MetricTypes[0].Namespace().String(), ShouldResemble, "/foo/*/bar")

		})
		Convey("Get error in Get Metric Type", func() {
			mockErrorPlugin := &mockErrorPlugin{}
			errC := &collectorPluginProxy{
				Plugin:  mockErrorPlugin,
				Session: mockSessionState,
			}
			var reply []byte
			err := errC.GetMetricTypes([]byte{}, &reply)
			So(err.Error(), ShouldResemble, "GetMetricTypes call error : Error in get Metric Type")
		})
		Convey("Collect Metric ", func() {
			args := CollectMetricsArgs{
				MetricTypes: mockMetricType,
			}
			out, err := c.Session.Encode(args)
			So(err, ShouldBeNil)
			var reply []byte
			c.CollectMetrics(out, &reply)
			var mtr CollectMetricsReply
			err = c.Session.Decode(reply, &mtr)
			So(mtr.PluginMetrics[0].Namespace().String(), ShouldResemble, "/foo/test/bar")
			So(mtr.PluginMetrics[0].Namespace()[1].Name, ShouldEqual, "test")

			Convey("Get error in Collect Metric ", func() {
				args := CollectMetricsArgs{
					MetricTypes: mockMetricType,
				}
				mockErrorPlugin := &mockErrorPlugin{}
				errC := &collectorPluginProxy{
					Plugin:  mockErrorPlugin,
					Session: mockSessionState,
				}
				out, err := errC.Session.Encode(args)
				So(err, ShouldBeNil)
				var reply []byte
				err = errC.CollectMetrics(out, &reply)
				So(err, ShouldNotBeNil)
			})

		})

	})
}
Beispiel #5
0
// NewSessionState takes the plugin args and returns a SessionState
// returns State or error and returnCode:
// 0 - ok
// 2 - error when unmarshaling pluginArgs
// 3 - cannot open error files
func NewSessionState(pluginArgsMsg string, plugin Plugin, meta *PluginMeta) (*SessionState, error, int) {
	pluginArg := &Arg{}
	err := json.Unmarshal([]byte(pluginArgsMsg), pluginArg)
	if err != nil {
		return nil, err, 2
	}

	// If no port was provided we let the OS select a port for us.
	// This is safe as address is returned in the Response and keep
	// alive prevents unattended plugins.
	if pluginArg.listenPort == "" {
		pluginArg.listenPort = "0"
	}

	// If no PingTimeoutDuration was provided we need to set it
	if pluginArg.PingTimeoutDuration == 0 {
		pluginArg.PingTimeoutDuration = PingTimeoutDurationDefault
	}

	// Generate random token for this session
	rb := make([]byte, 32)
	rand.Read(rb)
	rs := base64.URLEncoding.EncodeToString(rb)

	logger := &log.Logger{
		Out:       os.Stderr,
		Formatter: &simpleFormatter{},
		Hooks:     make(log.LevelHooks),
		Level:     pluginArg.LogLevel,
	}

	var enc encoding.Encoder
	switch meta.RPCType {
	case JSONRPC:
		enc = encoding.NewJsonEncoder()
	case NativeRPC:
		enc = encoding.NewGobEncoder()
	case GRPC:
		enc = encoding.NewGobEncoder()
		//TODO(CDR): re-think once content-types is settled
	}
	ss := &SessionState{
		Arg:     pluginArg,
		Encoder: enc,

		plugin:   plugin,
		token:    rs,
		killChan: make(chan int),
		logger:   logger,
	}

	if !meta.Unsecure {
		key, err := rsa.GenerateKey(rand.Reader, 2048)
		if err != nil {
			return nil, err, 2
		}
		encrypt := encrypter.New(nil, key)
		enc.SetEncrypter(encrypt)
		ss.Encrypter = encrypt
		ss.privateKey = key
	}
	return ss, nil, 0
}
Beispiel #6
0
// NewSessionState takes the plugin args and returns a SessionState
// returns State or error and returnCode:
// 0 - ok
// 2 - error when unmarshaling pluginArgs
// 3 - cannot open error files
func NewSessionState(pluginArgsMsg string, plugin Plugin, meta *PluginMeta) (*SessionState, error, int) {
	pluginArg := &Arg{}
	err := json.Unmarshal([]byte(pluginArgsMsg), pluginArg)
	if err != nil {
		return nil, err, 2
	}

	// If no port was provided we let the OS select a port for us.
	// This is safe as address is returned in the Response and keep
	// alive prevents unattended plugins.
	if pluginArg.listenPort == "" {
		pluginArg.listenPort = "0"
	}

	// If no PingTimeoutDuration was provided we need to set it
	if pluginArg.PingTimeoutDuration == 0 {
		pluginArg.PingTimeoutDuration = PingTimeoutDurationDefault
	}

	// Generate random token for this session
	rb := make([]byte, 32)
	rand.Read(rb)
	rs := base64.URLEncoding.EncodeToString(rb)

	// Initialize a logger based on PluginLogPath
	truncOrAppend := os.O_TRUNC // truncate log file explicitly given by user
	// Empty or /tmp means use default tmp log (needs to be removed post-aAtruncOrAppendpha)
	if pluginArg.PluginLogPath == "" || pluginArg.PluginLogPath == "/tmp" {
		if runtime.GOOS == "windows" {
			pluginArg.PluginLogPath = `c:\TEMP\snap_plugin.log`
		} else {
			pluginArg.PluginLogPath = "/tmp/snap_plugin.log"
		}
		truncOrAppend = os.O_APPEND
	}
	lf, err := os.OpenFile(pluginArg.PluginLogPath, os.O_WRONLY|os.O_CREATE|truncOrAppend, 0666)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("error opening log file: %v", err)), 3
	}
	logger := log.New(lf, ">>>", log.Ldate|log.Ltime)

	var enc encoding.Encoder
	switch meta.RPCType {
	case JSONRPC:
		enc = encoding.NewJsonEncoder()
	case NativeRPC:
		enc = encoding.NewGobEncoder()
	}
	ss := &SessionState{
		Arg:     pluginArg,
		Encoder: enc,

		plugin:   plugin,
		token:    rs,
		killChan: make(chan int),
		logger:   logger,
	}

	if !meta.Unsecure {
		key, err := rsa.GenerateKey(rand.Reader, 2048)
		if err != nil {
			return nil, err, 2
		}
		encrypt := encrypter.New(nil, key)
		enc.SetEncrypter(encrypt)
		ss.Encrypter = encrypt
		ss.privateKey = key
	}
	return ss, nil, 0
}