示例#1
0
func (s *DaemonSuite) TestEndpointLabelsAddOK(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	wantedLabels := labels.LabelOp{
		labels.AddLabelsOp: labels.Labels{
			"foo": labels.NewLabel("foo", "bar", "cilium"),
		},
	}

	s.d.OnEndpointLabelsUpdate = func(epID uint16, lbls labels.LabelOp) error {
		c.Assert(ep.ID, DeepEquals, epID)
		c.Assert(wantedLabels, DeepEquals, lbls)
		return nil
	}

	err := s.c.EndpointLabelsUpdate(ep.ID, wantedLabels)
	c.Assert(err, IsNil)
}
示例#2
0
func (s *DaemonSuite) TestEndpointLabelsAddFail(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	wantedLabels := labels.LabelOp{
		labels.AddLabelsOp: labels.Labels{
			"foo": labels.NewLabel("foo", "bar", "cilium"),
		},
	}

	s.d.OnEndpointLabelsUpdate = func(epID uint16, labelOp labels.LabelOp) error {
		c.Assert(ep.ID, DeepEquals, epID)
		c.Assert(labelOp, DeepEquals, wantedLabels)
		return errors.New("invalid endpoint")
	}

	err := s.c.EndpointLabelsUpdate(ep.ID, wantedLabels)
	c.Assert(strings.Contains(err.Error(), "invalid endpoint"), Equals, true)
}
示例#3
0
func (s *DaemonSuite) TestEndpointLabelsGetOK(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	epLbls := labels.Labels{
		"foo": labels.NewLabel("foo", "bar", "cilium"),
	}
	ciliumLbls := labels.Labels{
		"bar": labels.NewLabel("bar", "foo", "cilium"),
	}
	wantedLbls := labels.OpLabels{
		AllLabels:      ciliumLbls,
		EndpointLabels: epLbls,
	}

	s.d.OnEndpointLabelsGet = func(epID uint16) (*labels.OpLabels, error) {
		c.Assert(ep.ID, DeepEquals, epID)
		return &wantedLbls, nil
	}

	lbls, err := s.c.EndpointLabelsGet(ep.ID)
	c.Assert(err, IsNil)
	c.Assert(wantedLbls, DeepEquals, *lbls)
}
示例#4
0
func (s *DaemonSuite) TestEndpointLeaveOK(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	s.d.OnEndpointLeave = func(epID uint16) error {
		c.Assert(ep.ID, Equals, epID)
		return nil
	}

	err := s.c.EndpointLeave(ep.ID)
	c.Assert(err, Equals, nil)
}
示例#5
0
func (s *DaemonSuite) TestEndpointJoinFail(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	s.d.OnEndpointJoin = func(receivedEp endpoint.Endpoint) error {
		c.Assert(ep, DeepEquals, receivedEp)
		return errors.New("invalid endpoint")
	}

	err := s.c.EndpointJoin(ep)
	c.Assert(strings.Contains(err.Error(), "invalid endpoint"), Equals, true)
}
示例#6
0
func (s *DaemonSuite) TestEndpointJoinOK(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	s.d.OnEndpointJoin = func(receivedEp endpoint.Endpoint) error {
		c.Assert(ep, DeepEquals, receivedEp)
		return nil
	}

	err := s.c.EndpointJoin(ep)
	c.Assert(err, Equals, nil)
}
示例#7
0
func (s *DaemonSuite) TestEndpointLeaveFail(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	s.d.OnEndpointLeave = func(epID uint16) error {
		c.Assert(ep.ID, Equals, epID)
		return errors.New("invalid endpoint")
	}

	err := s.c.EndpointLeave(ep.ID)
	c.Assert(strings.Contains(err.Error(), "invalid endpoint"), Equals, true)
}
示例#8
0
func (s *DaemonSuite) TestEndpointLabelsGetFail(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:          HardAddr,
		IPv6:            IPv6Addr,
		IPv4:            IPv4Addr,
		NodeMAC:         HardAddr,
		NodeIP:          NodeAddr,
		IfName:          "ifname",
		DockerNetworkID: "dockernetwork",
		SecLabel:        SecLabel,
	}
	ep.SetID()

	s.d.OnEndpointLabelsGet = func(epID uint16) (*labels.OpLabels, error) {
		c.Assert(ep.ID, DeepEquals, epID)
		return nil, errors.New("invalid endpoint")
	}

	lbls, err := s.c.EndpointLabelsGet(ep.ID)
	c.Assert(strings.Contains(err.Error(), "invalid endpoint"), Equals, true)
	c.Assert(lbls, IsNil)
}
示例#9
0
func (s *DaemonSuite) EndpointLeaveByDockerEPIDFail(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:           HardAddr,
		IPv6:             IPv6Addr,
		IPv4:             IPv4Addr,
		NodeMAC:          HardAddr,
		NodeIP:           NodeAddr,
		IfName:           "ifname",
		DockerNetworkID:  "dockernetwork",
		DockerEndpointID: "123abc",
		SecLabel:         SecLabel,
	}
	ep.SetID()

	s.d.OnEndpointLeaveByDockerEPID = func(dockerEPIDreceived string) error {
		c.Assert(ep.DockerEndpointID, Equals, dockerEPIDreceived)
		return errors.New("invalid endpoint")
	}

	err := s.c.EndpointLeaveByDockerEPID(ep.DockerEndpointID)
	c.Assert(strings.Contains(err.Error(), "invalid endpoint"), Equals, true)
}
示例#10
0
func (s *DaemonSuite) EndpointLeaveByDockerEPIDOK(c *C) {
	ep := endpoint.Endpoint{
		LXCMAC:           HardAddr,
		IPv6:             IPv6Addr,
		IPv4:             IPv4Addr,
		NodeMAC:          HardAddr,
		NodeIP:           NodeAddr,
		IfName:           "ifname",
		DockerNetworkID:  "dockernetwork",
		DockerEndpointID: "123abc",
		SecLabel:         SecLabel,
	}
	ep.SetID()

	s.d.OnEndpointLeaveByDockerEPID = func(dockerEPIDreceived string) error {
		c.Assert(ep.DockerEndpointID, Equals, dockerEPIDreceived)
		return nil
	}

	err := s.c.EndpointLeaveByDockerEPID(ep.DockerEndpointID)
	c.Assert(err, Equals, nil)
}
示例#11
0
func (driver *driver) createEndpoint(w http.ResponseWriter, r *http.Request) {
	var create CreateEndpointRequest
	if err := json.NewDecoder(r.Body).Decode(&create); err != nil {
		sendError(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest)
		return
	}
	log.Debugf("Create endpoint request: %+v", &create)

	endID := create.EndpointID
	ipv6Address := create.Interface.AddressIPv6
	ipv4Address := create.Interface.Address

	if ipv4Address == "" {
		log.Warningf("No IPv4 address provided in CreateEndpoint request")
	}

	if ipv6Address == "" {
		sendError(w, "No IPv6 address provided (required)", http.StatusBadRequest)
		return
	}

	maps := make([]endpoint.PortMap, 0, 32)

	for key, val := range create.Options {
		switch key {
		case "com.docker.network.portmap":
			var portmap []lnTypes.PortBinding
			if err := json.Unmarshal(val, &portmap); err != nil {
				sendError(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest)
				return
			}
			log.Debugf("PortBinding: %+v", &portmap)

			// FIXME: Host IP is ignored for now
			for _, m := range portmap {
				maps = append(maps, endpoint.PortMap{
					From:  m.HostPort,
					To:    m.Port,
					Proto: uint8(m.Proto),
				})
			}

		case "com.docker.network.endpoint.exposedports":
			var tp []lnTypes.TransportPort
			if err := json.Unmarshal(val, &tp); err != nil {
				sendError(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest)
				return
			}
			log.Debugf("ExposedPorts: %+v", &tp)
			// TODO: handle exposed ports
		}
	}

	ep, err := driver.client.EndpointGetByDockerEPID(endID)
	if err != nil {
		sendError(w, fmt.Sprintf("Error retrieving endpoint %s", err), http.StatusBadRequest)
		return
	}
	if ep != nil {
		sendError(w, "Endpoint already exists", http.StatusBadRequest)
		return
	}

	endpoint := endpoint.Endpoint{
		NodeIP:           driver.nodeAddress,
		DockerNetworkID:  create.NetworkID,
		DockerEndpointID: endID,
		PortMap:          maps,
	}

	if ipv6Address != "" {
		ip6, _, err := net.ParseCIDR(ipv6Address)
		if err != nil {
			sendError(w, fmt.Sprintf("Invalid IPv6 address: %s", err), http.StatusBadRequest)
			return
		}
		endpoint.IPv6 = addressing.DeriveCiliumIPv6(ip6)
	}

	if ipv4Address != "" {
		ip4, _, err := net.ParseCIDR(ipv4Address)
		if err != nil {
			sendError(w, fmt.Sprintf("Invalid IPv4 address: %s", err), http.StatusBadRequest)
			return
		}
		endpoint.IPv4 = addressing.DeriveCiliumIPv4(ip4)
	}

	endpoint.SetID()

	if err = driver.client.EndpointSave(endpoint); err != nil {
		sendError(w, fmt.Sprintf("Error retrieving endpoint %s", err), http.StatusBadRequest)
		return
	}

	log.Debugf("Created Endpoint: %+v", endpoint)

	log.Infof("New endpoint %s with IPv6: %s, IPv4: %s", endID, ipv6Address, ipv4Address)

	respIface := &api.EndpointInterface{
		// Fixme: the lxcmac is an empty string at this point and we only know the
		// mac address at the end of joinEndpoint
		// There's no problem in the setup but docker inspect will show an empty mac address
		MacAddress: endpoint.LXCMAC.String(),
	}
	resp := &api.CreateEndpointResponse{
		Interface: respIface,
	}
	log.Debugf("Create endpoint response: %+v", resp)
	objectResponse(w, resp)
}
示例#12
0
func cmdAdd(args *skel.CmdArgs) error {
	n, err := loadNetConf(args.StdinData)
	if err != nil {
		return err
	}

	log.Debugf("Args %s", args)

	c, err := cnc.NewDefaultClient()
	if err != nil {
		return fmt.Errorf("error while starting cilium-client: %s", err)
	}

	netNs, err := ns.GetNS(args.Netns)
	if err != nil {
		return fmt.Errorf("failed to open netns %q: %s", args.Netns, err)
	}
	defer netNs.Close()

	if err := removeIfFromNSIfExists(netNs, args.IfName); err != nil {
		return fmt.Errorf("failed removing interface %q from namespace %q: %s",
			args.IfName, args.Netns, err)
	}

	var ep endpoint.Endpoint
	veth, peer, tmpIfName, err := plugins.SetupVeth(args.ContainerID, n.MTU, &ep)
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			if err = netlink.LinkDel(veth); err != nil {
				log.Warningf("failed to clean up veth %q: %s", veth.Name, err)
			}
		}
	}()

	if err = netlink.LinkSetNsFd(*peer, int(netNs.Fd())); err != nil {
		return fmt.Errorf("unable to move veth pair %q to netns: %s", peer, err)
	}

	err = netNs.Do(func(_ ns.NetNS) error {
		err := renameLink(tmpIfName, args.IfName)
		if err != nil {
			return fmt.Errorf("failed to rename %q to %q: %s", tmpIfName, args.IfName, err)
		}
		return nil
	})

	req := ipam.IPAMReq{}
	ipamConf, err := c.AllocateIP(ipam.CNIIPAMType, req)
	if err != nil {
		return err
	}
	defer func() {
		if err != nil && ipamConf != nil {
			if ipamConf.IP6 != nil {
				req := ipam.IPAMReq{IP: &ipamConf.IP6.IP.IP}
				if err = c.ReleaseIP(ipam.CNIIPAMType, req); err != nil {
					log.Warningf("failed to release allocated IPv6 of container ID %q: %s", args.ContainerID, err)
				}
			}
			if ipamConf.IP4 != nil {
				req := ipam.IPAMReq{IP: &ipamConf.IP4.IP.IP}
				if err = c.ReleaseIP(ipam.CNIIPAMType, req); err != nil {
					log.Warningf("failed to release allocated IPv4 of container ID %q: %s", args.ContainerID, err)
				}
			}
		}
	}()

	if err = netNs.Do(func(_ ns.NetNS) error {
		return configureIface(args.IfName, ipamConf)
	}); err != nil {
		return err
	}

	ep.IPv6 = addressing.DeriveCiliumIPv6(ipamConf.IP6.IP.IP)
	if ipamConf.IP4 != nil {
		ep.IPv4 = addressing.DeriveCiliumIPv4(ipamConf.IP4.IP.IP)
	}
	ep.NodeIP = ipamConf.IP6.Gateway
	ep.DockerID = args.ContainerID
	ep.SetID()
	if err = c.EndpointJoin(ep); err != nil {
		return fmt.Errorf("unable to create eBPF map: %s", err)
	}

	return createCNIReply(ipamConf)
}