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])
	}
}
Exemple #5
0
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)
}
Exemple #14
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)
}
Exemple #16
0
// 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())
}
Exemple #18
0
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)
}