func TestNamespaceDelete(t *testing.T) { client := new(contrail_mocks.ApiClient) client.Init() allocator := new(mocks.AddressAllocator) networkMgr := new(mocks.NetworkManager) controller := NewTestController(nil, client, allocator, networkMgr) namespace := &api.Namespace{ ObjectMeta: api.ObjectMeta{ Name: "netns", UID: kubetypes.UID(uuid.New()), }, } project := new(types.Project) project.SetFQName("domain", []string{DefaultDomain, "netns"}) project.SetUuid(string(namespace.ObjectMeta.UID)) client.Create(project) shutdown := make(chan struct{}) go controller.Run(shutdown) controller.DeleteNamespace(namespace) time.Sleep(100 * time.Millisecond) type shutdownMsg struct { } shutdown <- shutdownMsg{} _, err := client.FindByUuid("project", string(namespace.ObjectMeta.UID)) assert.NotNil(t, err) }
func TestReadChildren(t *testing.T) { client := new(ApiClient) client.Init() project := new(types.Project) project.SetFQName("domain", []string{"default-domain", "p1"}) assert.NoError(t, client.Create(project)) net := new(types.VirtualNetwork) net.SetFQName("project", []string{"default-domain", "p1", "n1"}) assert.NoError(t, client.Create(net)) vmi1 := new(types.VirtualMachineInterface) vmi1.SetFQName("project", []string{"default-domain", "p1", "port1"}) vmi1.AddVirtualNetwork(net) assert.NoError(t, client.Create(vmi1)) vmi2 := new(types.VirtualMachineInterface) vmi2.SetFQName("project", []string{"default-domain", "p1", "port2"}) vmi2.AddVirtualNetwork(net) assert.NoError(t, client.Create(vmi2)) refs, err := project.GetVirtualMachineInterfaces() assert.NoError(t, err) assert.Len(t, refs, 2) }
func TestConsistencyStaleInterface(t *testing.T) { client := createTestClient() podStore := new(mocks.Store) serviceStore := new(mocks.Store) checker := NewConsistencyChecker(client, NewConfig(), podStore, serviceStore, nil) kube := mocks.NewKubeClient() controller := NewTestController(kube, client, nil, nil) netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) installPods(controller, &kube.PodInterface.Mock, &podStore.Mock, "testns", 3) shutdown := make(chan struct{}) go controller.Run(shutdown) time.Sleep(100 * time.Millisecond) type shutdownMsg struct { } shutdown <- shutdownMsg{} time.Sleep(100 * time.Millisecond) serviceStore.On("List").Return([]interface{}{}) assert.True(t, checker.Check()) vmi := new(types.VirtualMachineInterface) vmi.SetFQName("project", []string{"default-domain", "testns", "pod03"}) assert.NoError(t, client.Create(vmi)) assert.False(t, checker.Check()) }
func TestListByParent(t *testing.T) { client := new(ApiClient) client.Init() projectNames := []string{"p1", "p2", "p3"} vmNames := []string{"a", "b", "c", "d"} for _, projectName := range projectNames { project := new(types.Project) project.SetFQName("domain", []string{"default-domain", projectName}) assert.NoError(t, client.Create(project)) for _, vmName := range vmNames { vm := new(types.VirtualMachine) vm.SetFQName("project", []string{"default-domain", projectName, vmName}) assert.NoError(t, client.Create(vm)) } } elements, err := client.ListByParent("virtual-machine", "default-domain:p2") assert.NoError(t, err) for _, element := range elements { assert.Equal(t, "p2", element.Fq_name[1]) } }
func getNetworkUuidByName( client *contrail.Client, project_name, project_id, name string) ( string, error) { var fqn []string if len(project_id) > 0 { uuid := strings.ToLower(project_id) if !config.IsUuid(uuid) { fmt.Fprintf(os.Stderr, "Invalid project-id value: %s\n", uuid) os.Exit(2) } obj, err := client.FindByUuid("project", project_id) if err != nil { fmt.Fprint(os.Stderr, err) os.Exit(2) } fqn = obj.GetFQName() } else { fqn = strings.Split(project_name, ":") if len(fqn) == 1 { obj := new(types.Project) fqn = append(obj.GetDefaultParent(), project_name) } } fqn = append(fqn, name) return client.UuidByName("virtual-network", strings.Join(fqn, ":")) }
func TestClient(t *testing.T) { client := contrail.NewClient("localhost", 8082) elements, err := client.List("project") if err != nil { t.Fatal(err) } if len(elements) < 1 { t.Error("Empty project list") } for _, element := range elements { obj, err := client.ReadListResult("project", &element) if obj == nil { t.Fatal(err) } var project *types.Project = obj.(*types.Project) networks, err := project.GetVirtualNetworks() if len(networks) < 1 { t.Error("Empty virtual-network list") } for _, network := range networks { iObj, err := client.ReadReference( "virtual-network", &network) if iObj == nil { t.Fatal(err) } net := iObj.(*types.VirtualNetwork) fmt.Println(net.GetName()) } } }
func (m *ApiClient) Init() { m.db = NewInMemDatabase() m.updater = NewObjectUpdater(m.db) domain := new(types.Domain) domain.SetName("default-domain") err := m.Create(domain) if err != nil { panic(err.Error()) } project := new(types.Project) project.SetFQName("domain", []string{"default-domain", "default-project"}) err = m.Create(project) if err != nil { panic(err.Error()) } ipam := new(types.NetworkIpam) ipam.SetFQName("project", []string{"default-domain", "default-project", "default-network-ipam"}) err = m.Create(ipam) if err != nil { panic(err.Error()) } }
func TestConsistencyMissingInterface(t *testing.T) { env := new(TestFramework) env.SetUp("192.0.2.0/24") client := env.client netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) env.Start() installPods(env, "testns", 3) env.SyncBarrier() env.Shutdown() assert.True(t, env.checker.Check()) vmi, err := types.VirtualMachineInterfaceByName(client, "default-domain:testns:pod01") assert.NoError(t, err) refs, err := vmi.GetInstanceIpBackRefs() for _, ref := range refs { ip, err := types.InstanceIpByUuid(client, ref.Uuid) assert.NoError(t, err) ip.ClearVirtualMachineInterface() assert.NoError(t, client.Update(ip)) } assert.NoError(t, client.Delete(vmi)) assert.False(t, env.checker.Check()) }
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 (t *TestFramework) SetUp(publicSubnet string) { t.client = new(contrail_mocks.ApiClient) t.client.Init() t.client.AddInterceptor("virtual-machine-interface", &VmiInterceptor{}) t.client.AddInterceptor("virtual-network", &NetworkInterceptor{}) t.client.AddInterceptor("instance-ip", &IpInterceptor{}) t.client.AddInterceptor("floating-ip", &FloatingIpInterceptor{}) t.podStore = new(mocks.Store) t.serviceStore = new(mocks.Store) t.kubeMock = mocks.NewKubeClient() t.config = NewConfig() t.config.PublicSubnet = publicSubnet t.controller = makeSyncController(t.kubeMock, t.config) t.controller.SetPodStore(t.podStore) t.controller.SetServiceStore(t.serviceStore) t.controller.initComponents(t.client) t.checker = t.controller.newConsistencyChecker() for _, projectName := range testProjects { project := new(types.Project) project.SetFQName("domain", []string{t.config.DefaultDomain, projectName}) t.client.Create(project) } t.state = make(map[string]*TestGroupState, 0) t.clusterIPs = make(map[int]string, 0) t.keyList = make([]string, 0) t.shutdown = make(chan struct{}) keysCall := t.podStore.On("ListKeys").Return() keysCall.Run(func(arg mock.Arguments) { keysCall.Return(t.keyList) }) listCall := t.serviceStore.On("List").Return() listCall.Run(func(arg mock.Arguments) { serviceList := make([]interface{}, 0) for _, v := range t.state { for _, svc := range v.Services { serviceList = append(serviceList, svc) } } listCall.Return(serviceList) }) }
func TestPodCreate(t *testing.T) { kube := mocks.NewKubeClient() client := new(contrail_mocks.ApiClient) client.Init() client.AddInterceptor("virtual-machine-interface", &VmiInterceptor{}) allocator := new(mocks.AddressAllocator) networkMgr := new(mocks.NetworkManager) controller := NewTestController(kube, client, allocator, networkMgr) pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "name": "testnet", }, }, } netnsProject := new(types.Project) netnsProject.SetUuid(uuid.New()) netnsProject.SetFQName("", []string{"default-domain", "testns"}) client.Create(netnsProject) testnet := new(types.VirtualNetwork) testnet.SetFQName("project", []string{"default-domain", "testns", "testnet"}) client.Create(testnet) allocator.On("LocateIpAddress", string(pod.ObjectMeta.UID)).Return("10.0.0.42", nil) networkMgr.On("LocateNetwork", "testns", "testnet", controller.config.PrivateSubnet).Return(testnet, nil) networkMgr.On("GetGatewayAddress", testnet).Return("10.0.255.254", nil) kube.PodInterface.On("Update", pod).Return(pod, nil) shutdown := make(chan struct{}) go controller.Run(shutdown) controller.AddPod(pod) time.Sleep(100 * time.Millisecond) type shutdownMsg struct { } shutdown <- shutdownMsg{} kube.PodInterface.AssertExpectations(t) }
func (m *NamespaceManager) LocateNamespace(name, uid string) *types.Project { fqn := []string{DefaultDomain, name} obj, err := m.client.FindByName("project", strings.Join(fqn, ":")) if err == nil { return obj.(*types.Project) } project := new(types.Project) project.SetFQName("domain", fqn) project.SetUuid(uid) err = m.client.Create(project) if err != nil { glog.Errorf("Create project %s: %v", name, err) } return project }
func TestReadModifiedPolicy(t *testing.T) { client := new(ApiClient) client.Init() project := new(types.Project) project.SetFQName("domain", []string{"default-domain", "p1"}) assert.NoError(t, client.Create(project)) policy := new(types.NetworkPolicy) policy.SetFQName("project", []string{"default-domain", "p1", "x"}) assert.NoError(t, client.Create(policy)) net1 := new(types.VirtualNetwork) net1.SetFQName("project", []string{"default-domain", "p1", "n1"}) net1.AddNetworkPolicy(policy, types.VirtualNetworkPolicyType{ Sequence: &types.SequenceType{10, 0}, }) assert.NoError(t, client.Create(net1)) net2 := new(types.VirtualNetwork) net2.SetFQName("project", []string{"default-domain", "p1", "n2"}) net2.AddNetworkPolicy(policy, types.VirtualNetworkPolicyType{ Sequence: &types.SequenceType{10, 0}, }) assert.NoError(t, client.Create(net2)) refs, err := policy.GetVirtualNetworkBackRefs() assert.NoError(t, err) assert.Len(t, refs, 2) assert.NoError(t, client.Delete(net1)) refs, err = policy.GetVirtualNetworkBackRefs() assert.NoError(t, err) assert.Len(t, refs, 1) assert.NoError(t, client.Delete(net2)) refs, err = policy.GetVirtualNetworkBackRefs() assert.NoError(t, err) assert.Len(t, refs, 0) }
func GetProjectFQN( client *contrail.Client, projectName string, projectId string) ( []string, error) { if len(projectId) > 0 { uuid := strings.ToLower(projectId) if !IsUuid(uuid) { return nil, fmt.Errorf("Invalid uuid value: %s\n", uuid) } return client.FQNameByUuid(uuid) } if strings.ContainsRune(projectName, ':') { return strings.Split(projectName, ":"), nil } obj := new(types.Project) return append(obj.GetDefaultParent(), projectName), nil }
func TestNetworkLocate(t *testing.T) { client := new(contrail_mocks.ApiClient) client.Init() config := new(Config) config.PublicNetwork = "default-domain:default-project:Public" netman := NewNetworkManager(client, config) project := new(types.Project) project.SetUuid(uuid.New()) project.SetFQName("", []string{config.DefaultDomain, "p1"}) client.Create(project) network, err := netman.LocateNetwork("p1", "n1", "10.0.1.0/24") assert.NoError(t, err, "LocateNetwork") n2, err := netman.LocateNetwork("p1", "n1", "10.0.1.0/24") assert.NoError(t, err, "LocateNetwork -- exists") assert.Equal(t, network, n2) }
// TODO: Create default security-group. func CreateProject(client *contrail.Client, name string, createIpam bool) ( string, error) { project := new(types.Project) project.SetName(name) err := client.Create(project) if err != nil { return "", err } if createIpam { ipam := new(types.NetworkIpam) ipam.SetParent(project) ipam.SetName("default-network-ipam") err = client.Create(ipam) if err != nil { client.Delete(project) return "", err } } return project.GetUuid(), nil }
func TestConsistencyStaleVM(t *testing.T) { env := new(TestFramework) env.SetUp("192.0.2.0/24") client := env.client netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) env.Start() installPods(env, "testns", 3) env.SyncBarrier() env.Shutdown() assert.True(t, env.checker.Check()) p2 := new(types.Project) p2.SetFQName("domain", []string{"default-domain", "p2"}) assert.NoError(t, client.Create(p2)) vm := new(types.VirtualMachine) vm.SetFQName("project", []string{"default-domain", "p2", "x"}) assert.NoError(t, client.Create(vm)) assert.False(t, env.checker.Check()) assert.NoError(t, client.Delete(vm)) assert.True(t, env.checker.Check()) vm = new(types.VirtualMachine) vm.SetFQName("project", []string{"default-domain", "testns", "pod03"}) assert.NoError(t, client.Create(vm)) assert.False(t, env.checker.Check()) }
func GetProjectId( client *contrail.Client, project_name string, project_id string) ( string, error) { if len(project_id) > 0 { uuid := strings.ToLower(project_id) if !IsUuid(uuid) { return "", fmt.Errorf("Invalid uuid value: %s\n", uuid) } return uuid, nil } var name string if strings.ContainsRune(project_name, ':') { name = project_name } else { obj := new(types.Project) fqn := append(obj.GetDefaultParent(), project_name) name = strings.Join(fqn, `:`) } return client.UuidByName("project", name) }
func TestUpdateClearVM(t *testing.T) { client := new(ApiClient) client.Init() project := new(types.Project) project.SetFQName("domain", []string{"default-domain", "tenant"}) assert.NoError(t, client.Create(project)) vm := new(types.VirtualMachine) vm.SetFQName("project", []string{"default-domain", "tenant", "instance"}) assert.NoError(t, client.Create(vm)) vmi := new(types.VirtualMachineInterface) vmi.SetFQName("project", []string{"default-domain", "tenant", "instance"}) vmi.AddVirtualMachine(vm) assert.NoError(t, client.Create(vmi)) vmi.ClearVirtualMachine() assert.NoError(t, client.Update(vmi)) assert.NoError(t, client.Delete(vm)) }
func TestReadRefs(t *testing.T) { client := new(ApiClient) client.Init() project := new(types.Project) project.SetFQName("domain", []string{"default-domain", "p1"}) assert.NoError(t, client.Create(project)) net := new(types.VirtualNetwork) net.SetFQName("project", []string{"default-domain", "p1", "n1"}) assert.NoError(t, client.Create(net)) vmi1 := new(types.VirtualMachineInterface) vmi1.SetFQName("project", []string{"default-domain", "p1", "port1"}) vmi1.AddVirtualNetwork(net) assert.NoError(t, client.Create(vmi1)) refs, err := vmi1.GetVirtualNetworkRefs() assert.NoError(t, err) assert.Len(t, refs, 1) assert.Equal(t, net.GetUuid(), refs[0].Uuid) }
func TestReadBackRefs(t *testing.T) { client := new(ApiClient) client.Init() project := new(types.Project) project.SetFQName("domain", []string{"default-domain", "p1"}) assert.NoError(t, client.Create(project)) net := new(types.VirtualNetwork) net.SetFQName("project", []string{"default-domain", "p1", "n1"}) props := new(types.VirtualNetworkType) props.ForwardingMode = "turbo" net.SetVirtualNetworkProperties(props) assert.NoError(t, client.Create(net)) vmi1 := new(types.VirtualMachineInterface) vmi1.SetFQName("project", []string{"default-domain", "p1", "port1"}) vmi1.AddVirtualNetwork(net) assert.NoError(t, client.Create(vmi1)) vmi2 := new(types.VirtualMachineInterface) vmi2.SetFQName("project", []string{"default-domain", "p1", "port2"}) vmi2.AddVirtualNetwork(net) assert.NoError(t, client.Create(vmi2)) refs, err := net.GetVirtualMachineInterfaceBackRefs() assert.NoError(t, err) assert.Len(t, refs, 2) idList := make([]string, len(refs)) for i, ref := range refs { idList[i] = ref.Uuid } assert.Contains(t, idList, vmi1.GetUuid()) assert.Contains(t, idList, vmi2.GetUuid()) rProps := net.GetVirtualNetworkProperties() assert.Equal(t, "turbo", rProps.ForwardingMode) }
func TestConsistencyMissingInterface(t *testing.T) { client := createTestClient() podStore := new(mocks.Store) serviceStore := new(mocks.Store) checker := NewConsistencyChecker(client, NewConfig(), podStore, serviceStore, nil) kube := mocks.NewKubeClient() controller := NewTestController(kube, client, nil, nil) netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) installPods(controller, &kube.PodInterface.Mock, &podStore.Mock, "testns", 3) shutdown := make(chan struct{}) go controller.Run(shutdown) time.Sleep(100 * time.Millisecond) type shutdownMsg struct { } shutdown <- shutdownMsg{} time.Sleep(100 * time.Millisecond) serviceStore.On("List").Return([]interface{}{}) assert.True(t, checker.Check()) vmi, err := types.VirtualMachineInterfaceByName(client, "default-domain:testns:pod01") assert.NoError(t, err) refs, err := vmi.GetInstanceIpBackRefs() for _, ref := range refs { ip, err := types.InstanceIpByUuid(client, ref.Uuid) assert.NoError(t, err) ip.ClearVirtualMachineInterface() assert.NoError(t, client.Update(ip)) } assert.NoError(t, client.Delete(vmi)) assert.False(t, checker.Check()) }
func TestChildrenRefs(t *testing.T) { db := NewInMemDatabase() project := new(types.Project) project.SetUuid(uuid.New()) project.SetName("p1") assert.NoError(t, db.Put(project, nil, GetReferenceList(project))) net := new(types.VirtualNetwork) net.SetUuid(uuid.New()) net.SetFQName("project", []string{"p1", "n1"}) assert.NoError(t, db.Put(net, project, UIDList{})) vmi1 := new(types.VirtualMachineInterface) vmi1.SetUuid(uuid.New()) vmi1.SetName("port1") vmi1.AddVirtualNetwork(net) assert.NoError(t, db.Put(vmi1, project, GetReferenceList(vmi1))) vmi2 := new(types.VirtualMachineInterface) vmi2.SetUuid(uuid.New()) vmi2.SetName("port2") vmi2.AddVirtualNetwork(net) assert.NoError(t, db.Put(vmi2, project, GetReferenceList(vmi2))) result, err := db.GetChildren(parseUID(project.GetUuid()), "virtual_network") assert.NoError(t, err) assert.Len(t, result, 1) result, err = db.GetChildren(parseUID(project.GetUuid()), "virtual_machine_interface") assert.NoError(t, err) assert.Len(t, result, 2) assert.Contains(t, result, parseUID(vmi1.GetUuid())) assert.Contains(t, result, parseUID(vmi2.GetUuid())) assert.Error(t, db.Delete(project)) assert.NoError(t, db.Delete(vmi1)) assert.Error(t, db.Delete(net)) assert.NoError(t, db.Delete(vmi2)) assert.NoError(t, db.Delete(net)) assert.NoError(t, db.Delete(project)) }
func TestGlobalNetworkConsistencyUpdateNetwork(t *testing.T) { env := new(TestFramework) env.SetUp("192.0.2.0/24") config := env.config config.GlobalNetworks = []string{"default-domain:cluster:global"} pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz1", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "server", config.NetworkTag: "backend", }, }, } pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz2", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "client", config.NetworkTag: "client", config.NetworkAccessTag: "svc", }, }, } pod3 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "gPod", Namespace: "cluster", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "global", config.NetworkTag: "global", }, }, } service := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "s1", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "svc", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "Name": "server", }, ClusterIP: "10.254.42.42", }, } clusterProject := new(types.Project) clusterProject.SetFQName("", []string{"default-domain", "cluster"}) require.NoError(t, env.client.Create(clusterProject)) netnsProject := new(types.Project) netnsProject.SetFQName("", []string{"default-domain", "testns"}) require.NoError(t, env.client.Create(netnsProject)) env.Start() env.AddPod(pod1) env.AddPod(pod2) env.AddPod(pod3) env.AddService(service, "server") env.SyncBarrier() // This connects the global-network policy with the respective network which is created after // the policy. assert.False(t, env.checker.Check()) // It should be ok now. assert.True(t, env.checker.Check()) policyName := makeGlobalNetworkPolicyName(config, []string{"default-domain", "cluster", "global"}) policy, err := types.NetworkPolicyByName(env.client, strings.Join(policyName, ":")) require.NoError(t, err) netRefs, err := policy.GetVirtualNetworkBackRefs() require.NoError(t, err) assert.Len(t, netRefs, 3) assert.Len(t, policy.GetNetworkPolicyEntries().PolicyRule, 2) env.DeletePod(pod1) env.DeletePod(pod2) env.DeleteService(service, "server") env.SyncBarrier() _, err = types.NetworkPolicyByName(env.client, strings.Join(policyName, ":")) assert.Error(t, err) assert.True(t, env.checker.Check()) env.Shutdown() }
func TestConsistencyConnectionsDelete(t *testing.T) { podStore := new(mocks.Store) serviceStore := new(mocks.Store) kube := mocks.NewKubeClient() client := createTestClient() controller := NewTestController(kube, client, nil, nil) config := controller.config controller.SetPodStore(podStore) controller.SetServiceStore(serviceStore) checker := NewConsistencyChecker(client, controller.config, podStore, serviceStore, controller.serviceMgr) controller.config.ClusterServices = []string{"kube-system/dns", "kube-system/monitoring"} // 2 client pods in network "private" pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod01", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ config.NetworkTag: "private", config.NetworkAccessTag: "tagA", }, }, } pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod02", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ config.NetworkTag: "private", config.NetworkAccessTag: "tagB", }, }, } // The service pods for service tagA and tagB respectivly. pod3 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod03", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ config.NetworkTag: "svc-backend", "app": "provider01", }, }, } pod4 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod04", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ config.NetworkTag: "svc-backend", "app": "provider02", }, }, } // And the services service1 := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "service1", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "tagA", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "app": "provider01", }, ClusterIP: "10.254.42.42", Type: api.ServiceTypeClusterIP, }, } service2 := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "service1", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "tagB", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "app": "provider02", }, ClusterIP: "10.254.42.43", Type: api.ServiceTypeClusterIP, }, } netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) sysProject := new(types.Project) sysProject.SetFQName("domain", []string{"default-domain", "kube-system"}) client.Create(sysProject) keys := make([]string, 0) addPod(pod1, kube.PodInterface, podStore, &keys) addPod(pod2, kube.PodInterface, podStore, &keys) addPod(pod3, kube.PodInterface, podStore, &keys) addPod(pod4, kube.PodInterface, podStore, &keys) podStore.On("ListKeys").Return(keys).Once() serviceStore.On("List").Return([]interface{}{service1, service2}) s1Pods := makeListOptSelector(map[string]string{"app": "provider01"}) kube.PodInterface.On("List", s1Pods).Return(&api.PodList{Items: []api.Pod{*pod3}}, nil) s2Pods := makeListOptSelector(map[string]string{"app": "provider02"}) kube.PodInterface.On("List", s2Pods).Return(&api.PodList{Items: []api.Pod{*pod4}}, nil) kube.ServiceInterface.On("Update", service1).Return(service1, nil) kube.ServiceInterface.On("Update", service2).Return(service2, nil) shutdown := make(chan struct{}) go controller.Run(shutdown) controller.AddPod(pod1) controller.AddPod(pod2) controller.AddPod(pod3) controller.AddPod(pod4) controller.AddService(service1) controller.AddService(service2) time.Sleep(100 * time.Millisecond) assert.True(t, checker.Check()) controller.DeletePod(pod2) time.Sleep(100 * time.Millisecond) keys = append(keys[0:1], keys[2:]...) podStore.On("ListKeys").Return(keys) assert.False(t, checker.Check()) assert.False(t, checker.Check()) assert.True(t, checker.Check()) config.ClusterServices = []string{"kube-system/dns"} assert.False(t, checker.Check()) assert.False(t, checker.Check()) assert.True(t, checker.Check()) type shutdownMsg struct { } shutdown <- shutdownMsg{} }
func TestConsistencyServiceIp(t *testing.T) { env := new(TestFramework) env.SetUp("192.0.2.0/24") config := env.config client := env.client netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) service1 := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "s1", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "services", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "Name": "pod01", }, ClusterIP: "10.254.42.42", Type: api.ServiceTypeLoadBalancer, }, } service2 := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "s2", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "services", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "Name": "pod02", }, ClusterIP: "10.254.42.43", ExternalIPs: []string{"10.1.4.89"}, }, } service3 := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "s3", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "services", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "Name": "pod01", }, ClusterIP: "10.254.42.44", }, } env.Start() installPods(env, "testns", 3) env.AddService(service1, "pod01") env.AddService(service2, "pod02") env.AddService(service3, "pod01") env.SyncBarrier() env.Shutdown() assert.True(t, env.checker.Check()) pool, err := types.FloatingIpPoolByName(client, "default-domain:testns:service-services:service-services") assert.NoError(t, err) vmi, err := types.VirtualMachineInterfaceByName(client, "default-domain:testns:pod01") assert.NoError(t, err) vip := new(types.FloatingIp) fqn := make([]string, len(pool.GetFQName())+1) copy(fqn, pool.GetFQName()) fqn[len(pool.GetFQName())] = "s4" vip.SetFQName(vip.GetDefaultParentType(), fqn) vip.AddVirtualMachineInterface(vmi) assert.NoError(t, client.Create(vip)) assert.False(t, env.checker.Check()) assert.NoError(t, client.Delete(vip)) assert.True(t, env.checker.Check()) vip, err = types.FloatingIpByName(client, "default-domain:testns:service-services:service-services:s3") assert.NoError(t, err) assert.NoError(t, client.Delete(vip)) assert.False(t, env.checker.Check()) }
func TestGlobalNetworkConsistencyConfigChange(t *testing.T) { env := new(TestFramework) env.SetUp("192.0.2.0/24") config := env.config config.GlobalNetworks = []string{"default-domain:cluster:global"} pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz1", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "server", config.NetworkTag: "backend", }, }, } pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-xz2", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "client", config.NetworkTag: "client", config.NetworkAccessTag: "svc", }, }, } pod3 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "gPod", Namespace: "cluster", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "global", config.NetworkTag: "global", }, }, } service := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "s1", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "svc", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "Name": "server", }, ClusterIP: "10.254.42.42", }, } clusterProject := new(types.Project) clusterProject.SetFQName("", []string{"default-domain", "cluster"}) require.NoError(t, env.client.Create(clusterProject)) netnsProject := new(types.Project) netnsProject.SetFQName("", []string{"default-domain", "testns"}) require.NoError(t, env.client.Create(netnsProject)) env.Start() env.AddPod(pod3) env.AddPod(pod1) env.AddPod(pod2) env.AddService(service, "server") env.SyncBarrier() assert.True(t, env.checker.Check()) config.GlobalNetworks = []string{} for i := 0; i < 2; i++ { assert.False(t, env.checker.Check()) } assert.True(t, env.checker.Check()) policyName := makeGlobalNetworkPolicyName(config, []string{"default-domain", "cluster", "global"}) _, err := types.NetworkPolicyByName(env.client, strings.Join(policyName, ":")) require.Error(t, err) env.DeletePod(pod1) env.DeletePod(pod2) env.DeletePod(pod3) env.DeleteService(service, "server") env.SyncBarrier() env.Shutdown() assert.True(t, env.checker.Check()) }
func TestConsistencyConnectionsDelete(t *testing.T) { env := new(TestFramework) env.SetUp("192.0.2.0/24") client := env.client config := env.config config.ClusterServices = []string{"kube-system/dns", "kube-system/monitoring"} // 2 client pods in network "private" pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod01", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "private", config.NetworkTag: "private", config.NetworkAccessTag: "tagA", }, }, } pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod02", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "private", config.NetworkTag: "private", config.NetworkAccessTag: "tagB", }, }, } // The service pods for service tagA and tagB respectivly. pod3 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod03", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "provider01", config.NetworkTag: "svc-backend", "app": "provider01", }, }, } pod4 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod04", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "provider02", config.NetworkTag: "svc-backend", "app": "provider02", }, }, } // And the services service1 := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "service1", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "tagA", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "app": "provider01", }, ClusterIP: "10.254.42.42", Type: api.ServiceTypeClusterIP, }, } service2 := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "service1", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "tagB", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "app": "provider02", }, ClusterIP: "10.254.42.43", Type: api.ServiceTypeClusterIP, }, } netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) sysProject := new(types.Project) sysProject.SetFQName("domain", []string{"default-domain", "kube-system"}) client.Create(sysProject) env.Start() env.AddPod(pod1) env.AddPod(pod2) env.AddPod(pod3) env.AddPod(pod4) env.AddService(service1, "provider01") env.AddService(service2, "provider02") env.SyncBarrier() assert.True(t, env.checker.Check()) env.DeletePod(pod2) env.SyncBarrier() assert.False(t, env.checker.Check()) assert.False(t, env.checker.Check()) assert.True(t, env.checker.Check()) config.ClusterServices = []string{"kube-system/dns"} assert.False(t, env.checker.Check()) assert.False(t, env.checker.Check()) assert.True(t, env.checker.Check()) env.Shutdown() }
func TestConsistencyMissingVM(t *testing.T) { client := createTestClient() podStore := new(mocks.Store) serviceStore := new(mocks.Store) checker := NewConsistencyChecker(client, NewConfig(), podStore, serviceStore, nil, nil) pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-sv1", Namespace: "testns", UID: kubetypes.UID(uuid.New()), }, } pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "test-sv2", Namespace: "testns", UID: kubetypes.UID(uuid.New()), }, } kube := mocks.NewKubeClient() controller := NewTestController(kube, client, nil, nil) netnsProject := new(types.Project) netnsProject.SetFQName("domain", []string{"default-domain", "testns"}) client.Create(netnsProject) kube.Pods("testns").(*mocks.KubePodInterface).On("Update", pod1).Return(pod1, nil) kube.Pods("testns").(*mocks.KubePodInterface).On("Update", pod2).Return(pod2, nil) podStore.On("ListKeys").Return([]string{"testns/test-sv1", "testns/test-sv2"}) podStore.On("GetByKey", "testns/test-sv1").Return(pod1, true, nil) podStore.On("GetByKey", "testns/test-sv2").Return(pod2, true, nil) serviceStore.On("List").Return([]interface{}{}) shutdown := make(chan struct{}) go controller.Run(shutdown) controller.AddPod(pod1) controller.AddPod(pod2) time.Sleep(100 * time.Millisecond) type shutdownMsg struct { } shutdown <- shutdownMsg{} assert.True(t, checker.Check()) vmi, err := types.VirtualMachineInterfaceByName(client, "default-domain:testns:test-sv1") assert.NoError(t, err) if err == nil { vmi.ClearVirtualMachine() err = client.Update(vmi) assert.NoError(t, err) } vm, err := types.VirtualMachineByName(client, "default-domain:testns:test-sv1") assert.NoError(t, err) if err == nil { err = client.Delete(vm) assert.NoError(t, err) } assert.False(t, checker.Check()) }
func TestConsistencyPodUpdateRemovePrev(t *testing.T) { env := new(TestFramework) env.SetUp("192.0.2.0/24") client := env.client config := env.config pod1 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "x-1", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "client", config.NetworkTag: "client", config.NetworkAccessTag: "red", }, }, } pod2 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "x-2", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "client", config.NetworkTag: "client", config.NetworkAccessTag: "red", }, }, } pod3 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "redPod", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "red", config.NetworkTag: "redPrivate", }, }, } pod4 := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "bluePod", Namespace: "testns", UID: kubetypes.UID(uuid.New()), Labels: map[string]string{ "Name": "blue", config.NetworkTag: "bluePrivate", }, }, } redService := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "red", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "red", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "Name": "red", }, ClusterIP: "10.254.42.42", }, } blueService := &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "blue", Namespace: "testns", Labels: map[string]string{ config.NetworkTag: "blue", }, }, Spec: api.ServiceSpec{ Selector: map[string]string{ "Name": "blue", }, ClusterIP: "10.254.42.43", }, } netnsProject := new(types.Project) netnsProject.SetFQName("", []string{"default-domain", "testns"}) client.Create(netnsProject) env.Start() env.AddPod(pod1) env.AddService(redService, "red") env.AddPod(pod2) env.AddPod(pod3) env.AddPod(pod4) env.AddService(blueService, "blue") env.SyncBarrier() serviceConnections := getNetworkServiceConnections(t, client, config, "testns", "client") assert.EqualValues(t, []string{"default", "red"}, serviceConnections) assert.True(t, env.checker.Check()) policyName := makeServicePolicyName(config, "testns", "red") _, err := types.NetworkPolicyByName(client, strings.Join(policyName, ":")) assert.NoError(t, err) clonePodAndUpdateAccessTag := func(pod *api.Pod, color string) *api.Pod { newPod := new(api.Pod) *newPod = *pod newPod.Labels = make(map[string]string, 0) for k, v := range pod.Labels { newPod.Labels[k] = v } newPod.Labels[config.NetworkAccessTag] = color return newPod } // Update connections on pod1 nPod1 := clonePodAndUpdateAccessTag(pod1, "blue") env.UpdatePod(pod1, nPod1) env.SyncBarrier() serviceConnections = getNetworkServiceConnections(t, client, config, "testns", "client") assert.EqualValues(t, []string{"default", "red", "blue"}, serviceConnections) assert.True(t, env.checker.Check(), "red and blue present") // Update connections on pod2 // This will leave a stale connection to network red. nPod2 := clonePodAndUpdateAccessTag(pod2, "blue") env.UpdatePod(pod2, nPod2) env.SyncBarrier() serviceConnections = getNetworkServiceConnections(t, client, config, "testns", "client") assert.EqualValues(t, []string{"default", "red", "blue"}, serviceConnections) assert.False(t, env.checker.Check()) env.DeleteService(redService, "red") env.SyncBarrier() // The second pass will delete the connection to network red. assert.False(t, env.checker.Check()) serviceConnections = getNetworkServiceConnections(t, client, config, "testns", "client") assert.EqualValues(t, []string{"default", "blue"}, serviceConnections) assert.True(t, env.checker.Check()) env.Shutdown() _, err = types.NetworkPolicyByName(client, strings.Join(policyName, ":")) assert.Error(t, err) }