github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/pkg/remoteenforcer/remoteenforcer_test.go (about)

     1  package remoteenforcer
     2  
     3  import (
     4  	"context"
     5  	"crypto/hmac"
     6  	"crypto/sha256"
     7  	"encoding/binary"
     8  	"errors"
     9  	"fmt"
    10  	"os"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/blang/semver"
    15  	"github.com/golang/mock/gomock"
    16  	"github.com/mitchellh/hashstructure"
    17  	. "github.com/smartystreets/goconvey/convey"
    18  	"go.aporeto.io/enforcerd/trireme-lib/collector"
    19  	"go.aporeto.io/enforcerd/trireme-lib/common"
    20  	"go.aporeto.io/enforcerd/trireme-lib/controller/constants"
    21  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer"
    22  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/mockenforcer"
    23  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/utils/rpcwrapper"
    24  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/utils/rpcwrapper/mockrpcwrapper"
    25  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/supervisor"
    26  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/supervisor/mocksupervisor"
    27  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/fqconfig"
    28  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/remoteenforcer/internal/client/mockclient"
    29  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/remoteenforcer/internal/statscollector/mockstatscollector"
    30  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/remoteenforcer/internal/tokenissuer/mocktokenclient"
    31  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets"
    32  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets/testhelper"
    33  	"go.aporeto.io/enforcerd/trireme-lib/controller/runtime"
    34  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    35  )
    36  
    37  const (
    38  	pcchan = "/tmp/test.sock"
    39  )
    40  
    41  func initTestEnfReqPayload() rpcwrapper.InitRequestPayload {
    42  	var initEnfPayload rpcwrapper.InitRequestPayload
    43  
    44  	initEnfPayload.Validity = constants.SynTokenRefreshTime
    45  	initEnfPayload.MutualAuth = true
    46  	initEnfPayload.ServerID = "598236b81c252c000102665d"
    47  
    48  	_, s, err := testhelper.NewTestCompactPKISecrets()
    49  	if err != nil {
    50  		fmt.Println("CompackPKI creation failed with:", err)
    51  	}
    52  	initEnfPayload.Secrets = s.RPCSecrets()
    53  	initEnfPayload.Configuration = &runtime.Configuration{}
    54  	return initEnfPayload
    55  }
    56  
    57  func initIdentity(id string) *policy.TagStore {
    58  	initID := policy.NewTagStore()
    59  	initID.AppendKeyValue(id, "")
    60  	return initID
    61  }
    62  
    63  func initAnnotations(an string) *policy.TagStore {
    64  	initAnno := policy.NewTagStore()
    65  	initAnno.AppendKeyValue(an, "")
    66  	return initAnno
    67  }
    68  
    69  func initTrans() policy.TagSelectorList {
    70  
    71  	var tags policy.TagSelectorList
    72  	var tag policy.TagSelector
    73  	var keyval policy.KeyValueOperator
    74  	var action policy.FlowPolicy
    75  	var accept policy.ActionType
    76  
    77  	keyval.Key = "@usr:role"
    78  	keyval.Value = []string{"server"}
    79  	keyval.Operator = "="
    80  	accept = policy.Accept
    81  	action.Action = accept
    82  	tag.Clause = []policy.KeyValueOperator{keyval}
    83  	tag.Policy = &action
    84  	tags = []policy.TagSelector{tag}
    85  
    86  	return tags
    87  }
    88  
    89  func getHash(payload interface{}) []byte {
    90  	hash, err := hashstructure.Hash(payload, nil)
    91  	if err != nil {
    92  		return []byte{}
    93  	}
    94  
    95  	buf := make([]byte, 8)
    96  	binary.BigEndian.PutUint64(buf, hash)
    97  	return buf
    98  }
    99  
   100  func initTestEnfPayload() rpcwrapper.EnforcePayload {
   101  
   102  	var initPayload rpcwrapper.EnforcePayload
   103  	idString := "@usr:role=client $namespace=/sibicentos AporetoContextID=5983bc8c923caa0001337b11"
   104  	anoString := "@app:name=/inspiring_roentgen $namespace=/sibicentos @usr:build-date=20170801 @usr:license=GPLv2 @usr:name=CentOS Base Image @usr:role=client @usr:vendor=CentOS $id=5983bc8c923caa0001337b11 $namespace=/sibicentos $operationalstatus=Running $protected=false $type=Docker $description=centos $enforcerid=5983bba4923caa0001337a19 $name=centos $nativecontextid=b06f47830f64 @app:image=centos @usr:role=client role=client $id=5983bc8c923caa0001337b11 $identity=processingunit $id=5983bc8c923caa0001337b11 $namespace=/sibicentos"
   105  
   106  	initPayload.ContextID = "b06f47830f64"
   107  	initPayload.Policy = &policy.PUPolicyPublic{
   108  		ManagementID:     "5983bc8c923caa0001337b11",
   109  		TriremeAction:    2,
   110  		IPs:              policy.ExtendedMap{"bridge": "172.17.0.2"},
   111  		Identity:         initIdentity(idString).GetSlice(),
   112  		Annotations:      initAnnotations(anoString).GetSlice(),
   113  		CompressedTags:   policy.NewTagStore().GetSlice(),
   114  		TransmitterRules: initTrans(),
   115  	}
   116  
   117  	return initPayload
   118  }
   119  
   120  func initTestUnEnfPayload() rpcwrapper.UnEnforcePayload {
   121  
   122  	var initPayload rpcwrapper.UnEnforcePayload
   123  
   124  	initPayload.ContextID = "b06f47830f64"
   125  
   126  	return initPayload
   127  }
   128  
   129  func Test_NewRemoteEnforcer(t *testing.T) {
   130  
   131  	ctrl := gomock.NewController(t)
   132  	defer ctrl.Finish()
   133  
   134  	Convey("When I try to retrieve rpc server handle", t, func() {
   135  
   136  		rpcHdl := mockrpcwrapper.NewMockRPCServer(ctrl)
   137  		statsClient := mockclient.NewMockReporter(ctrl)
   138  		reportsClient := mockclient.NewMockReporter(ctrl)
   139  		collector := mockstatscollector.NewMockCollector(ctrl)
   140  		tokenclient := mocktokenclient.NewMockTokenClient(ctrl)
   141  		Convey("When I try to create new server with no env set", func() {
   142  			ctx := context.Background()
   143  
   144  			rpcHdl.EXPECT().StartServer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(0)
   145  			server, err := newRemoteEnforcer(ctx, rpcHdl, "mysecret", statsClient, collector, reportsClient, tokenclient, "", "", "", 1, policy.EnforcerMapping, semver.Version{})
   146  
   147  			Convey("Then I should get error for no stats", func() {
   148  				So(err, ShouldBeNil)
   149  				So(server, ShouldNotBeNil)
   150  				So(server.service, ShouldBeNil)
   151  				So(server.rpcHandle, ShouldEqual, rpcHdl)
   152  				So(server.procMountPoint, ShouldResemble, constants.DefaultProcMountPoint)
   153  				So(server.statsClient, ShouldEqual, statsClient)
   154  				So(server.reportsClient, ShouldEqual, reportsClient)
   155  				So(server.ctx, ShouldEqual, ctx)
   156  				So(server.exit, ShouldNotBeNil)
   157  			})
   158  		})
   159  	})
   160  }
   161  
   162  func TestInitEnforcer(t *testing.T) {
   163  
   164  	ctrl := gomock.NewController(t)
   165  	defer ctrl.Finish()
   166  
   167  	Convey("When I try to retrieve rpc server handle", t, func() {
   168  		rpcHdl := mockrpcwrapper.NewMockRPCServer(ctrl)
   169  		mockEnf := mockenforcer.NewMockEnforcer(ctrl)
   170  		mockStats := mockclient.NewMockReporter(ctrl)
   171  		mockReports := mockclient.NewMockReporter(ctrl)
   172  		mockCollector := mockstatscollector.NewMockCollector(ctrl)
   173  		mockSupevisor := mocksupervisor.NewMockSupervisor(ctrl)
   174  		mockTokenClient := mocktokenclient.NewMockTokenClient(ctrl)
   175  
   176  		// Mock the global functions.
   177  		createEnforcer = func(
   178  			mutualAuthorization bool,
   179  			fqConfig fqconfig.FilterQueue,
   180  			collector collector.EventCollector,
   181  			secrets secrets.Secrets,
   182  			serverID string,
   183  			validity time.Duration,
   184  			mode constants.ModeType,
   185  			procMountPoint string,
   186  			externalIPCacheTimeout time.Duration,
   187  			packetLogs bool,
   188  			cfg *runtime.Configuration,
   189  			tokenIssuer common.ServiceTokenIssuer,
   190  			isBPFEnabled bool,
   191  			agentVersion semver.Version,
   192  			serviceMeshType policy.ServiceMesh,
   193  		) (enforcer.Enforcer, error) {
   194  			return mockEnf, nil
   195  		}
   196  
   197  		createSupervisor = func(
   198  			collector collector.EventCollector,
   199  			enforcerInstance enforcer.Enforcer,
   200  			mode constants.ModeType,
   201  			cfg *runtime.Configuration,
   202  			ipv6Enabled bool,
   203  			iptablesLockfile string,
   204  		) (supervisor.Supervisor, error) {
   205  			return mockSupevisor, nil
   206  		}
   207  		defer func() {
   208  			createSupervisor = supervisor.NewSupervisor
   209  			createEnforcer = enforcer.New
   210  		}()
   211  
   212  		Convey("When I try to create new server with env set", func() {
   213  			serr := os.Setenv(constants.EnvStatsChannel, pcchan)
   214  			So(serr, ShouldBeNil)
   215  			serr = os.Setenv(constants.EnvStatsSecret, "T6UYZGcKW-aum_vi-XakafF3vHV7F6x8wdofZs7akGU=")
   216  			So(serr, ShouldBeNil)
   217  
   218  			secret := "T6UYZGcKW-aum_vi-XakafF3vHV7F6x8wdofZs7akGU="
   219  			server, err := newRemoteEnforcer(context.Background(), rpcHdl, secret, mockStats, mockCollector, mockReports, mockTokenClient, "", "", "", 1, policy.EnforcerMapping, semver.Version{})
   220  			So(err, ShouldBeNil)
   221  
   222  			Convey("When I try to initiate an enforcer with invalid secret", func() {
   223  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(false)
   224  
   225  				var rpcwrperreq rpcwrapper.Request
   226  				var rpcwrperres rpcwrapper.Response
   227  
   228  				rpcwrperreq.Payload = initTestEnfReqPayload()
   229  
   230  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   231  
   232  				Convey("Then I should get error", func() {
   233  					So(err, ShouldResemble, errors.New("init message authentication failed"))
   234  				})
   235  			})
   236  
   237  			Convey("When I try to instantiate the enforcer with a bad payload, it should error ", func() {
   238  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   239  
   240  				var rpcwrperreq rpcwrapper.Request
   241  				var rpcwrperres rpcwrapper.Response
   242  
   243  				rpcwrperreq.Payload = initTestEnfPayload()
   244  
   245  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   246  
   247  				Convey("Then I should get error", func() {
   248  					So(err, ShouldResemble, errors.New("invalid request payload"))
   249  				})
   250  			})
   251  
   252  			Convey("When I try to instantiate the enforcer amd the enforcer is initialized, it should fail ", func() {
   253  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   254  
   255  				var rpcwrperreq rpcwrapper.Request
   256  				var rpcwrperres rpcwrapper.Response
   257  
   258  				rpcwrperreq.Payload = initTestEnfReqPayload()
   259  
   260  				server.enforcer = mockEnf
   261  
   262  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   263  
   264  				Convey("Then I should get error", func() {
   265  					So(err, ShouldResemble, errors.New("remote enforcer is already initialized"))
   266  				})
   267  			})
   268  
   269  			Convey("When I try to instantiate the enforcer and the enforcer fails, it should fail and cleanup", func() {
   270  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   271  
   272  				var rpcwrperreq rpcwrapper.Request
   273  				var rpcwrperres rpcwrapper.Response
   274  
   275  				rpcwrperreq.Payload = initTestEnfReqPayload()
   276  
   277  				createEnforcer = func(
   278  					mutualAuthorization bool,
   279  					fqConfig fqconfig.FilterQueue,
   280  					collector collector.EventCollector,
   281  					secrets secrets.Secrets,
   282  					serverID string,
   283  					validity time.Duration,
   284  					mode constants.ModeType,
   285  					procMountPoint string,
   286  					externalIPCacheTimeout time.Duration,
   287  					packetLogs bool,
   288  					cfg *runtime.Configuration,
   289  					tokenIssuer common.ServiceTokenIssuer,
   290  					isBPFEnabled bool,
   291  					agentVersion semver.Version,
   292  					serviceMeshType policy.ServiceMesh,
   293  				) (enforcer.Enforcer, error) {
   294  					return nil, fmt.Errorf("failed enforcer")
   295  				}
   296  
   297  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   298  
   299  				Convey("Then I should get error", func() {
   300  					So(err, ShouldNotBeNil)
   301  					So(err, ShouldResemble, errors.New("Error while initializing remote enforcer, failed enforcer"))
   302  				})
   303  			})
   304  
   305  			Convey("When I try to instantiate the enforcer and the supervisor fails, it should fail", func() {
   306  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   307  
   308  				var rpcwrperreq rpcwrapper.Request
   309  				var rpcwrperres rpcwrapper.Response
   310  
   311  				rpcwrperreq.Payload = initTestEnfReqPayload()
   312  
   313  				createSupervisor = func(
   314  					collector collector.EventCollector,
   315  					enforcerInstance enforcer.Enforcer,
   316  					mode constants.ModeType,
   317  					cfg *runtime.Configuration,
   318  					ipv6Enabled bool,
   319  					iptablesLockfile string,
   320  				) (supervisor.Supervisor, error) {
   321  					return nil, fmt.Errorf("failed supervisor")
   322  				}
   323  
   324  				mockEnf.EXPECT().CleanUp()
   325  
   326  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   327  
   328  				Convey("Then I should get error", func() {
   329  					So(err, ShouldNotBeNil)
   330  					So(err, ShouldResemble, errors.New("unable to setup supervisor: failed supervisor"))
   331  				})
   332  			})
   333  
   334  			Convey("When I try to instantiate the enforcer and the controller fails to run, it should clean up", func() {
   335  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   336  
   337  				var rpcwrperreq rpcwrapper.Request
   338  				var rpcwrperres rpcwrapper.Response
   339  
   340  				rpcwrperreq.Payload = initTestEnfReqPayload()
   341  
   342  				mockEnf.EXPECT().Run(server.ctx).Return(fmt.Errorf("enforcer run error"))
   343  				mockSupevisor.EXPECT().CleanUp()
   344  				mockEnf.EXPECT().CleanUp()
   345  
   346  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   347  
   348  				Convey("Then I should get error", func() {
   349  					So(err, ShouldNotBeNil)
   350  					So(err, ShouldResemble, errors.New("enforcer run error"))
   351  				})
   352  			})
   353  
   354  			Convey("When I try to instantiate the enforcer and the statclient fails to run, it should clean up", func() {
   355  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   356  
   357  				var rpcwrperreq rpcwrapper.Request
   358  				var rpcwrperres rpcwrapper.Response
   359  
   360  				rpcwrperreq.Payload = initTestEnfReqPayload()
   361  
   362  				mockEnf.EXPECT().Run(server.ctx).Return(nil)
   363  				mockStats.EXPECT().Run(server.ctx).Return(fmt.Errorf("stats error"))
   364  				mockSupevisor.EXPECT().CleanUp()
   365  				mockEnf.EXPECT().CleanUp()
   366  
   367  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   368  
   369  				Convey("Then I should get error", func() {
   370  					So(err, ShouldNotBeNil)
   371  					So(err, ShouldResemble, errors.New("stats error"))
   372  				})
   373  			})
   374  
   375  			Convey("When I try to instantiate the enforcer and the supervisor fails to run, it should clean up", func() {
   376  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   377  
   378  				var rpcwrperreq rpcwrapper.Request
   379  				var rpcwrperres rpcwrapper.Response
   380  
   381  				rpcwrperreq.Payload = initTestEnfReqPayload()
   382  
   383  				mockEnf.EXPECT().Run(server.ctx).Return(nil)
   384  				mockStats.EXPECT().Run(server.ctx).Return(nil)
   385  				mockSupevisor.EXPECT().Run(server.ctx).Return(fmt.Errorf("supervisor run"))
   386  				mockSupevisor.EXPECT().CleanUp()
   387  				mockEnf.EXPECT().CleanUp()
   388  
   389  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   390  
   391  				Convey("Then I should get error", func() {
   392  					So(err, ShouldNotBeNil)
   393  					So(err, ShouldResemble, errors.New("supervisor run"))
   394  				})
   395  			})
   396  
   397  			Convey("When i try to instantiate the enforcer and reports Client fails to run it should cleanup", func() {
   398  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   399  
   400  				var rpcwrperreq rpcwrapper.Request
   401  				var rpcwrperres rpcwrapper.Response
   402  
   403  				rpcwrperreq.Payload = initTestEnfReqPayload()
   404  
   405  				mockEnf.EXPECT().Run(server.ctx).Return(nil)
   406  				mockStats.EXPECT().Run(server.ctx).Return(nil)
   407  				mockSupevisor.EXPECT().Run(server.ctx).Return(nil)
   408  				mockReports.EXPECT().Run(server.ctx).Return(errors.New("failed to run counterclient"))
   409  				mockSupevisor.EXPECT().CleanUp()
   410  				mockEnf.EXPECT().CleanUp()
   411  
   412  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   413  
   414  				Convey("Then I should get error", func() {
   415  					So(err, ShouldNotBeNil)
   416  					So(err, ShouldResemble, errors.New("ReportsClientfailed to run counterclient"))
   417  				})
   418  
   419  			})
   420  			Convey("When I try to instantiate the enforcer and it succeeds it should not error", func() {
   421  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), os.Getenv(constants.EnvStatsSecret)).Times(1).Return(true)
   422  
   423  				var rpcwrperreq rpcwrapper.Request
   424  				var rpcwrperres rpcwrapper.Response
   425  
   426  				rpcwrperreq.Payload = initTestEnfReqPayload()
   427  
   428  				mockEnf.EXPECT().Run(server.ctx).Return(nil)
   429  				mockStats.EXPECT().Run(server.ctx).Return(nil)
   430  				mockSupevisor.EXPECT().Run(server.ctx).Return(nil)
   431  				mockReports.EXPECT().Run(server.ctx).Return(nil)
   432  				mockTokenClient.EXPECT().Run(server.ctx).Return(nil)
   433  				err := server.InitEnforcer(rpcwrperreq, &rpcwrperres)
   434  
   435  				Convey("Then I should not get error", func() {
   436  					So(err, ShouldBeNil)
   437  				})
   438  			})
   439  
   440  		})
   441  	})
   442  }
   443  
   444  func TestEnforce(t *testing.T) {
   445  	ctrl := gomock.NewController(t)
   446  	defer ctrl.Finish()
   447  
   448  	Convey("When I try to retrieve rpc server handle", t, func() {
   449  		rpcHdl := mockrpcwrapper.NewMockRPCServer(ctrl)
   450  		mockEnf := mockenforcer.NewMockEnforcer(ctrl)
   451  		mockSup := mocksupervisor.NewMockSupervisor(ctrl)
   452  		ctx, cancel := context.WithCancel(context.TODO())
   453  
   454  		Convey("When I try to create new server with env set", func() {
   455  
   456  			server := &RemoteEnforcer{
   457  				rpcHandle:  rpcHdl,
   458  				supervisor: mockSup,
   459  				enforcer:   mockEnf,
   460  				ctx:        ctx,
   461  				cancel:     cancel,
   462  			}
   463  
   464  			Convey("When I try to send enforce command with invalid secret", func() {
   465  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(false)
   466  				var rpcwrperreq rpcwrapper.Request
   467  				var rpcwrperres rpcwrapper.Response
   468  
   469  				rpcwrperreq.HashAuth = []byte{0xDE, 0xBD, 0x1C, 0x6A, 0x2A, 0x51, 0xC0, 0x02, 0x4B, 0xD7, 0xD1, 0x82, 0x78, 0x8A, 0xC4, 0xF1, 0xBE, 0xBF, 0x00, 0x89, 0x47, 0x0F, 0x13, 0x71, 0xAB, 0x4C, 0x0D, 0xD9, 0x9D, 0x85, 0x45, 0x04}
   470  				rpcwrperreq.Payload = initTestEnfPayload()
   471  				rpcwrperres.Status = ""
   472  
   473  				digest := hmac.New(sha256.New, []byte("InvalidSecret"))
   474  				if _, err := digest.Write(getHash(rpcwrperreq.Payload)); err != nil {
   475  					So(err, ShouldBeNil)
   476  				}
   477  				rpcwrperreq.HashAuth = digest.Sum(nil)
   478  				server.enforcer = mockEnf
   479  
   480  				err := server.Enforce(rpcwrperreq, &rpcwrperres)
   481  
   482  				Convey("Then I should get error", func() {
   483  					So(err, ShouldNotBeNil)
   484  					So(err, ShouldResemble, errors.New("enforce message auth failed"))
   485  				})
   486  			})
   487  
   488  			Convey("When I try to send enforce command with wrong payload it should fail", func() {
   489  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   490  				var rpcwrperreq rpcwrapper.Request
   491  				var rpcwrperres rpcwrapper.Response
   492  
   493  				rpcwrperreq.Payload = initTestEnfReqPayload()
   494  
   495  				err := server.Enforce(rpcwrperreq, &rpcwrperres)
   496  
   497  				Convey("Then I should get error", func() {
   498  					So(err, ShouldNotBeNil)
   499  					So(err, ShouldResemble, errors.New("invalid enforcer payload"))
   500  				})
   501  			})
   502  
   503  			Convey("When I try to send enforce command and the supervisor is nil, it should fail", func() {
   504  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   505  				var rpcwrperreq rpcwrapper.Request
   506  				var rpcwrperres rpcwrapper.Response
   507  
   508  				rpcwrperreq.Payload = initTestEnfPayload()
   509  				server.supervisor = nil
   510  
   511  				err := server.Enforce(rpcwrperreq, &rpcwrperres)
   512  
   513  				Convey("Then I should get error", func() {
   514  					So(err, ShouldNotBeNil)
   515  					So(err, ShouldResemble, errors.New("enforcer not initialized - cannot enforce"))
   516  				})
   517  			})
   518  
   519  			Convey("When I try to send enforce command and the supervisor fails, it should fail and cleanup", func() {
   520  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   521  				mockSup.EXPECT().Supervise(gomock.Any(), gomock.Any()).Return(fmt.Errorf("supervisor error"))
   522  				mockSup.EXPECT().CleanUp()
   523  				mockEnf.EXPECT().CleanUp()
   524  
   525  				var rpcwrperreq rpcwrapper.Request
   526  				var rpcwrperres rpcwrapper.Response
   527  
   528  				rpcwrperreq.Payload = initTestEnfPayload()
   529  
   530  				err := server.Enforce(rpcwrperreq, &rpcwrperres)
   531  
   532  				Convey("Then I should get error", func() {
   533  					So(err, ShouldNotBeNil)
   534  					So(err, ShouldResemble, errors.New("supervisor error"))
   535  				})
   536  			})
   537  
   538  			Convey("When I try to send enforce command and the enforcer fails, it should fail and cleanup", func() {
   539  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   540  				mockSup.EXPECT().Supervise(gomock.Any(), gomock.Any()).Return(nil)
   541  				mockEnf.EXPECT().Enforce(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("enforcer error"))
   542  				mockSup.EXPECT().CleanUp()
   543  				mockEnf.EXPECT().CleanUp()
   544  
   545  				var rpcwrperreq rpcwrapper.Request
   546  				var rpcwrperres rpcwrapper.Response
   547  
   548  				rpcwrperreq.Payload = initTestEnfPayload()
   549  
   550  				err := server.Enforce(rpcwrperreq, &rpcwrperres)
   551  
   552  				Convey("Then I should get error", func() {
   553  					So(err, ShouldNotBeNil)
   554  					So(err, ShouldResemble, errors.New("enforcer error"))
   555  				})
   556  			})
   557  
   558  			Convey("When the enforce command succeeds, I should get no errors", func() {
   559  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   560  				mockSup.EXPECT().Supervise(gomock.Any(), gomock.Any()).Return(nil)
   561  				mockEnf.EXPECT().Enforce(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
   562  
   563  				var rpcwrperreq rpcwrapper.Request
   564  				var rpcwrperres rpcwrapper.Response
   565  
   566  				rpcwrperreq.Payload = initTestEnfPayload()
   567  
   568  				err := server.Enforce(rpcwrperreq, &rpcwrperres)
   569  
   570  				Convey("Then I should not get an error ", func() {
   571  					So(err, ShouldBeNil)
   572  				})
   573  			})
   574  		})
   575  	})
   576  }
   577  
   578  func Test_UnEnforce(t *testing.T) {
   579  	ctrl := gomock.NewController(t)
   580  	defer ctrl.Finish()
   581  
   582  	Convey("Given a new server", t, func() {
   583  		rpcHdl := mockrpcwrapper.NewMockRPCServer(ctrl)
   584  		mockEnf := mockenforcer.NewMockEnforcer(ctrl)
   585  		mockSup := mocksupervisor.NewMockSupervisor(ctrl)
   586  		mockStats := mockclient.NewMockReporter(ctrl)
   587  		ctx, cancel := context.WithCancel(context.TODO())
   588  
   589  		Convey("With proper initialization", func() {
   590  
   591  			server := &RemoteEnforcer{
   592  				rpcHandle:   rpcHdl,
   593  				supervisor:  mockSup,
   594  				enforcer:    mockEnf,
   595  				ctx:         ctx,
   596  				cancel:      cancel,
   597  				statsClient: mockStats,
   598  			}
   599  
   600  			Convey("When I try to send unenforce command with invalid secret", func() {
   601  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(false)
   602  				var rpcwrperreq rpcwrapper.Request
   603  				var rpcwrperres rpcwrapper.Response
   604  
   605  				rpcwrperreq.Payload = initTestUnEnfPayload()
   606  				rpcwrperres.Status = ""
   607  
   608  				err := server.Unenforce(rpcwrperreq, &rpcwrperres)
   609  
   610  				Convey("Then I should get error", func() {
   611  					So(err, ShouldNotBeNil)
   612  					So(err, ShouldResemble, errors.New("unenforce message auth failed"))
   613  				})
   614  			})
   615  
   616  			Convey("When I try to send unenforce command with wrong payload it should fail", func() {
   617  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   618  				mockStats.EXPECT().Send()
   619  				var rpcwrperreq rpcwrapper.Request
   620  				var rpcwrperres rpcwrapper.Response
   621  
   622  				rpcwrperreq.Payload = initTestEnfReqPayload()
   623  
   624  				err := server.Unenforce(rpcwrperreq, &rpcwrperres)
   625  
   626  				Convey("Then I should get error", func() {
   627  					So(err, ShouldNotBeNil)
   628  					So(err, ShouldResemble, errors.New("invalid unenforcer payload"))
   629  				})
   630  			})
   631  
   632  			Convey("When I try to send unenforce command and the supervisor fails, it should fail and cleanup", func() {
   633  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   634  				mockStats.EXPECT().Send()
   635  				mockSup.EXPECT().Unsupervise(gomock.Any()).Return(fmt.Errorf("supervisor error"))
   636  				mockSup.EXPECT().CleanUp()
   637  				mockEnf.EXPECT().CleanUp()
   638  
   639  				var rpcwrperreq rpcwrapper.Request
   640  				var rpcwrperres rpcwrapper.Response
   641  
   642  				rpcwrperreq.Payload = initTestUnEnfPayload()
   643  
   644  				err := server.Unenforce(rpcwrperreq, &rpcwrperres)
   645  
   646  				Convey("Then I should get error", func() {
   647  					So(err, ShouldNotBeNil)
   648  					So(err, ShouldResemble, errors.New("unable to clean supervisor: supervisor error"))
   649  				})
   650  			})
   651  
   652  			Convey("When I try to send unenforce command and the enforcer fails, it should fail and cleanup", func() {
   653  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   654  				mockStats.EXPECT().Send()
   655  				mockSup.EXPECT().Unsupervise(gomock.Any()).Return(nil)
   656  				mockEnf.EXPECT().Unenforce(gomock.Any(), gomock.Any()).Return(fmt.Errorf("enforcer error"))
   657  				mockSup.EXPECT().CleanUp()
   658  				mockEnf.EXPECT().CleanUp()
   659  
   660  				var rpcwrperreq rpcwrapper.Request
   661  				var rpcwrperres rpcwrapper.Response
   662  
   663  				rpcwrperreq.Payload = initTestUnEnfPayload()
   664  
   665  				err := server.Unenforce(rpcwrperreq, &rpcwrperres)
   666  
   667  				Convey("Then I should get error", func() {
   668  					So(err, ShouldNotBeNil)
   669  					So(err, ShouldResemble, errors.New("unable to stop enforcer: enforcer error"))
   670  				})
   671  			})
   672  
   673  			Convey("When the enforce command succeeds, I should get no errors", func() {
   674  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   675  				mockStats.EXPECT().Send()
   676  				mockSup.EXPECT().Unsupervise(gomock.Any()).Return(nil)
   677  				mockEnf.EXPECT().Unenforce(gomock.Any(), gomock.Any()).Return(nil)
   678  
   679  				var rpcwrperreq rpcwrapper.Request
   680  				var rpcwrperres rpcwrapper.Response
   681  
   682  				rpcwrperreq.Payload = initTestUnEnfPayload()
   683  
   684  				err := server.Unenforce(rpcwrperreq, &rpcwrperres)
   685  
   686  				Convey("Then I should not get an error ", func() {
   687  					So(err, ShouldBeNil)
   688  				})
   689  			})
   690  		})
   691  	})
   692  }
   693  
   694  func Test_EnableDatapathPacketTracing(t *testing.T) {
   695  	ctrl := gomock.NewController(t)
   696  	defer ctrl.Finish()
   697  
   698  	Convey("Given a new server", t, func() {
   699  		rpcHdl := mockrpcwrapper.NewMockRPCServer(ctrl)
   700  		mockEnf := mockenforcer.NewMockEnforcer(ctrl)
   701  		ctx, cancel := context.WithCancel(context.TODO())
   702  
   703  		Convey("With proper initialization", func() {
   704  
   705  			server := &RemoteEnforcer{
   706  				rpcHandle: rpcHdl,
   707  				enforcer:  mockEnf,
   708  				ctx:       ctx,
   709  				cancel:    cancel,
   710  			}
   711  
   712  			Convey("When I try to enable datapath tracing and the validity fails, it should fail", func() {
   713  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(false)
   714  				var rpcwrperreq rpcwrapper.Request
   715  				var rpcwrperres rpcwrapper.Response
   716  
   717  				rpcwrperreq.Payload = rpcwrapper.EnableDatapathPacketTracingPayLoad{}
   718  				rpcwrperres.Status = ""
   719  
   720  				err := server.EnableDatapathPacketTracing(rpcwrperreq, &rpcwrperres)
   721  
   722  				Convey("Then I should get error", func() {
   723  					So(err, ShouldNotBeNil)
   724  					So(err, ShouldResemble, errors.New("enable datapath packet tracing auth failed"))
   725  				})
   726  			})
   727  
   728  			Convey("When I try to enable datapath tracing  and the enforcer fails, it should fail and cleanup", func() {
   729  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   730  				mockEnf.EXPECT().EnableDatapathPacketTracing(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("error"))
   731  
   732  				var rpcwrperreq rpcwrapper.Request
   733  				var rpcwrperres rpcwrapper.Response
   734  
   735  				rpcwrperreq.Payload = rpcwrapper.EnableDatapathPacketTracingPayLoad{}
   736  
   737  				err := server.EnableDatapathPacketTracing(rpcwrperreq, &rpcwrperres)
   738  
   739  				Convey("Then I should get error", func() {
   740  					So(err, ShouldNotBeNil)
   741  					So(err, ShouldResemble, errors.New("error"))
   742  				})
   743  			})
   744  
   745  			Convey("When the enforce command succeeds, I should get no errors", func() {
   746  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   747  				mockEnf.EXPECT().EnableDatapathPacketTracing(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
   748  
   749  				var rpcwrperreq rpcwrapper.Request
   750  				var rpcwrperres rpcwrapper.Response
   751  
   752  				rpcwrperreq.Payload = rpcwrapper.EnableDatapathPacketTracingPayLoad{}
   753  
   754  				err := server.EnableDatapathPacketTracing(rpcwrperreq, &rpcwrperres)
   755  
   756  				Convey("Then I should not get an error ", func() {
   757  					So(err, ShouldBeNil)
   758  				})
   759  			})
   760  		})
   761  	})
   762  }
   763  
   764  func Test_EnableIPTablesPacketTracing(t *testing.T) {
   765  	ctrl := gomock.NewController(t)
   766  	defer ctrl.Finish()
   767  
   768  	Convey("Given a new server", t, func() {
   769  		rpcHdl := mockrpcwrapper.NewMockRPCServer(ctrl)
   770  		mockSup := mocksupervisor.NewMockSupervisor(ctrl)
   771  		ctx, cancel := context.WithCancel(context.TODO())
   772  
   773  		Convey("With proper initialization", func() {
   774  
   775  			server := &RemoteEnforcer{
   776  				rpcHandle:  rpcHdl,
   777  				supervisor: mockSup,
   778  				ctx:        ctx,
   779  				cancel:     cancel,
   780  			}
   781  
   782  			Convey("When I try to enable datapath tracing and the validity fails, it should fail", func() {
   783  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(false)
   784  				var rpcwrperreq rpcwrapper.Request
   785  				var rpcwrperres rpcwrapper.Response
   786  
   787  				rpcwrperreq.Payload = rpcwrapper.EnableIPTablesPacketTracingPayLoad{}
   788  				rpcwrperres.Status = ""
   789  
   790  				err := server.EnableIPTablesPacketTracing(rpcwrperreq, &rpcwrperres)
   791  
   792  				Convey("Then I should get error", func() {
   793  					So(err, ShouldNotBeNil)
   794  					So(err, ShouldResemble, errors.New("enable iptable packet tracing auth failed"))
   795  				})
   796  			})
   797  
   798  			Convey("When I try to enable datapath tracing  and the enforcer fails, it should fail and cleanup", func() {
   799  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   800  				mockSup.EXPECT().EnableIPTablesPacketTracing(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("error"))
   801  
   802  				var rpcwrperreq rpcwrapper.Request
   803  				var rpcwrperres rpcwrapper.Response
   804  
   805  				rpcwrperreq.Payload = rpcwrapper.EnableIPTablesPacketTracingPayLoad{}
   806  
   807  				err := server.EnableIPTablesPacketTracing(rpcwrperreq, &rpcwrperres)
   808  
   809  				Convey("Then I should get error", func() {
   810  					So(err, ShouldNotBeNil)
   811  					So(err, ShouldResemble, errors.New("error"))
   812  				})
   813  			})
   814  
   815  			Convey("When the enforce command succeeds, I should get no errors", func() {
   816  				rpcHdl.EXPECT().CheckValidity(gomock.Any(), gomock.Any()).Times(1).Return(true)
   817  				mockSup.EXPECT().EnableIPTablesPacketTracing(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
   818  
   819  				var rpcwrperreq rpcwrapper.Request
   820  				var rpcwrperres rpcwrapper.Response
   821  
   822  				rpcwrperreq.Payload = rpcwrapper.EnableIPTablesPacketTracingPayLoad{}
   823  
   824  				err := server.EnableIPTablesPacketTracing(rpcwrperreq, &rpcwrperres)
   825  
   826  				Convey("Then I should not get an error ", func() {
   827  					So(err, ShouldBeNil)
   828  				})
   829  			})
   830  		})
   831  	})
   832  }