github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/applicationproxy/serviceregistry/serviceregistry_test.go (about) 1 // +build !windows 2 3 package serviceregistry 4 5 import ( 6 "net" 7 "testing" 8 "time" 9 10 . "github.com/smartystreets/goconvey/convey" 11 triremecommon "go.aporeto.io/enforcerd/trireme-lib/common" 12 "go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/applicationproxy/common" 13 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/pucontext" 14 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets" 15 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets/testhelper" 16 "go.aporeto.io/enforcerd/trireme-lib/policy" 17 "go.aporeto.io/enforcerd/trireme-lib/utils/portspec" 18 ) 19 20 func newBaseApplicationServices(exposedPortValue, publicPortValue, privatePortValue, dependentPortValue uint16) (*policy.ApplicationService, *policy.ApplicationService) { 21 22 exposed1 := "10.1.1.0/24" 23 exposed2 := "20.1.1.0/24" 24 public1 := "30.1.1.0/24" 25 public2 := "40.1.1.0/24" 26 dependent1 := "50.1.1.0/24" 27 dependent2 := "60.1.1.0/24" 28 29 exposedPort, err := portspec.NewPortSpec(exposedPortValue, exposedPortValue, nil) 30 So(err, ShouldBeNil) 31 publicPort, err := portspec.NewPortSpec(publicPortValue, publicPortValue, nil) 32 So(err, ShouldBeNil) 33 privatePort, err := portspec.NewPortSpec(privatePortValue, privatePortValue, nil) 34 So(err, ShouldBeNil) 35 dependentPort, err := portspec.NewPortSpec(dependentPortValue, dependentPortValue, nil) 36 So(err, ShouldBeNil) 37 38 return &policy.ApplicationService{ 39 ID: "policyExposed", 40 NetworkInfo: &triremecommon.Service{ 41 Ports: exposedPort, 42 Protocol: 6, 43 Addresses: map[string]struct{}{exposed1: struct{}{}, exposed2: struct{}{}}, 44 }, 45 PublicNetworkInfo: &triremecommon.Service{ 46 Ports: publicPort, 47 Protocol: 6, 48 Addresses: map[string]struct{}{public1: struct{}{}}, 49 }, 50 PrivateNetworkInfo: &triremecommon.Service{ 51 Ports: privatePort, 52 Protocol: 6, 53 Addresses: map[string]struct{}{}, 54 }, 55 Type: policy.ServiceHTTP, 56 PublicServiceTLSType: policy.ServiceTLSTypeAporeto, 57 }, 58 &policy.ApplicationService{ 59 ID: "policyDepend", 60 NetworkInfo: &triremecommon.Service{ 61 Ports: dependentPort, 62 Protocol: 6, 63 FQDNs: []string{"www.google.com"}, 64 Addresses: map[string]struct{}{ 65 dependent1: struct{}{}, 66 dependent2: struct{}{}, 67 }, 68 }, 69 PublicNetworkInfo: &triremecommon.Service{ 70 Ports: publicPort, 71 Protocol: 6, 72 Addresses: map[string]struct{}{public2: struct{}{}}, 73 }, 74 PrivateNetworkInfo: &triremecommon.Service{ 75 Ports: privatePort, 76 Protocol: 6, 77 Addresses: map[string]struct{}{}, 78 }, 79 Type: policy.ServiceHTTP, 80 PublicServiceTLSType: policy.ServiceTLSTypeAporeto, 81 } 82 } 83 84 func newPU(name string, exposedPort, publicPort, privatePort, dependentPort uint16, doubleExposed, doubleDependent bool) (*policy.PUInfo, *pucontext.PUContext, secrets.Secrets) { 85 exposed, dependent := newBaseApplicationServices(exposedPort, publicPort, privatePort, dependentPort) 86 87 exposedServices := policy.ApplicationServicesList{exposed} 88 if doubleExposed { 89 exposedServices = append(exposedServices, exposed) 90 } 91 92 dependentServices := policy.ApplicationServicesList{dependent} 93 if doubleDependent { 94 dependentServices = append(dependentServices, dependent) 95 } 96 plc := policy.NewPUPolicy( 97 name+"-policyid1", 98 "/ns1", 99 policy.Police, 100 policy.IPRuleList{}, 101 policy.IPRuleList{}, 102 policy.DNSRuleList{}, 103 policy.TagSelectorList{}, 104 policy.TagSelectorList{}, 105 policy.NewTagStore(), 106 policy.NewTagStoreFromSlice([]string{"app=web", "type=aporeto"}), 107 nil, 108 nil, 109 0, 110 0, 111 exposedServices, 112 dependentServices, 113 []string{}, 114 policy.EnforcerMapping, 115 policy.Reject|policy.Log, 116 policy.Reject|policy.Log, 117 ) 118 119 puInfo := policy.NewPUInfo(name, "/ns1", triremecommon.ContainerPU) 120 puInfo.Policy = plc 121 pctx, err := pucontext.NewPU(name, puInfo, nil, time.Second*1000) 122 So(err, ShouldBeNil) 123 _, s, _ := testhelper.NewTestCompactPKISecrets() 124 return puInfo, pctx, s 125 } 126 127 func TestRegister(t *testing.T) { 128 Convey("Given a new registry", t, func() { 129 r := Instance() 130 Convey("When I register a new PU with no services", func() { 131 puInfo, pctx, s := newPU("pu1", 8080, 443, 80, 8080, false, false) 132 sctx, err := r.Register("pu1", puInfo, pctx, s) 133 Convey("The data structures should be correct and I should be able to retrieve the service", func() { 134 So(err, ShouldBeNil) 135 So(sctx, ShouldNotBeNil) 136 So(sctx.PU, ShouldResemble, puInfo) 137 So(sctx.PUContext, ShouldResemble, pctx) 138 So(sctx.dependentServiceCache, ShouldNotBeNil) 139 }) 140 Convey("And I should be able to retrieve the services using the three provided methods", func() { 141 serviceContext, rerr := r.RetrieveServiceByID("pu1") 142 So(rerr, ShouldBeNil) 143 So(serviceContext, ShouldNotBeNil) 144 So(serviceContext, ShouldResemble, sctx) 145 146 portContext, perr := r.RetrieveExposedServiceContext(net.ParseIP("10.1.1.1").To4(), 80, "") 147 So(perr, ShouldBeNil) 148 So(portContext, ShouldNotBeNil) 149 So(portContext.ID, ShouldResemble, "pu1") 150 So(portContext.TargetPort, ShouldEqual, 80) 151 So(portContext.Service, ShouldResemble, puInfo.Policy.ExposedServices()[0]) 152 So(portContext.Type, ShouldEqual, common.HTTPSNetwork) 153 154 }) 155 Convey("Update the dependent services by fqdn, and it should be able to find", func() { 156 for _, dependentService := range pctx.DependentServices("www.google.com") { 157 dependentService.NetworkInfo.Addresses["4.4.4.4/32"] = struct{}{} 158 } 159 160 err := r.UpdateDependentServicesByID("pu1") 161 So(err, ShouldBeNil) 162 163 _, _, err = r.RetrieveDependentServiceDataByIDAndNetwork("pu1", net.ParseIP("4.4.4.4").To4(), 8080, "") 164 So(err, ShouldBeNil) 165 }) 166 Convey("But I should get errors for non existing ports or services", func() { 167 serviceContext, rerr := r.RetrieveServiceByID("badpu") 168 So(rerr, ShouldNotBeNil) 169 So(serviceContext, ShouldBeNil) 170 171 portContext, perr := r.RetrieveExposedServiceContext(net.ParseIP("100.1.1.1").To4(), 100, "") 172 So(perr, ShouldNotBeNil) 173 So(portContext, ShouldBeNil) 174 }) 175 176 Convey("When I register a second service with no overlaps", func() { 177 puInfo, pctx, s := newPU("pu2", 8000, 4443, 8080, 10000, false, false) 178 sctx, err := r.Register("pu2", puInfo, pctx, s) 179 So(err, ShouldBeNil) 180 So(sctx, ShouldNotBeNil) 181 182 Convey("And I should be able to retrieve the updated services using the three provided methods", func() { 183 serviceContext, rerr := r.RetrieveServiceByID("pu2") 184 So(rerr, ShouldBeNil) 185 So(serviceContext, ShouldNotBeNil) 186 So(serviceContext, ShouldResemble, sctx) 187 188 portContext, perr := r.RetrieveExposedServiceContext(net.ParseIP("10.1.1.1").To4(), 8080, "") 189 So(perr, ShouldBeNil) 190 So(portContext, ShouldNotBeNil) 191 So(portContext.ID, ShouldResemble, "pu2") 192 So(portContext.TargetPort, ShouldEqual, 8080) 193 So(portContext.Service, ShouldResemble, puInfo.Policy.ExposedServices()[0]) 194 So(portContext.Type, ShouldEqual, common.HTTPSNetwork) 195 }) 196 }) 197 198 Convey("When I register a second service with port overlaps, I should get errors", func() { 199 // exposedService overlap 200 puInfo, pctx, s := newPU("pu2", 8080, 4443, 8080, 10000, true, false) 201 sctx, err := r.Register("pu2", puInfo, pctx, s) 202 So(err, ShouldNotBeNil) 203 So(sctx, ShouldBeNil) 204 205 // dependentService overlap 206 puInfo, pctx, s = newPU("pu2", 8080, 4443, 8080, 10000, false, true) 207 sctx, err = r.Register("pu2", puInfo, pctx, s) 208 So(err, ShouldNotBeNil) 209 So(sctx, ShouldBeNil) 210 211 // both overlaps 212 puInfo, pctx, s = newPU("pu2", 8080, 4443, 8080, 10000, true, true) 213 sctx, err = r.Register("pu2", puInfo, pctx, s) 214 So(err, ShouldNotBeNil) 215 So(sctx, ShouldBeNil) 216 217 }) 218 219 Convey("When I re-register the service with updates on the ports", func() { 220 puInfo, pctx, s := newPU("pu1", 8000, 4443, 8080, 10000, false, false) 221 sctx, err := r.Register("pu1", puInfo, pctx, s) 222 So(err, ShouldBeNil) 223 So(sctx, ShouldNotBeNil) 224 225 Convey("And I should be able to retrieve the updated services using the three provided methods", func() { 226 serviceContext, rerr := r.RetrieveServiceByID("pu1") 227 So(rerr, ShouldBeNil) 228 So(serviceContext, ShouldNotBeNil) 229 So(serviceContext, ShouldResemble, sctx) 230 231 portContext, perr := r.RetrieveExposedServiceContext(net.ParseIP("10.1.1.1").To4(), 8080, "") 232 So(perr, ShouldBeNil) 233 So(portContext, ShouldNotBeNil) 234 So(portContext.ID, ShouldResemble, "pu1") 235 So(portContext.TargetPort, ShouldEqual, 8080) 236 So(portContext.Service, ShouldResemble, puInfo.Policy.ExposedServices()[0]) 237 So(portContext.Type, ShouldEqual, common.HTTPSNetwork) 238 }) 239 }) 240 241 Convey("When I unregister the service, it should be deleted", func() { 242 uerr := r.Unregister("pu1") 243 So(uerr, ShouldBeNil) 244 retrievedContext, rerr := r.RetrieveServiceByID("pu1") 245 So(rerr, ShouldNotBeNil) 246 So(retrievedContext, ShouldBeNil) 247 portContext, perr := r.RetrieveExposedServiceContext(net.ParseIP("10.1.1.1").To4(), 80, "") 248 So(perr, ShouldNotBeNil) 249 So(portContext, ShouldBeNil) 250 }) 251 }) 252 }) 253 } 254 255 func TestServiceTypeToNetworkListenerType(t *testing.T) { 256 Convey("When I convert a network HTTP service it should be HTTPNetwork", t, func() { 257 t := serviceTypeToNetworkListenerType(policy.ServiceHTTP, true) 258 So(t, ShouldEqual, common.HTTPNetwork) 259 }) 260 Convey("When I convert a network HTTPS service it should be HTTPSNetwork", t, func() { 261 t := serviceTypeToNetworkListenerType(policy.ServiceHTTP, false) 262 So(t, ShouldEqual, common.HTTPSNetwork) 263 }) 264 Convey("When I convert a TCP service it should be TCPNetwork", t, func() { 265 t := serviceTypeToNetworkListenerType(policy.ServiceTCP, false) 266 So(t, ShouldEqual, common.TCPNetwork) 267 }) 268 } 269 270 func TestServiceTypeToApplicationListenerType(t *testing.T) { 271 Convey("When I convert an application HTTP service it should be HTTPApplication", t, func() { 272 t := serviceTypeToApplicationListenerType(policy.ServiceHTTP) 273 So(t, ShouldEqual, common.HTTPApplication) 274 }) 275 Convey("When I convert an application TCP service it should be TCPApplication", t, func() { 276 t := serviceTypeToApplicationListenerType(policy.ServiceTCP) 277 So(t, ShouldEqual, common.TCPApplication) 278 }) 279 }