func TestPodUsesNonExistingService(t *testing.T) { kube := mocks.NewKubeClient() client := new(contrail_mocks.ApiClient) client.Init() client.AddInterceptor("virtual-machine-interface", &VmiInterceptor{}) client.AddInterceptor("virtual-network", &NetworkInterceptor{}) allocator := new(mocks.AddressAllocator) controller := NewTestController(kube, client, allocator, nil) pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz1", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "name": "testpod", "uses": "nonexisting", }, }, } netnsProject := new(types.Project) netnsProject.SetFQName("", []string{"default-domain", "testns"}) client.Create(netnsProject) allocator.On("LocateIpAddress", string(pod1.ObjectMeta.UID)).Return("10.0.0.1", nil) allocator.On("ReleaseIpAddress", string(pod1.ObjectMeta.UID)).Return() kube.PodInterface.On("Update", pod1).Return(pod1, nil) shutdown := make(chan struct{}) go controller.Run(shutdown) controller.AddPod(pod1) time.Sleep(100 * time.Millisecond) _, err := types.NetworkPolicyByName(client, "default-domain:testns:nonexisting") assert.NoError(t, err) _, err = types.VirtualNetworkByName(client, "default-domain:testns:testpod") assert.NoError(t, err) controller.DeletePod(pod1) time.Sleep(100 * time.Millisecond) type shutdownMsg struct { } shutdown <- shutdownMsg{} _, err = types.VirtualNetworkByName(client, "default-domain:testns:testpod") assert.Error(t, err) _, err = types.NetworkPolicyByName(client, "default-domain:testns:nonexisting") assert.Error(t, err) allocator.AssertExpectations(t) }
func (m *NetworkManagerImpl) disconnectNetworkFromPolicy(policy *types.NetworkPolicy, targetCSN string) error { target, err := types.VirtualNetworkByName(m.client, targetCSN) if err != nil { return err } err = target.DeleteNetworkPolicy(policy.GetUuid()) if err != nil { return err } return m.client.Update(target) }
// global networks can be created externally. Attached the network to the respective policy in case // the policy was created first. func (c *consistencyChecker) globalNetworkChecker() bool { success := true for _, gbl := range c.config.GlobalNetworks { network, err := types.VirtualNetworkByName(c.client, gbl) if err != nil { glog.V(5).Infof("Network %s: %v", gbl, err) continue } if !c.globalNetworkCheckPolicyAttachment(network) { success = false } } return success }
func getNetworkServiceConnections(t *testing.T, client contrail.ApiClient, config *Config, namespace, networkName string) []string { network, err := types.VirtualNetworkByName(client, strings.Join([]string{config.DefaultDomain, namespace, networkName}, ":")) require.NoError(t, err) policyRefs, err := network.GetNetworkPolicyRefs() require.NoError(t, err) serviceList := make([]string, 0, len(policyRefs)) for _, ref := range policyRefs { svc, err := serviceNameFromPolicyName(ref.To[2]) if err != nil { continue } serviceList = append(serviceList, svc) } return serviceList }
// Connect creates a network-policy and corresponding policy rule (when they do not exist) in order to // connect the source network with the target. The target network may or not exist yet. func (m *NetworkManagerImpl) Connect(network *types.VirtualNetwork, targetCSN string) error { targetName := strings.Split(targetCSN, ":") policy, err := m.locatePolicy(targetName) if err != nil { return err } policyAttach(m.client, network, policy) target, err := types.VirtualNetworkByName(m.client, targetCSN) if err == nil { err = policyAttach(m.client, target, policy) if err != nil { glog.Error(err) } } err = policyLocateRuleByFQN(m.client, policy, network.GetFQName(), targetName) if err != nil { return err } return nil }
func (c *consistencyChecker) NetworkChecker(connections networkConnectionMap) bool { lastPolicyMap := c.gcPolicyMap c.gcPolicyMap = make(networkConnectionMap, 0) var kubeNetworks sort.StringSlice connectionCheck := true for k, v := range connections { kubeNetworks = append(kubeNetworks, k) if c.serviceMgr == nil { continue } network, err := types.VirtualNetworkByName(c.client, k) if err != nil { glog.Error(err) continue } // State policy references are removed if they are found to be stale in // two successive cycles. c.serviceMgr.PurgeStalePolicyRefs(network, v, func(namespace, service string) bool { networkName := strings.Join(network.GetFQName(), ":") if entry, ok := lastPolicyMap[networkName]; ok { if entry.Contains(namespace, service) { glog.Infof("%s service connection %s/%s delete", networkName, namespace, service) connectionCheck = false return true } } var serviceList ServiceIdList if entry, ok := c.gcPolicyMap[networkName]; ok { serviceList = entry } else { serviceList = MakeServiceIdList() } glog.Infof("%s service connection %s/%s not used by pod specifications", networkName, namespace, service) serviceList.Add(namespace, service) c.gcPolicyMap[networkName] = serviceList connectionCheck = false return false }) } // consider service networks. c.addServiceNetworks(&kubeNetworks) kubeNetworks.Sort() var dbNetworks sort.StringSlice elements, err := c.client.List("virtual-network") if err != nil { glog.Error(err) return false } for _, ref := range elements { networkName := strings.Join(ref.Fq_name, ":") if networkName == c.config.PublicNetwork { continue } if isSystemDefaultNetwork(networkName) { continue } dbNetworks = append(dbNetworks, networkName) } dbNetworks.Sort() cmp := CompareSortedLists(kubeNetworks, dbNetworks, func(key string) { glog.Errorf("network %s not present in opencontrail db", key) }, func(key string) { glog.Errorf("network %s not used by kubernetes", key) if c.serviceMgr == nil { return } network, err := types.VirtualNetworkByName(c.client, key) if err != nil { glog.Error(err) return } c.serviceMgr.PurgeStalePolicyRefs(network, MakeServiceIdList(), func(string, string) bool { return true }) }, func(key string) bool { return true }) return connectionCheck && cmp }
func (c *consistencyChecker) NetworkChecker(connections networkServiceMap) bool { lastPolicyMap := c.staleConnectionMap c.staleConnectionMap = make(networkConnectionMap, 0) var kubeNetworks sort.StringSlice connectionCheck := true for k, v := range connections { kubeNetworks = append(kubeNetworks, k) if c.serviceMgr == nil { continue } network, err := types.VirtualNetworkByName(c.client, k) if err != nil { glog.Error(err) continue } status, err := c.networkEvalPolicyRefs(network, v, lastPolicyMap) if err != nil { glog.Error(err) continue } if !status { connectionCheck = false } } // consider service networks. c.addServiceNetworks(&kubeNetworks) kubeNetworks.Sort() var dbNetworks sort.StringSlice elements, err := c.client.List("virtual-network") if err != nil { glog.Error(err) return false } for _, ref := range elements { networkName := strings.Join(ref.Fq_name, ":") if networkName == c.config.PublicNetwork { continue } if isSystemDefaultNetwork(networkName) { continue } dbNetworks = append(dbNetworks, networkName) } dbNetworks.Sort() cmp := CompareSortedLists(kubeNetworks, dbNetworks, func(key string) { glog.Errorf("network %s not present in opencontrail db", key) }, func(key string) { glog.Errorf("network %s not used by kubernetes", key) if c.serviceMgr == nil { return } network, err := types.VirtualNetworkByName(c.client, key) if err != nil { glog.Error(err) return } c.networkEvalPolicyRefs(network, MakeServiceIdList(), nil) }, func(key string) bool { return true }) return connectionCheck && cmp }
func TestServiceWithMultipleUsers(t *testing.T) { kube := mocks.NewKubeClient() client := new(contrail_mocks.ApiClient) client.Init() client.AddInterceptor("virtual-machine-interface", &VmiInterceptor{}) client.AddInterceptor("virtual-network", &NetworkInterceptor{}) allocator := new(mocks.AddressAllocator) controller := NewTestController(kube, client, allocator, nil) pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-server", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "name": "server", }, }, } pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz1", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "name": "client1", "uses": "x1", }, }, } pod3 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz2", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "name": "client1", "uses": "x1", }, }, } pod4 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz3", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "name": "client2", "uses": "x1", }, }, } service := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "s1", Namespace: "testns", Labels: map[string]string{ "name": "x1", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "name": "server", }, ClusterIP: "10.254.42.42", }, } netnsProject := new(types.Project) netnsProject.SetFQName("", []string{"default-domain", "testns"}) client.Create(netnsProject) allocator.On("LocateIpAddress", string(pod1.ObjectMeta.UID)).Return("10.0.0.1", nil) allocator.On("LocateIpAddress", string(pod2.ObjectMeta.UID)).Return("10.0.0.2", nil) allocator.On("LocateIpAddress", string(pod3.ObjectMeta.UID)).Return("10.0.0.3", nil) allocator.On("LocateIpAddress", string(pod4.ObjectMeta.UID)).Return("10.0.0.4", nil) allocator.On("ReleaseIpAddress", string(pod1.ObjectMeta.UID)).Return() allocator.On("ReleaseIpAddress", string(pod2.ObjectMeta.UID)).Return() allocator.On("ReleaseIpAddress", string(pod3.ObjectMeta.UID)).Return() allocator.On("ReleaseIpAddress", string(pod4.ObjectMeta.UID)).Return() kube.PodInterface.On("Update", pod1).Return(pod1, nil) kube.PodInterface.On("Update", pod2).Return(pod2, nil) kube.PodInterface.On("Update", pod3).Return(pod3, nil) kube.PodInterface.On("Update", pod4).Return(pod4, nil) kube.PodInterface.On("List", mock.Anything, mock.Anything).Return(&api.PodList{Items: []api.Pod{*pod1}}, nil) shutdown := make(chan struct{}) go controller.Run(shutdown) controller.AddPod(pod1) controller.AddService(service) controller.AddPod(pod2) controller.AddPod(pod3) controller.AddPod(pod4) time.Sleep(100 * time.Millisecond) policy, err := types.NetworkPolicyByName(client, "default-domain:testns:x1") assert.NoError(t, err) if err == nil { assert.Len(t, policy.GetNetworkPolicyEntries().PolicyRule, 2) assert.True(t, policyHasRule(policy, "default-domain:testns:client1", "default-domain:testns:service-x1")) assert.True(t, policyHasRule(policy, "default-domain:testns:client2", "default-domain:testns:service-x1")) } _, err = types.VirtualNetworkByName(client, "default-domain:testns:client2") assert.NoError(t, err) controller.DeletePod(pod3) time.Sleep(100 * time.Millisecond) policy, err = types.NetworkPolicyByName(client, "default-domain:testns:x1") assert.NoError(t, err) if err == nil { assert.Len(t, policy.GetNetworkPolicyEntries().PolicyRule, 2) } controller.DeletePod(pod4) time.Sleep(100 * time.Millisecond) _, err = types.VirtualNetworkByName(client, "default-domain:testns:client2") assert.Error(t, err) policy, err = types.NetworkPolicyByName(client, "default-domain:testns:x1") assert.NoError(t, err) if err == nil { assert.Len(t, policy.GetNetworkPolicyEntries().PolicyRule, 1) assert.True(t, policyHasRule(policy, "default-domain:testns:client1", "default-domain:testns:service-x1")) } controller.DeletePod(pod2) time.Sleep(100 * time.Millisecond) policy, err = types.NetworkPolicyByName(client, "default-domain:testns:x1") assert.NoError(t, err) if err == nil { assert.Len(t, policy.GetNetworkPolicyEntries().PolicyRule, 0) } controller.DeletePod(pod1) controller.DeleteService(service) time.Sleep(100 * time.Millisecond) type shutdownMsg struct { } shutdown <- shutdownMsg{} policy, err = types.NetworkPolicyByName(client, "default-domain:testns:x1") assert.Error(t, err) }